遺傳演算法的簡單使用
阿新 • • 發佈:2019-01-14
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代繁衍,後面的老鼠體型都是很大一個了,蛇已經吃不了它們,但還是偶爾會有基因突變的小老鼠繁衍出來。
如有錯誤,歡迎指正!