我正在尝试为项目编写遗传算法,并且难以将不同的功能分开。我一直在阅读基于策略的设计,这似乎是问题的解决方案,但我真的不明白如何实现它。
我有一个OptimizerHost,它继承自SelectionPolicy(用于确定要评估的解决方案)和FitnessPolicy(用于确定任何给定解决方案的适用性)。问题是我无法弄清楚这两个政策如何相互沟通。算法的大部分是在SelectionPolicy中实现的,但它仍然需要能够检查其解决方案的适用性。我唯一能想到的是在OptimizerHost本身中实现SelectionPolicy算法,因此它将从FitnessPolicy继承它所需的东西。但这似乎首先忽略了使用政策的重点。我误解了什么吗?
答案 0 :(得分:0)
我对基于策略的设计原则不太熟悉(对不起)但是当我读到你的问题时,我觉得你需要像纯虚拟类(作为接口)来帮助你完成它。
问题是,你不能使用其他东西,如果以前没有声明:这是基本规则。因此,您需要使用和虚拟接口来说SelectPolicy,即FitnessPolicy有一些要使用的成员。请按照示例进行操作,并根据您的需要进行相应更改。
首先:为SelectionPolicy和FitnessPolicy
创建接口template <class T> class FitnessPolicyBase
{
public:
virtual int Fitness(T fitnessSet); // assuming you have implemented the required classes etc. here - return value can be different of course
...
} // write your other FitnessPolicy stuff here
template <class T> class SelectionPolicyBase
{
public:
virtual T Selector(FitnessPolicyBase<Solution> evaluator, Set<T> selectionSet); // assuming such a set exists here
...
} // write your other selectionpolicy interface here
现在,由于我们将这些类设为纯虚拟(它们只有虚函数),我们不能使用它们,只能从它们继承。这正是我们要做的:SelectionPolicy类和FitnessPolicy类将分别从它们继承:
class SelectionPolicy: public SelectionPolicyBase<Solution> // say, our solutions are of Solution Type...
{
public:
virtual Solution Selector(FitnessPolicyBase<Solution> evaluator, Set<Solution> selectionSet); // return your selected item in this function
...
}
class FitnessPolicy : public FitnessPolicy Base<Solution> // say, our solutions are of SolutionSet Type...
{
public:
virtual int Fitness(Solution set); // return the fitness score here
...
}
现在,我们的algortihm可以运行两种类型的参数:SolutionSetBase和FitnessSetBase。我们真的需要xxxBase类型吗?实际上,只要我们拥有SolutionPolicy和FitnessPolicy类的公共接口,我们就可以使用它们;但是用这种方式,我们有点分离了问题中的“逻辑”。
现在,我们的选择策略算法可以引用策略类,然后调用所需的函数。请注意,策略类也可以调用彼此的类。所以现在这是一个有效的情况:
virtual Solution SelectionPolicy::Selector(FitnessPolicyBase<Solution> evaluator, Set<T> selectionSet)
{
int score = evaluator.Fitness(selectionSet[0]); //assuming an array type indexing here. Change accordingly to your implementation and comparisons etc.
}
现在,为了使其正常工作,您必须初始化FitnessPolicy对象并将其传递给此Selector。由于上传和虚拟功能,它将正常工作。
如果我过度复杂的话,请原谅我 - 我最近从C ++开始有点远近(最近在C#上工作)因此可能会误解语法,但逻辑应该是相同的。