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

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

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