Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何构造遗传算法类层次结构?_C++_Inheritance_Oop_Polymorphism_Genetic Algorithm - Fatal编程技术网

C++ 如何构造遗传算法类层次结构?

C++ 如何构造遗传算法类层次结构?,c++,inheritance,oop,polymorphism,genetic-algorithm,C++,Inheritance,Oop,Polymorphism,Genetic Algorithm,我正在做一些关于遗传算法的工作,想写我自己的遗传算法类。由于遗传算法可以有不同的方法来进行选择、变异、交叉、生成初始种群、计算适应度和终止算法,因此我需要一种方法来插入这些方法的不同组合。我最初的方法是创建一个抽象类,将所有这些方法定义为纯虚拟的,任何具体的类都必须实现它们。例如,如果我想尝试两个相同但具有不同交叉方法的GAs,我必须创建一个从GeneticAlgorithm继承并实现除交叉方法之外的所有方法的抽象类,然后创建两个从该类继承并仅实现交叉方法的具体类。这样做的缺点是,每当我想交换一

我正在做一些关于遗传算法的工作,想写我自己的遗传算法类。由于遗传算法可以有不同的方法来进行选择、变异、交叉、生成初始种群、计算适应度和终止算法,因此我需要一种方法来插入这些方法的不同组合。我最初的方法是创建一个抽象类,将所有这些方法定义为纯虚拟的,任何具体的类都必须实现它们。例如,如果我想尝试两个相同但具有不同交叉方法的GAs,我必须创建一个从GeneticAlgorithm继承并实现除交叉方法之外的所有方法的抽象类,然后创建两个从该类继承并仅实现交叉方法的具体类。这样做的缺点是,每当我想交换一两个方法来尝试新的东西时,我必须创建一个或多个新类


还有其他方法可以更好地解决这个问题吗?

您的实现看起来像一个。我将GA作为多个对象的协作来处理,而不是封装整个算法的一个大类。基本上,您可以为每个大的 变化点,以及您想要的每个实现选择的具体类。然后将所需的具体类组合成多种GA

此外,您可能希望熟悉策略模式:
我认为你的方法过于复杂化了。建议您下载该软件包。即使您只提取html或pdf格式的文档。这些lib已经存在了一段时间,我确信您将通过查看在GAlib中是如何完成的来学习如何构造lib的

我角色中的一些随机位:

  • 您应该签出的项目(作为一种方法)是
  • 构建GAs最困难的部分是为您的问题找到一个合理的遗传表示,并为给定的群体构建一个具有良好适应度分布的适应度函数
  • 当处理(m)任何硬约束时,您可以考虑引入一个Translator类来处理硬约束,代价是(可能)垃圾DNA和一点性能

正如人们所说,不要把它变成一个巨大的阶级。那太可怕了。在不同的类中封装行为。战略是一种解决方案。

如果需要示例,请下载源代码和示例。它支持遗传编程和遗传算法。你会看到那里有漂亮的设计。变异、交叉、选择、群体、基因——所有这些都是独立的类别。您只需设置配置对象,在其中启动定义的接口和要使用的实现,传递适当的算法参数并运行它。真正的包是巨大的,javadoc很好,您可以随时查看源代码或检查邮件组以获得一些答案。当我在寻找GA软件包时,我看到了GAlib和其他人,但我认为这是最完整的,设计非常好

我在实施GA框架时采取的方法如下: 创建以下类: 一代 遗传算法 遗传算法适配器 遗传算法参数 人口 个人

虽然我没有为各种操作实现策略模式,但我确信在GeneticAlgorithm实例上创建各种GA操作实现作为参数是微不足道的

GeneticAlgorithm类捕获基本算法。它实际上只是定义了各种步骤(群体创建、个体随机化、选择、交叉、变异等),并在算法运行时管理个体群体。我想,如果你愿意,你可以在这里插入不同的操作

真正的魔力在于适配器。这就是使问题域(个体的特定子类及其所有相关数据)适应遗传算法的方法。我在这里大量使用泛型,以便将特定类型的总体、参数和个体传递到实现中。这使我能够对适配器的实现进行智能感知和强类型检查。适配器基本上需要定义如何对给定个体(及其基因组)执行特定操作。例如,以下是适配器的接口:

/// <summary>
/// The interface for an adapter that adapts a domain problem so that it can be optimised with a genetic algorithm.
    /// It is a strongly typed version of the adapter.
    /// </summary>
    /// <typeparam name="TGA"></typeparam>
    /// <typeparam name="TIndividual"></typeparam>
    /// <typeparam name="TPopulation"></typeparam>
    public interface IGeneticAlgorithmAdapter<TGA, TIndividual, TGeneration, TPopulation> : IGeneticAlgorithmAdapter
        where TGA : IGeneticAlgorithm
        where TIndividual : class, IIndividual, new()
        where TGeneration : class, IGeneration<TIndividual>, new()
        where TPopulation : class, IPopulation<TIndividual, TGeneration>, new()
    {
        /// <summary>
        /// This gets called before the adapter is used for an optimisation.
        /// </summary>
        /// <param name="pso"></param>
        void InitialiseAdapter(TGA ga);

        /// <summary>
        /// This initialises the individual so that it is ready to be used for the genetic algorithm.
        /// It gets randomised in the RandomiseIndividual method.
        /// </summary>
        /// <param name="ga">The genetic algorithm that is running.</param>
        /// <param name="individual">The individual to initialise.</param>
        void InitialiseIndividual(TGA ga, TIndividual individual);

        /// <summary>
        /// This initialises the generation so that it is ready to be used for the genetic algorithm.
        /// </summary>
        /// <param name="ga">The genetic algorithm that is running.</param>
        /// <param name="generation">The generation to initialise.</param>
        void InitialiseGeneration(TGA ga, TGeneration generation);

        /// <summary>
        /// This initialises the population so that it is ready to be used for the genetic algorithm.
        /// </summary>
        /// <param name="ga">The genetic algorithm that is running.</param>
        /// <param name="population">The population to initialise.</param>
        void InitialisePopulation(TGA ga, TPopulation population);

        void RandomiseIndividual(TGA ga, TIndividual individual);

        void BeforeIndividualUpdated(TGA ga, TIndividual individual);
        void AfterIndividualUpdated(TGA ga, TIndividual individual);

        void BeforeGenerationUpdated(TGA ga, TGeneration generation);
        void AfterGenerationUpdated(TGA ga, TGeneration generation);

        void BeforePopulationUpdated(TGA ga, TPopulation population);
        void AfterPopulationUpdated(TGA ga, TPopulation population);

        double CalculateFitness(TGA ga, TIndividual individual);

        void CloneIndividualValues(TIndividual from, TIndividual to);

        /// <summary>
        /// This selects an individual from the population for the given generation.
        /// </summary>
        /// <param name="ga">The genetic algorithm that is running.</param>
        /// <param name="generation">The generation to select the individual from.</param>
        /// <returns>The selected individual.</returns>
        TIndividual SelectIndividual(TGA ga, TGeneration generation);

        /// <summary>
        /// This crosses over two parents to create two children.
        /// </summary>
        /// <param name="ga">The genetic algorithm that is running.</param>
        /// <param name="parentsGeneration">The generation that the parent individuals belong to.</param>
        /// <param name="childsGeneration">The generation that the child individuals belong to.</param>
        /// <param name="parent1">The first parent to cross over.</param>
        /// <param name="parent2">The second parent to cross over.</param>
        /// <param name="child">The child that must be updated.</param>
        void CrossOver(TGA ga, TGeneration parentsGeneration, TIndividual parent1, TIndividual parent2, TGeneration childsGeneration, TIndividual child);

        /// <summary>
        /// This mutates the given individual.
        /// </summary>
        /// <param name="ga">The genetic algorithm that is running.</param>
        /// <param name="generation">The individuals generation.</param>
        /// <param name="individual">The individual to mutate.</param>
        void Mutate(TGA ga, TGeneration generation, TIndividual individual);

        /// <summary>
        /// This gets the size of the next generation to create.
        /// Typically, this is the same size as the current generation.
        /// </summary>
        /// <param name="ga">The genetic algorithm that is running.</param>
        /// <param name="currentGeneration">The current generation.</param>
        /// <returns>The size of the next generation to create.</returns>
        int GetNextGenerationSize(TGA ga, TGeneration currentGeneration);


        /// <summary>
        /// This gets whether a cross over should be performed when creating a child from this individual.
        /// </summary>
        /// <param name="ga">The genetic algorithm that is running.</param>
        /// <param name="currentGeneration">The current generation.</param>
        /// <param name="individual">The individual to determine whether it needs a cross over.</param>
        /// <returns>True to perform a cross over. False to allow the individual through to the next generation un-altered.</returns>
        bool ShouldPerformCrossOver(TGA ga, TGeneration generation, TIndividual individual);

        /// <summary>
        /// This gets whether a mutation should be performed when creating a child from this individual.
        /// </summary>
        /// <param name="ga">The genetic algorithm that is running.</param>
        /// <param name="currentGeneration">The current generation.</param>
        /// <param name="individual">The individual to determine whether it needs a mutation.</param>
        /// <returns>True to perform a mutation. False to allow the individual through to the next generation un-altered.</returns>
        bool ShouldPerformMutation(TGA ga, TGeneration generation, TIndividual individual);
    }
//
///适配器的接口,用于适应域问题,以便使用遗传算法对其进行优化。
///它是适配器的强类型版本。
/// 
/// 
/// 
/// 
公共接口IGeneticAlgorithmAdapter:IGeneticAlgorithmAdapter
其中TGA:IGeneticAlgorithm
其中TIndividual:class、IIndividual、new()
其中tggeneration:class,IGeneration,new()
其中tppopulation:class,ippopulation,new()
{
/// 
///在使用适配器进行优化之前,将调用该函数。
/// 
/// 
空心接头(TGA-ga);
/// 
///这将初始化个体,以便它可以用于遗传算法。
///它在RandomiseIndividual方法中随机化。
/// 
///正在运行的遗传算法。
///需要初始化的个人。
无效初始个体(TGA ga,t个体);
/// 
///这将初始化生成,以便它可以用于遗传算法。
/// 
///正在运行的遗传算法。
///要初始化的一代。
空隙初始生成(TGA-ga,TG生成);
/// 
///这将初始化种群,以便它可以用于遗传算法。
/// 
///正在运行的遗传算法。
///人口需要初始化。
void InitialisePopulat