我有一个优化算法,可以找到图表的最佳分区。
分区的质量有很多度量(被优化的变量),所以我认为使用函数指针来处理这些质量函数是个好主意,并将其传递给我的优化算法函数。
这很好用,但问题是不同的质量函数需要一些不同的参数。
例如,一个质量函数为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参数。当然我可以把它作为一个参数包括在内,而不是在函数中使用它,但这似乎是不好的做法,一旦我开始添加很多不同的质量函数就会变得笨拙。
对于这种情况,什么是更好的设计?
答案 0 :(得分: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
}
};
(您可能需要根据自己的需要调整常数/参考值)
然后你可以这样调用你的函数:
cliques::find_optimal_partition_louvain(my_new_graph, cliques::find_linearised_stability(markov_times));
“声明...函数时,我使用什么类型的函数对象?”
使其成为一个函数模板,将函数对象类型作为模板参数,因此:
template<typename PR>
whatever find_optimal_partition_louvain(my_new_graph, PR & pr)
{
...
pr(my_new_graph, partition, stabilities);
...
}
答案 1 :(得分:2)
你唯一的选择是boost :: bind或类似存储在boost :: function之类的东西。
如果分析显示速度太慢,那么你将会陷入“糟糕的练习”版本,因为任何替代方案都会与UB发生冲突和/或最终变得像更合理的替代方案一样“慢”
答案 2 :(得分:0)
示例源代码:
#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