Unity中实现遗传算法【语言:C#】

3 篇文章 0 订阅
3 篇文章 0 订阅
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 遗传算法
/// </summary>
public class GeneticAlgorithm
{
    private List<Attr> curAttrList=new List<Attr>();
    private List<Attr> childAttrList = new List<Attr>();
    //传入种群|繁殖进化后再返回出去
    public List<Attr> Pushout(List<Attr> Attrs)
    {
        curAttrList = Attrs;
        tempcount = curAttrList.Count;
        childAttrList.Clear();
        SortAttr();
        return ChooseBest();
    }
    //排序
    private void SortAttr()
    {
        //从小到大排序
        curAttrList.Sort((left, right) =>
        {
            return left.fitness.CompareTo(right.fitness);
        });  
    }
    int tempcount;//初始的长度
    int splitBest = 0;

    //对个体选择
    private Attr Choose(List<Attr> attrs)
    {
        float totalfitness = 0;//总适应度
        foreach (var Attr in curAttrList)
        {
            totalfitness += Attr.fitness;
        }
        float totalpercent = 0;
        float rand = UnityEngine.Random.Range(0f, totalfitness);
        foreach (var attr in curAttrList)
        {
            totalpercent += attr.fitness;
            if (totalpercent >= rand)
                return attr.Clone();
        }
        return null;
    }
    //赌轮盘选择[(优秀基因保留)1/4效果比较好]
    private List<Attr> ChooseBest()//
    {
        while (true)
        {
            Attr attr1 = Choose(curAttrList);
            Attr attr2 = null;
            bool boo = true;//是否一样
            while (true)
            {
                attr2 = Choose(curAttrList);
                for (int i = 0; i < attr2.neuralNetwork.WeightList.Count; i++)
                {
                    if(attr2.neuralNetwork.WeightList[i]!= attr1.neuralNetwork.WeightList[i])
                    {
                        boo = false;
                        break;
                    }
                }
                if (!boo)
                    break;
            }
            Attr child1;
            Attr child2;
            CrossAttr(attr1, attr2, out child1, out child2);

            childAttrList.Add(child1);
            childAttrList.Add(child2);
            if (childAttrList.Count == (int)tempcount*3/4)
                break;
            if (childAttrList.Count > (int)tempcount * 3 / 4)
            {
                childAttrList.Remove(child2);
                break;
            }
        }

        VariationAttr(childAttrList);//变异
        //新生的交叉变异|优秀的保存不动
        /************      交叉变异     *************/
        int temp = childAttrList.Count;
        for (int i = tempcount-1; i >temp-1 ; i--)//特殊挑选的best也加入新群体
        {
            childAttrList.Add(curAttrList[i].Clone());
        }
        return childAttrList;
    }
    public void Foresh(double[] d)
    {

        string str = "";
        foreach (var item in d)
        {
            str += item.ToString() + ",";

        }
        Debug.LogError("权重s:" + str);
    }
    private List<Attr> crossAttrList;
    //交叉
    private void CrossAttr(Attr Attr1,Attr Attr2,out Attr child1,out Attr child2)
    {
        int count = Attr1.neuralNetwork.WeightList.Count;//基因的长度
        int index1 = UnityEngine.Random.Range(0, count - 1);
        int index2 = UnityEngine.Random.Range(index1, count);

        child1 = Attr1.Clone();
        child2 = Attr1.Clone();
        for (int j = index1; j < index2; j++)
        {
            double temp = child1.neuralNetwork.WeightList[j];
            child1.neuralNetwork.WeightList[j] = child2.neuralNetwork.WeightList[j];//基因片段交换
            child2.neuralNetwork.WeightList[j] = temp;//这里已经交叉了 

            if (child1.neuralNetwork.WeightList.Count == 0)
            child1.neuralNetwork.LoadWeight(child1.neuralNetwork.WeightList);
            if (child2.neuralNetwork.WeightList.Count == 0)
            child2.neuralNetwork.LoadWeight(child2.neuralNetwork.WeightList);
        }

    }
    float variation = 0.2f;//1/50 0.02的概率突变
    //变异[突变]
    private void VariationAttr(List<Attr> list)//ok
    {
        for (int i = 0; i < list.Count; i++)
        {
            float ran = UnityEngine.Random.Range(0, 1f);
            if (ran <= variation) //1/50的概率突变基因随一个片段[一部分]位置
            {
                int count = list[i].neuralNetwork.WeightList.Count;//基因的长度
                int index = UnityEngine.Random.Range(0, count);//变异一个片段
                list[i].neuralNetwork.WeightList[index] = UnityEngine.Random.Range(-1f, 1f);
                if (list[i].neuralNetwork.WeightList.Count == 0)
                list[i].neuralNetwork.LoadWeight(list[i].neuralNetwork.WeightList);
            }
        }
    }
}

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值