2016-09-13 12 views
0

これは私のコードです:次のようであるC++のSTL make_heapとPRIORITY_QUEUEは異なる出力に与え

std::priority_queue<SimpleCycle, 
        std::vector<SimpleCycle>, 
        SimpleCycle> pq; 
pq.push(cycle1); 
pq.push(cycle2); 
pq.push(cycle4); 
std::cout << pq.top().to_string() << std::endl; 

std::vector<SimpleCycle> pq2{ cycle1, cycle2, cycle4 }; 
std::make_heap(pq2.begin(), pq2.end(), SimpleCycle()); 
std::cout << pq2.front().to_string() << std::endl; 

コンパレータSimpleCycleのために:

const bool SimpleCycle::operator()(SimpleCycle& L, SimpleCycle& R) const 
{ 
    float a = L.avg_latency(); 
    float b = R.avg_latency(); 
    //Allow an error rate of 0.0000000001 
    //Ref. The Art of Computer Programming: Seminumerical algorithms(Page 128) 
    return (b - a) > ((fabs(a) < fabs(b) 
        ? fabs(b) : fabs(a)) * (0.0000000001)); 
} 

機能がfloatを返しavg_latency()。しかし、私は同じ同じ入力の場合に異なる出力を得ます。おそらく何が間違っていますか?

+0

は、私が行っていない...遊んで丸め誤差があるかもしれません反例が生成されますが、比較演算子が標準によって厳密な弱い順序を提供しない可能性があるので、どのような動作も期待できます。 –

答えて

2

比較演算子が「エラーレート0.0000000001を許可する」ため、これはC++の概念で定義されている厳密な弱い順序ではありません(例:http://en.cppreference.com/w/cpp/concept/Compare)。

特に、厳密な弱い順序付けの対称性要件は満たされません。例えば。 false

  • SimpleCycle()(1/e + 1, 1/e)戻りfalse
  • もう一つの問題は、中イゴールTandenikによって指摘

    • SimpleCycle()(1/e, 1/e + 1)リターン:私たちは(あなたの場合、0.0000000001で)エラーしきい値eを呼び出す場合、我々はそれを見ますそれが誘導する等価関係は推移的ではないということです:aはbに十分に近く、bはcに十分近いが、aはcに十分に近くない可能性があります。

      はあなたのcycle変数内のデータに応じて、これはpriority_queuemake_heapアプローチは、わずかに異なる最大の要素

      を返すために発生することがあり

    +0

    どうすればいいのか詳しく教えてください。 – ShinMigami13

    +1

    'comp(a、b)'と 'comp(b、a)'がどちらもfalseを返すのはまったく問題です。この述語の実際の問題は、それが誘導する等価関係は推移的ではないことです。「a」が「b」に十分に近く、「b」が「c」に十分近いが、「a」は近くにない可能性がある'c'に十分です。 @IgorTandetnik。 –

    +0

    推移性要件に関する良い点。アルゴリズムの観点から見れば、弱い順序をとっても問題はありませんが、出力コードが同等の結果に対して異なる出力を出力すると仮定すると、「同じ入力ケースに対して異なる出力を得ます」という問題につながります。 –

    関連する問題