4

X2 つの区間 [a,b] の間に均一に分布するランダムな倍精度数を生成する必要があります。ここでa、 とbも倍精度数です。

これらXの数値は、クラス関数内で生成する必要がありますmyclass::doSomething(a,b)[a,b]問題は、関数に渡される間隔が、関数が別のクラス関数によって呼び出されるdoSomething(a,b)たびに変化することです。doSomething(a,b)doThat()


次のことを可能にするソリューションがengine必要です。
2.関数Xへの各単一呼び出し内で生成されるランダムな倍精度数はdoSomething()、均一に分散する必要があります。

以下の私の解決策では、より高い範囲を許可しておらずengine、生成された数値が必ずしも均一に分布しているとは限りません。

//file: utilities.h
template <typename Generator>
double randomDoubleEngine(Generator& engine, double low_bound, double high_bound )
{
        if (low_bound > high_bound){
                std::swap(low_bound, high_bound);
        }

        return std::uniform_real_distribution<>( low_bound, high_bound )( engine );
}

//file: myclass.h
       void myclass::doThat(param1, param2){

            for(int i=0; i < myclass.iter; i++){
                ...
                ...
                doSomething(a,b);
                ...
            }

        }

        void myclass::doSomething(double a, double b)
        {
                std::random_device rd;
                static std::mt19937 engine(rd());
                .....
                double curThreshold = randomDoubleEngine(engine, a, b);
                ...
         }
4

1 に答える 1

2

engine を myclass の静的メンバーにしたいと思います。他の方法でエンジンを使用する必要がない限り、それがあなたが持っているものと実際の違いを生むかどうかはわかりません. 以下に考えられる解決策を貼り付けました。

また、gcc は標準と比較して間違っているように見えることにも注意してください (コード コメントのリンクを参照)。そのため、それを使用している場合は、これらの数値に適用しているテスト (均一な分布を確認するため) が失敗する理由を説明できます。私が理解しているように、gccはエンジンが[0,1)で数値を返すことを望んでいますが、標準では、ある範囲で均一な整数であるべきだと言っています。

残念ながら、古い Ubuntu リリースを実行しており、ideone では std::random_device が許可されていないように見えるため、gcc 4.4 でしかテストできませんでした。

#include <random>
#include <iostream>

/* In GCC 4.4, uniform_real_distribution is called uniform_real; renamed in 4.5
 *
 * However, GCC's description here
 *
 * http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-api-4.6/a00731.html
 *
 * doesn't match expectation here
 *
 * http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution
 *
 * which seems to match 26.5.8.2.2 of N3337
 *
 */
#if defined(__GNUC_MINOR__) && (__GNUC_MINOR__ <= 4)
#  define uniform_real_distribution uniform_real
#endif

template <typename Generator>
double randomDoubleEngine(Generator& engine, double low_bound, double high_bound)
{
  if (low_bound > high_bound){
    std::swap(low_bound, high_bound);
  }
  return std::uniform_real_distribution<double>(low_bound, high_bound)(engine);
}

class myclass
{
  double curThreshold;
  static std::mt19937 engine;
  void doSomething(double a, double b)
  {
    curThreshold= randomDoubleEngine(engine, a, b);
  }
public:
  myclass(): curThreshold(0) {}

  void doThat(){
    doSomething(0,10);
    std::cout << "threshold is " << curThreshold << std::endl;
  }
};

std::mt19937 myclass::engine=std::mt19937(std::random_device()());

int
main()
{
  myclass m;
  m.doThat();
  m.doThat();
  return 0;
}
于 2012-04-08T07:31:29.197 に答える