遗传算法初探-unity

遗传算法初探-unity

unity 机器学习 MachineLearning 遗传算法 Genetic Algorithm

引子 :茫茫宇宙中存在着一个神级文明,尽管他们有着领先的科技,但文明的进程却因为种种因素逐步走向灭亡。为了防止自身文明的覆灭,神级文明想要通过模拟自身文明形成和发展来寻求解救自身的办法。于是他们用自己的科技创造了数以万计的小宇宙,并为其播种下生命起源的种子,让文明得以演化。他们为这些创造的世界中潜移默化的植入超越文明自身进化的技术,加速文明的进程。他们观测着这些文明的走向,无数文明兴衰起落。尽管如此,仍然有着很多文明走向更远的未来,甚至由于神级文明不断注入超越他们时代的技术,他们也已经是接近神级文明的小宇宙。神级文明也从中寻找到了自身的影子,并吸取这些能存活文明的经验,摆脱自身灭亡的命运。

简介

遗传算法(Genetic Algorithm)是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。遗传算法可以算是计算机领域的仿生学。它摆脱多数解决问题的思路,把通过问题找到一组解的思路,转化为通过各种解来尝试最优的解决问题的思路,是一种像是“依赖倒转”的办法。

比如我们想到在灰色地面上最容易隐藏的猫,而猫的毛发颜色是由基因控制。我们通过一只褐色和一只白色的猫的父代,让他们繁殖并不断从繁殖后的世代中选取最容易在灰色地面隐藏的样本,让他们不断重复这一选择过程。经过数代的选择,个体中甚至突变产生了眼睛颜色也是灰色的个人体,我们会发现基因是灰色毛发,眼睛颜色也是灰色的个体不断存活下来,并得以生存。遗传算法模拟出了这种毛色(表达),繁殖后代(传递),眼睛变灰(突变),存活死亡(自然选择)的过程。

遗传

简易的遗传算法(Unity)

这里我们使用unity2d来模拟遗传算法的实现,创建一个2d角色为预制体,并为其添加2dcollider和DNA脚本。然后创建空物体,为其添加populationmanager脚本并添加预制体到参数,用来生成不同的角色。我们通过DNA来控制2d角色的材质颜色,再通过点击角色来挑出最接近某种颜色的角色肤色,然后不断重复这一过程。慢慢的,角色的肤色不断的接近我们所期望的某种肤色

color

DNA——决定角色的材质颜色即肤色

using UnityEngine;

namespace PeopleColor
{

    //基因,用来控制人的表现,肤色,大小等
    public class DNA : MonoBehaviour
    {

        //gene for colour
        public float r;
        public float g;
        public float b;
        public float s;
        bool dead = false;
        public float timeToDie = 0;
        SpriteRenderer sRenderer;
        Collider2D sCollider;

        //当鼠标点击的时候角色死亡,手动模拟遗传选择
        void OnMouseDown()
        {
            dead = true;
            timeToDie = PopulationManager.elapsed;
            sRenderer.enabled = false;
            sCollider.enabled = false;
        }

        // Use this for initialization
        void Start()
        {
            sRenderer = GetComponent<SpriteRenderer>();
            sCollider = GetComponent<Collider2D>();
            sRenderer.color = new Color(r, b, g);
        }
    }

}

PopulationManager——控制世代的繁衍

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

namespace PeopleColor
{
    public class PopulationManager : MonoBehaviour
    {

        public GameObject personPrefab;
        public int populationSize = 10;
        List<GameObject> population = new List<GameObject>();
        public static float elapsed = 0;
        /// <summary>
        /// 训练间隔
        /// </summary>
        int trialTime = 10;
        /// <summary>
        /// 第几代人
        /// </summary>
        int generation = 1;

        GUIStyle guiStyle = new GUIStyle();
        void OnGUI()
        {
            guiStyle.fontSize = 50;
            guiStyle.normal.textColor = Color.white;
            GUI.Label(new Rect(10, 10, 100, 20), "Generation: " + generation, guiStyle);
            GUI.Label(new Rect(10, 65, 100, 20), "Trial Time: " + (int)elapsed, guiStyle);
        }

        // Use this for initialization
        void Start()
        {

            //初始化:随机产生不同肤色和大小的人
            for (int i = 0; i < populationSize; i++)
            {
                Vector3 pos = new Vector3(Random.Range(-9, 9), Random.Range(-4.5f, 4.5f), 0);
                GameObject go = Instantiate(personPrefab, pos, Quaternion.identity);
                go.GetComponent<DNA>().r = Random.Range(0.0f, 1.0f);
                go.GetComponent<DNA>().g = Random.Range(0.0f, 1.0f);
                go.GetComponent<DNA>().b = Random.Range(0.0f, 1.0f);
                go.GetComponent<DNA>().s = Random.Range(0.1f, 0.3f);
                population.Add(go);
            }
        }

        /// <summary>
        /// 繁殖后代:模拟基因选择,二者择其一,或突变
        /// </summary>
        /// <param name="parent1">父代1</param>
        /// <param name="parent2">父代2</param>
        /// <returns></returns>
        GameObject Breed(GameObject parent1, GameObject parent2)
        {
            Vector3 pos = new Vector3(Random.Range(-9, 9), Random.Range(-4.5f, 4.5f), 0);
            GameObject offspring = Instantiate(personPrefab, pos, Quaternion.identity);
            DNA dna1 = parent1.GetComponent<DNA>();
            DNA dna2 = parent2.GetComponent<DNA>();
            //swap parent dna
            if (Random.Range(0, 1000) > 5)//5‰的概率产生突变
            {
                offspring.GetComponent<DNA>().r = Random.Range(0, 10) < 5 ? dna1.r : dna2.r;
                offspring.GetComponent<DNA>().g = Random.Range(0, 10) < 5 ? dna1.g : dna2.g;
                offspring.GetComponent<DNA>().b = Random.Range(0, 10) < 5 ? dna1.b : dna2.b;
                offspring.GetComponent<DNA>().b = Random.Range(0, 10) < 5 ? dna1.s : dna2.s;
            }
            else//变异
            {
                offspring.GetComponent<DNA>().r = Random.Range(0.0f, 1.0f);
                offspring.GetComponent<DNA>().g = Random.Range(0.0f, 1.0f);
                offspring.GetComponent<DNA>().b = Random.Range(0.0f, 1.0f);
                offspring.GetComponent<DNA>().s = Random.Range(0.1f, 0.3f);
            }
            return offspring;
        }

        /// <summary>
        ///
        /// </summary>
        void BreedNewPopulation()
        {
            List<GameObject> newPopulation = new List<GameObject>();
            //get rid of unfit individuals
            //淘汰不合适的个体
            List<GameObject> sortedList = population.OrderByDescending(o => o.GetComponent<DNA>().timeToDie).ToList();
            foreach (var o in sortedList)
            {
                Debug.Log("time2Die: " + o.GetComponent<DNA>().timeToDie);
            }
            population.Clear();
            //breed upper half of sorted list
            //繁殖已排序列表中的
            for (int i = (int)(sortedList.Count / 2.0f) - 1; i < sortedList.Count - 1; i++)
            {
                population.Add(Breed(sortedList[i], sortedList[i + 1]));
                population.Add(Breed(sortedList[i + 1], sortedList[i]));
            }

            //destroy all parents and previous population
            //销毁先前所有的种群
            for (int i = 0; i < sortedList.Count; i++)
            {
                Destroy(sortedList[i]);
            }
            generation++;
        }

        // Update is called once per frame
        void Update()
        {
            elapsed += Time.deltaTime;
            if (elapsed > trialTime)
            {
                BreedNewPopulation();
                elapsed = 0;
            }
        }
    }

}

原文地址:https://www.cnblogs.com/Firepad-magic/p/8685964.html

时间: 2024-08-04 17:19:07

遗传算法初探-unity的相关文章

FingerGestures研究院之初探Unity手势操作

最近研究了一下Unity中的一个手势操作的插件FingerGestures.它能很方便监听到Unity中的各种手势事件:上下左右四方向的滑动事件.按下事件.抬起事件.移动事件.连击事件.长按事件等等.它同时支持触摸屏操作与鼠标操作,总起来说使用起来还是比较方便的,今天写下教程记录这个插件的详细使用步骤.首先下载这个插件,大家可以在圣典上找这个插件的下载地址,当然也可以在本文最后下载该插件.  我看了一下这个插件底层的实现步骤,他是通过C#代理的形式来实现手势操作的.如下图红圈内所示,这五个重要的

Unity Shader 学习之旅-初探

Unity Shader 学习之旅-初探 unity shader 图形图像 美丽的梦和美丽的诗一样 都是可遇而不可求的--席慕蓉 最简单的顶点片元着色器 顶点片元着色器基本结构 Unity Shader基本结构:Shader ,Properties,SubShder,Fallback等. 结构 Shader "ShaderName"{  Properties{  //属性,暴露在inspector面板上  }  SubShader{  //针对显卡A的SubShader  Pass{

Unity初探之黑暗之光(1)

Unity初探之黑暗之光(1) 1.镜头拉近 1 public float speed=10f;//镜头的移动速度 2 public int endZ = -20;//镜头的结束位置 3 4 // Update is called once per frame 5 void Update () { 6 if (transform.position.z<endZ) 7 { 8 transform.Translate(Vector3.forward * speed * Time.deltaTime)

unity初探之黑暗之光(2)

unity初探之黑暗之光(2) 一.设置角色跟随鼠标点击移动 思路:使用charactercollider的SimpleMove方法来控制角色的移动.通过摄像机的射线投射到地面,通过屏幕上的一个点也就是鼠标单击的点.该射线与地面发生碰撞返回发生碰撞的点,然后让角色转向该点,开始移动.当移动到一定范围时停止移动. 使用到的方法: Camera.ScreenPointToRay 屏幕位置转射线 function ScreenPointToRay (position : Vector3) : Ray

Unity初探—SpaceShoot

Unity初探—SpaceShoot DestroyByBoundary脚本(C#) 在游戏中我们添加了一个Cube正方体,让他来作为游戏的边界.它是可以触发触发事件的(勾选Is Trigger),当游戏中的碰撞体结束trigger事件,也就是出了正方体边界,我们就将其销毁. 1 void OnTriggerExit(Collider other) 2 { 3 Destroy(other.gameObject); 4 } Description描述 OnTriggerExit is called

unity初探学习笔记-hello unity

unity3d是目前使用最广泛的3d游戏引擎之一,本系列教程将使用unity制作一款坦克大战游戏,从而带大家体验一下unity的使用. 这一篇教程主要介绍引擎的安装和环境的搭建,最后,我们会在手机上运行起来unity的第一个程序. 首先在unity的官方网站上下载unity的最新引擎,目前最新的版本是5.3.4,下载地址:http://unity3d.com/cn/get-unity/download?ref=personal 下载后一步步的按照提示安装即可,运行起unity,效果如下: 在这里

【Unity Shaders】初探Surface Shader背后的机制

转载请注明出处:http://blog.csdn.net/candycat1992/article/details/39994049 写在前面 一直以来,Unity Surface Shader背后的机制一直是刚開始学习的人为之困惑的地方. Unity Surface Shader在Unity 3.0的时候被开放给公众使用.其宣传手段也是号称让所有人都能够轻松地写shader.但因为资料缺乏,非常多人知其然不知其所以然,无法理解Unity Surface Shader在背后为我们做了哪些事情.

Unity 5 全局光照GI与新的烘焙系统初探

GI是啥 Realtime GI,实时全局光照,听上去就是一个非常高大上的词,但是越高大上就越令人心生敬畏,因为世上没有免费的午餐,越好的效果意味着越多的消耗,对于移动平台来说,这样的消耗受不受的起呢?首先来说说GI是干啥的,非常粗略的来描述下,如果说我们以前的光照系统就是由光源 - 物体 - 视点组成的话,那么全局光照系统就是由光源 - n多环境反射光 - 物体 - 视点.就是说GI额外包括了环境反射光的计算,它可以使得渲染出来的场景物体间的光影交互更为真实. 如果是离线烘焙的话,n多的环境反

Unity之UGUI初探—按钮动画

今天试了一下unity的新的UI系统—UGUI,感觉很强大,很多功能一目了然,使用起来相当方便接下来就是先试试使用他的动画吧 先创建一个UGUI的按钮,当然也可以先创建画布,然后在画布上创建按钮 然后点击按钮, 图中的transition的选项点开之后,有一项Animation的选项, 点击之后选择Auto Generate Animation 之后会弹出文件夹选项,就会意思是新建的这个动画的保存路径,自己选择路径命名即可,但要在Assets文件夹下 之后在window下,可以选择Animati