Политики, взаимодействующие друг с другом в разработке политики

Я пытаюсь запрограммировать генетический алгоритм для проекта, и мне трудно разделять разные функции. Я читал об основанном на политике дизайне, и это похоже на решение проблемы, но я не совсем понимаю, как это реализовать.

У меня есть OptimizerHost, который наследуется от SelectionPolicy (чтобы определить, какие решения оцениваются) и FitnessPolicy (для определения пригодности любого данного решения). Проблема в том, что я не могу понять, как две политики могут взаимодействовать друг с другом. Большая часть алгоритма реализована в SelectionPolicy, но ему все еще нужно уметь проверять пригодность своих решений. Единственное, о чем я могу думать, - это реализовать алгоритм SelectionPolicy в самом OptimizerHost, чтобы он унаследовал то, что ему нужно, от FitnessPolicy. Но похоже, что в первую очередь упускается из виду использование политик. Я что-то неправильно понимаю?

1 ответ

Я не очень знаком с принципами проектирования на основе политик (извините), но когда я прочитал вашу проблему, я почувствовал, что вам нужно что-то вроде чисто виртуальных классов (в качестве интерфейсов), чтобы помочь вам в этом.

Дело в том, что вы не можете использовать что-то от другого, если это не объявлено ранее: это основное правило. Таким образом, вам нужно использовать и виртуальный интерфейс, чтобы сказать 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

  ...
}

Теперь наш алгоритм может работать с двумя типами параметров: 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 и передать его этому селектору. Благодаря апскейтингу и виртуальным функциям он будет работать правильно.

Пожалуйста, прости меня, если я слишком усложнял вещи - я был довольно далек от C++ (в последнее время работал над C#), поэтому мог ошибиться в синтаксисе, но логика должна быть в любом случае такой же.

Другие вопросы по тегам