2011-01-13 13 views
2

私はグラフの最適なパーティションを見つける最適化アルゴリズムを持っています。さまざまな引数を持つ関数ポインタを使用するためのより良い設計

パーティションの品質(最適化される変数)には多くの措置があるため、これらの品質関数への関数ポインタを使用して最適化アルゴリズム関数に渡すことをお勧めします。

これはうまくいきますが、問題は異なる品質関数がいくつかの異なる引数を取ることです。

例えば1つの品質関数は、find_linearised_stabilityであり、それはmarkov_timeパラメータを必要とする:

float find_linearised_stability(cliques::Graph<T> &my_graph, cliques::Partition &my_partition, 
           std::vector<float> &markov_times, std::vector<float> &stabilities) 

及び最適化関数で使用される:

cliques::find_optimal_partition_louvain(my_new_graph, markov_times, &cliques::find_linearised_stability); 

しかし、別の品質関数 find_modularityにはmarkov_timeパラメータを必要としません。もちろん、それを引数として含めることはできますが、関数内で使用することはできませんが、それは悪い習慣のように思えますし、いろいろな質の関数を追加し始めたら扱いにくくなります。

このような状況に適したデザインは何ですか?

答えて

6

関数オブジェクトを使用します。これらの関数オブジェクトの一つは、コンストラクタに渡されmarkov_timeメンバー持つことができます。

struct find_linearised_stability { 
    std::vector<float> & markov_times_; 

    find_linearised_stability(std::vector<float> & markov_times) 
     :markov_times_(markov_times) 
    {} 

    float operator() (cliques::Graph<T> &my_graph, cliques::Partition &my_partition, 
       std::vector<float> &stabilities) 
    { 
     // use markov_times_ in here, we didn't need to pass it since it's a member 
    } 
}; 

(あなたがあなたのニーズに合うようにconst性/ referencenessに調整を行う必要があるかもしれません)

を次に、あなたを呼び出すことができますこのような関数:「?...関数を宣言するとき、私は、関数オブジェクトの種類を使っています」

cliques::find_optimal_partition_louvain(my_new_graph, cliques::find_linearised_stability(markov_times)); 

はthusly、そのテンプレートパラメータとして関数オブジェクトの型を取る関数テンプレートください:含まれている全ての関数(参照/ポインタ)に引数を追加します。前に

template<typename PR> 
whatever find_optimal_partition_louvain(my_new_graph, PR & pr) 
{ 
    ... 
    pr(my_new_graph, partition, stabilities); 
    ... 
} 
+0

[OK]をしかし、その後クリーク:: find_optimal_partition_louvain関数を宣言するときに私が使うのです関数オブジェクトのためのどのタイプ? – zenna

+0

@zenna - それを関数テンプレートにします。たとえば、更新された答えを見てください。 –

+0

@zenna - 関数オブジェクトクラスに変換したくないと思っている人がいれば、通常の関数を渡すこともできます。 –

2

あなたの唯一の選択肢は、boost :: bindなどのboostオプションやそれに似たものです。

プロファイリングが遅すぎると表示されている場合は、「貧弱な練習」バージョンに固執するでしょう。これは、代替案がUBと違反している可能性があります。代替。

0
  1. パラメータが知られていませんすべての情報、すべての関数は必要なものを使用します。
  2. パラメータは以前から知られています。:

サンプルソースコード:

#include <iostream> 
#include <cstddef> 
#include <algorithm> 
#include <boost/bind.hpp> 
using namespace std; 

void output(int a, int b) 
{ 
    cout << a << ", " << b << '\n'; 
} 

int main() 
{ 
    int arr[] = { 1, 2, 3, 4, 5 }; 
    for_each(arr, arr + 5, bind(output, 5, _1)); 
    return 0; 
} 

出力:

5, 1 
5, 2 
5, 3 
5, 4 
5, 5
関連する問題