自己进化的Unity人工智能(三)

来源:互联网 发布:创想电玩淘宝店靠谱吗 编辑:程序博客网 时间:2024/05/27 00:29

贴上(二)的地址:第二章

这次基于上一章所讲主要讲解一下遗传算法的代码:

   先说一下遗传算法的实现所需要的步骤:

   需要知道这几点:

1、  种群:

 

生物以种群形式进行(这也是游戏中训练的难点,并无法大规模的训练);

2、  个体:

 

组成种群的单个生物;

3、  基因:

 

一个遗传因子(这里我们是单个的权重);

4、  染色体:

 

一组基因(也就是这一组权重);

5、  生存竞争,适者生存:

这里我们需要适应度来决定哪个更能适应这个环境,从而选择NB的基因进行繁殖;适应度低的也就是上一章讲的靠山下的给正义掉;从而选择优秀的基因进行繁殖;

6、  遗传和变异:

新个体会遗传父母双方各一部分的基因,同时有一定的概率发生基因变异。(这个父母双方)这里我们采用一个轮盘赌的算法来决定这对夫妇;

 

遗传步骤:

1、  随机种群基因:因为第一组的是弱智他不知道干什么;这需要在开始的时候初始化;

2、  然后开始按照第一部分的基因开始神经网络判定和行为;

3、  根据规则的一顿击杀评分来计算出他的适应度,因为这里只讲遗传算法的脚本,SO不多讲;

4、  到时间后进行新的一波繁殖,根据适应度;也就是只找到了两只优秀的坦克;

5、  繁殖过程需要经过交叉,变异和遗传;

6、  第二轮经过优秀的坦克的基因继续进行行为;

 

 

下面贴代码:(代码已经在我个人认为的难点和属性做了注释)

using System;using System.Collections.Generic;using System.Linq;    public class Geneticalgorithm {  //选择的方法        public int Count;//种群数量        public List<IGizeable> ListIG; //储存种群所有个体        public double Mutation;    //变异概率        public static Random _random = new Random();        public Geneticalgorithm(int poCount, double mutate) {                       this.Count = poCount;            this.Mutation = mutate;            ListIG = new List<IGizeable>(poCount);        }                  private List<IGizeable> GetAThera() {   //获取同样种群数量的对数的夫妇来用来繁殖新的群体            var res = new List<IGizeable>(2 * Count);            var sum = ListIG.Sum(            itme => itme.fitness            );  //获取这个群体所有适应度的总和            var fitnessgote = new double[Count];   //用来储存每一个 单体生物的适应度概率;            for (var i = 0; i < fitnessgote.Length; i++) fitnessgote[i] = ListIG[i].fitness / sum;  //计算每一个适应度的概率             fitnessgote.OrderByDescending(                 x => x                 );               var counter = 0;            while (counter < Count) {//循环不停的配对  每一对基本上都不一样                var leftGen = RandomIndex(fitnessgote);   //获取适应度最好的那个个体下标;                var rightGen = RandomIndex(fitnessgote);//获取另一个 两个不一样                if (leftGen == rightGen) continue;                res.Add(ListIG[leftGen].Reproduce());                res.Add(ListIG[rightGen].Reproduce());                counter ++;            }            return res;        }        public void Cross(IGizeable mom, IGizeable dad) {//交叉              var momW = mom._weightAndBasi;            var dadW = dad._weightAndBasi;            var n = _random.Next(momW.Count);             for (var i = 0; i < momW.Count; i++) {                if (i < n)                    momW[i] = dadW[i];                else                    dadW[i] = momW[i];            }            mom._weightAndBasi = momW;            dad._weightAndBasi = dadW;        }        private void AllReproduce(List<IGizeable> pairs) {//繁殖新一代群体基因;        ListIG.Clear();            for (var i = 0; i < pairs.Count; i += 2) {            Cross(pairs[i], pairs[i + 1]);            Muta(pairs[i]);            ListIG.Add(pairs[i]);            }        }      public void Evolve(double[] newFitnesses) {//进化              for (var i = 0; i < newFitnesses.Length; i++) ListIG[i].fitness = newFitnesses[i];        AllReproduce(GetAThera());        }              public void Randomlation(double min = -1.0, double max = 1.0) {//随机种群  在训练初始化时调用            for (var i = 0; i < Count; i++)            Randommm(ListIG[i], min, max);        }         private int RandomIndex(IList<double> probs) {  //算法返回下标                               double top = 0;                    var randomValue = _random.NextDouble();                    for (var i = 0; i < probs.Count; i++) {                        var bot = top;                        top += probs[i];                        if (randomValue >= bot && randomValue <= top) return i;                    }                    return 0;                        }    public void Muta(IGizeable gen) {//变异            var w = gen._weightAndBasi;            for (var i = 0; i < w.Count; i++)                if (_random.NextDouble() < Mutation) w[i] += _random.NextDouble() * 2 - 1;            gen._weightAndBasi = w;        }        private static void Randommm(IGizeable gen, double min, double max) {            var w = gen._weightAndBasi;            for (var i = 0; i < w.Count; i++) {                w[i] = _random.NextDouble() * (max - min) + min;                            }            gen._weightAndBasi = w;         }    }    public interface IGizeable {//优化遗传接口  用来储存继承这个接口的所有个体;        List<double> _weightAndBasi { get; set; }  //一组遗传基因(这里也就是这组权重和偏移);        double fitness { get; set; } //适应度  用来决定淘汰的是谁;    IGizeable Reproduce();     //繁殖的方法;    }


因为我这里都在分开讲,最后会结合在一起讲,其他细节先不需要考虑 ,主要理解遗传

原创粉丝点击