• 遗传算法的简单使用


    1、示例说明

           前几天记了一下遗传算法的基本概念,我们知道,遗传算法就是模拟达尔文生物进化论而提出来的算法。这里提供一个遗传算法使用的简单示例,在这个示例中,有一条吃老鼠的蛇,这条蛇只吃体型较小的老鼠,老鼠种群经过N代繁殖,经历了物竞天择、适者生存的自然法则,最后基本都进化成了体型很大的老鼠,蛇吃不了它们,当然也有少数基因突变的老鼠体型还是很小,依然躲不过被蛇吃的命运。下面在unity中简单实现一下它:
     

    2、定义老鼠个体类

    ////////////////////////////////////////////////////////////////////
    //                          _ooOoo_                               //
    //                         o8888888o                              //
    //                         88" . "88                              //
    //                         (| ^_^ |)                              //
    //                         O  =  /O                              //
    //                      ____/`---'\____                           //
    //                    .'  \|     |//  `.                         //
    //                   /  \|||  :  |||//                          //
    //                  /  _||||| -:- |||||-                         //
    //                  |   | \  -  /// |   |                       //
    //                  | \_|  ''---/''  |   |                       //
    //                    .-\__  `-`  ___/-. /                       //
    //                ___`. .'  /--.--  `. . ___                     //
    //              ."" '<  `.___\_<|>_/___.'  >'"".                  //
    //            | | :  `- \`.;` _ /`;.`/ - ` : | |                 //
    //               `-.   \_ __ /__ _/   .-` /  /                 //
    //      ========`-.____`-.___\_____/___.-`____.-'========         //
    //                           `=---='                              //
    //      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
    //            佛祖保佑                    永无BUG                   //
    ////////////////////////////////////////////////////////////////////
    
    
    
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class RatItem : MonoBehaviour {
    
        public float size = 1;//大小
    
        public float survivalTime = 8;//存活时间
    
        //被蛇吃
        public void Dead()
        {
            survivalTime = Population.timeCount;
            gameObject.SetActive(false);
        }
        
    }

    3、定义老鼠种群管理类

    ////////////////////////////////////////////////////////////////////
    //                          _ooOoo_                               //
    //                         o8888888o                              //
    //                         88" . "88                              //
    //                         (| ^_^ |)                              //
    //                         O  =  /O                              //
    //                      ____/`---'\____                           //
    //                    .'  \|     |//  `.                         //
    //                   /  \|||  :  |||//                          //
    //                  /  _||||| -:- |||||-                         //
    //                  |   | \  -  /// |   |                       //
    //                  | \_|  ''---/''  |   |                       //
    //                    .-\__  `-`  ___/-. /                       //
    //                ___`. .'  /--.--  `. . ___                     //
    //              ."" '<  `.___\_<|>_/___.'  >'"".                  //
    //            | | :  `- \`.;` _ /`;.`/ - ` : | |                 //
    //               `-.   \_ __ /__ _/   .-` /  /                 //
    //      ========`-.____`-.___\_____/___.-`____.-'========         //
    //                           `=---='                              //
    //      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
    //            佛祖保佑                    永无BUG                   //
    ////////////////////////////////////////////////////////////////////
    
    
    
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class Population : MonoBehaviour {
        public GameObject ratPrefab;//老鼠prefab
        public int populationSize = 10;//种群大小
        public List<GameObject> population = new List<GameObject>();//老鼠种群
        static List<GameObject> ratSize;
        public static float timeCount = 0;//计时
        private int trailInterval = 10;//每一代训练间隔
        private int count = 1;//第几代老鼠
        public float mutation = 0.1f;//基因突变概率
        public Text countText;//第几代显示
        public Text timeCountText;//时间显示
    
        void Start () {
            //初始化第一代种群
            for (int i = 0; i < populationSize; i++)
            {
                Vector3 pos = new Vector3(Random.Range(-3, 3), 0, Random.Range(-3, 3));
                GameObject go = Instantiate(ratPrefab, pos, Quaternion.identity);
                float randomSize= Random.Range(1, 4);
                go.GetComponent<RatItem>().size = randomSize;
                go.transform.localScale = new Vector3(randomSize, randomSize, randomSize);
                population.Add(go);
            }
            ratSize = population.OrderByDescending(go => go.GetComponent<RatItem>().size).ToList();
        }
        
        void Update () {
            //定时繁衍新一代
            timeCount += Time.deltaTime;
            if (timeCount > trailInterval)
            {
                BreedNewPopulation();
                timeCount = 0;
            }
    
            countText.text ="繁衍代数:"+ count.ToString();
            timeCountText.text = "计时:" + timeCount.ToString();
        }
    
        //繁衍一代
        void BreedNewPopulation()
        {
            List<GameObject> newPopulation = new List<GameObject>();
            //给上一代个体列表按存活时间降序排序
            List<GameObject> sortedList = population.OrderByDescending(go => go.GetComponent<RatItem>().survivalTime).ToList();
            //清空上一代列表
            population.Clear();
            ratSize.Clear();
            //选择优良的两个父代(存活时间长)去繁殖新一代
            for (int i =0; i < (int)(sortedList.Count / 2); i++)
            {
                population.Add(Breed(sortedList[i].GetComponent<RatItem>(), sortedList[i + 1].GetComponent<RatItem>()));
                population.Add(Breed(sortedList[i + 1].GetComponent<RatItem>(), sortedList[i].GetComponent<RatItem>()));
            }
            ratSize = population.OrderByDescending(go => go.GetComponent<RatItem>().size).ToList();
            //销毁先前所有的种群
            for (int i = 0; i < sortedList.Count; i++)
            {
                Destroy(sortedList[i]);
            }
            count++;
        }
    
        //两个父代繁殖出新个体 (交叉)
        GameObject Breed(RatItem item1,RatItem item2)
        {
            Vector3 pos = new Vector3(Random.Range(-3, 3), 0, Random.Range(-3, 3));
            GameObject go = Instantiate(ratPrefab, pos, Quaternion.identity);
            RatItem item = go.GetComponent<RatItem>();
            //新个体随机继承父亲或母亲的基因
            if (Random.Range(0, 100) > mutation * 100)
            {
                float random= Random.Range(0, 1) > 0.5f ? item1.size : item2.size;
                item.size = random;
                go.transform.localScale = new Vector3(random, random, random);
            }
            //基因突变
            else
            {
                float random = Random.Range(0, 2);
                item.size = random;
                go.transform.localScale = new Vector3(random, random, random);
            }
            return go;
        }
    
    
        //得到体型最小的个体
         public static GameObject GetSmallRat()
        {
            if (ratSize.Count > 0)
            {
                GameObject go = ratSize[ratSize.Count - 1];
                go.GetComponent<RatItem>().Dead();
                ratSize.Remove(go);
                return go;
            }
            else
                return null;
        }
    
    
    }

    4、定义蛇类

    ////////////////////////////////////////////////////////////////////
    //                          _ooOoo_                               //
    //                         o8888888o                              //
    //                         88" . "88                              //
    //                         (| ^_^ |)                              //
    //                         O  =  /O                              //
    //                      ____/`---'\____                           //
    //                    .'  \|     |//  `.                         //
    //                   /  \|||  :  |||//                          //
    //                  /  _||||| -:- |||||-                         //
    //                  |   | \  -  /// |   |                       //
    //                  | \_|  ''---/''  |   |                       //
    //                    .-\__  `-`  ___/-. /                       //
    //                ___`. .'  /--.--  `. . ___                     //
    //              ."" '<  `.___\_<|>_/___.'  >'"".                  //
    //            | | :  `- \`.;` _ /`;.`/ - ` : | |                 //
    //               `-.   \_ __ /__ _/   .-` /  /                 //
    //      ========`-.____`-.___\_____/___.-`____.-'========         //
    //                           `=---='                              //
    //      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
    //            佛祖保佑                    永无BUG                   //
    ////////////////////////////////////////////////////////////////////
    
    
    
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using UnityEngine;
    
    public class Snake : MonoBehaviour {
        public float interval = 2;//每三秒吃一只老鼠
        private float timeCount = 0;//计时
    
        
        // Update is called once per frame
        void Update () {
            timeCount += Time.deltaTime;
            if (timeCount > interval)
            {
                EatRat();
                timeCount = 0;
            }
        }
    
        //吃老鼠
        void EatRat()
        {
            GameObject go = Population.GetSmallRat();
            if (go != null)
            {
                if (go.GetComponent<RatItem>().size < 2.5f)
                {
                    Debug.Log("吃只小老鼠!");
                    go.GetComponent<RatItem>().Dead();
                }
                else
                    Debug.Log("老鼠都太大了,我吃不下了!");
            }
        }
    }
    5、操作步骤与运行测试
            在上述代码中,首先初始化第一代老鼠种群,蛇会吃了淘汰掉体型较小的老鼠,老鼠种群会挑选基因优良(存活时间长)的老鼠父代去繁衍下一代。 在unity中,建好一个场景,并制作老鼠prefab,将RatItem类挂到该prefab上,准备好所有后运行场景:
     

    可以看到,经过5代繁衍,后面的老鼠体型都是很大一个了,蛇已经吃不了它们,但还是偶尔会有基因突变的小老鼠繁衍出来。

     如有错误,欢迎指正!

  • 相关阅读:
    java 读取ini文件
    JPA简单的分页条件查询
    工厂模式之简单工厂模式,head first设计模式
    mvnw 找不到或无法加载主类,找不到符号,类
    spring boot 通过feign调用api接口
    Ubuntu18.04 samba配置
    log4cplus例子
    ES->PES->PS打包程序
    RED5安装与配置
    Java 常用的日志工具——JDK自带的java.util.logging包、APACHE 的log4j 与 slf4j日志处理接口
  • 原文地址:https://www.cnblogs.com/IAMTOM/p/10267197.html
Copyright © 2020-2023  润新知