AI算法用于多维度解决方案优化/预测

我有6个整数参数,范围从0到100

这些数字的总组合数为100^6,每个组合的结果大约在-10000到100000之间,甚至可能更高。

输入数据示例:MySimulation (57, 78, 20, 10, 90, 50) = 300  <- 最佳结果MySimulation (50, 80, 10, 90, 35, 8) = 200MySimulation (4, 55, 40, 99, 40, 50) = -50 <- 最差结果

结果越高,数字组合就越好,我已经有了计算结果的公式,我只需要AI来找到一个更好的数字组合以获得更高的结果。

输出数据示例:55, 70, 25, 15, 95, 52   <- 假设这些数字组合是由AI选择的,并且在我的模拟中会产生400的结果

注意:数字的顺序也很重要。

如何使用AI减少100^6的总组合数,以便在不遍历所有100^6个组合的情况下获得最佳结果?

我计划在C#中使用Accord.NET(或者有更好的选择吗?),因为我是AI新手,所以一个代码示例会很有帮助。


回答:

欢迎进入多目标优化领域。这是我的博士论文研究的领域。解决此类问题有许多算法,但最著名的可能是NSGA-II和SPEA2。

当然,你只有一个目标:你的评分函数产生的任何结果。我认为多目标算法也适用,因为你不仅对单一解决方案感兴趣,还对它们的群体感兴趣。

我可以推荐你访问http://jmetalnet.sourceforge.net/吗?

这个想法是你将生成包含跨越100^6个可能解决方案的输入的随机向量群体。这些群体将被突变和交配以生成新的解决方案,从这些新群体中,它们将以一种方式被筛选,使得更优选的解决方案被选中留存(并在进化中生存)。

在多目标世界中,你可能会面临比较不同解决方案的适应度的问题。但在你的单目标世界中,比较适应度很简单:你只需要决定你是想要更高的数字还是更低的数字。看起来你想要更高的数字。

概述

  1. 创建随机解决方案群体。
  2. 在你的解决方案中随机进行突变/交叉操作。
  3. 计算每个体的适应度,并排序。
  4. 将最佳解决方案回采样到初始群体大小。
  5. 重复步骤2-4 [直到收敛:直到平均适应度>阈值?]
  6. 输出最终一代。

结果:

这是一个粗略的分析,值得注意的是,你可以通过平均每个参数级别的(比如)20次运行的结果来做得更好。首先,你可以看出突变率应该保持低水平,显然,更高的群体大小可以帮助(直到收敛点)。

结果格式为平均分数前后,最高600

PopSize=100,NumGens=50,MutRate=0.2,CrossRate=0.8
295.23,542.12

PopSize=100,NumGens=500,MutRate=0.2,CrossRate=0.8
298.53,565

PopSize=1000,NumGens=50,MutRate=0.2,CrossRate=0.8
301.814,579.334

PopSize=10000,NumGens=500,MutRate=0.2,CrossRate=0.8
299.8901,588

PopSize=1000,NumGens=50,MutRate=0.4,CrossRate=0.8
306.22,385.55

代码

我用了大约20分钟写这段代码,所以它并不优雅或出色。我希望它只是传达了要点。

using System;using System.Collections.Generic;using System.Diagnostics;using System.Linq;namespace moo_in_csharp{    internal class Individual    {        public int[] Decisions;        public double Fitness;        private int _numdecisions = 6;        /// <summary>        /// 默认构造函数。        /// </summary>        public Individual()        {            Decisions = new int[_numdecisions];        }        /// <summary>        /// 用配偶的决策替换决策的前半部分。        /// </summary>        /// <param name="mate"></param>        public void Crossover(Individual mate)        {            int crossoverPoint = _numdecisions / 2;            for (int i = 0; i < crossoverPoint; i++)            {                Decisions[i] = mate.Decisions[i];            }        }        /// <summary>        /// 简单适应度函数,计算a+b+c+d+e+f的总和。        /// </summary>        public double Evaluate()        {            Fitness = Decisions.Sum();            return Fitness;        }        /// <summary>        /// 为其决策分配随机值。        /// </summary>        public void Generate()        {            for (int i = 0; i < _numdecisions; i++)            {                Decisions[i] = Program.rand.Next(0, 101);            }        }        /// <summary>        /// 随机突变选择的决策。        /// </summary>        public void Mutate()        {            for (int i = 0; i < _numdecisions; i++)            {                Decisions[i] = Program.rand.Next(0, 101);            }        }    }    internal class Program    {        public static Random rand = new Random();        private static void Main(string[] args)        {            //参数            int populationSize = 100;            int numGenerations = 50;            double mutationRate = 0.2;            double crossoverRate = 0.8;            //构建初始群体            List<Individual> solutions = new List<Individual>();            for (int i = 0; i < populationSize; i++)            {                var solution = new Individual();                solution.Generate();                solution.Evaluate();                solutions.Add(solution);            }            //计算初始群体的平均分数            var averageScoreBefore = solutions.Select(x => x.Evaluate()).Average();            //迭代生成代数            for (int i = 0; i < numGenerations; i++)            {                //通过交配顺序对的解决方案构建后代                var offspring = new List<Individual>();                for (int e = 0; e < solutions.Count() - 1; e += 2)                {                    if (rand.NextDouble() < crossoverRate)                    {                        var newIndividual = new Individual();                        solutions[e].Decisions.CopyTo(newIndividual.Decisions, 0);                        newIndividual.Crossover(solutions[e + 1]);                        offspring.Add(newIndividual);                    }                }                //将我们的后代添加到我们的解决方案中                solutions.AddRange(offspring);                //以低概率突变解决方案                foreach (var solution in solutions)                {                    if (rand.NextDouble() < mutationRate)                    {                        solution.Mutate();                    }                }                //对我们的解决方案进行排序,并回采样到初始群体大小                solutions = solutions.OrderByDescending(x => x.Evaluate()).ToList();                solutions = solutions.Take(populationSize).ToList();            }            //计算之后的平均分数            var averageScoreAfter = solutions.Select(x => x.Evaluate()).Average();            Debug.WriteLine(averageScoreBefore + "," + averageScoreAfter);        }    }}

其他说明

你的运行时间主要取决于你的适应度评分函数。对于简单的数学函数,这个运行时间不会很难。显然,如果涉及到一个过程,你会希望将评估次数保持在最低限度。这是我的博士研究内容,我开发了一种名为GALE的新算法:

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注