遗传算法简介:

一直都在收听卓老板聊科技这个节目,最近播出了一起人工智能的节目,主要讲的是由霍兰提出的遗传算法,在目中详细阐述了一个有趣的小实验:吃豆人。

首先简单介绍下遗传算法:
1:为了解决某个具体的问题,先随机生成若干个解决问题的实体,每个实体解决问题的方式都用“基因”来表示,也就是说,不同的实体拥有不同的基因,那么也对应着不同的解决问题的方案。
2:有了若干实体之后,接下来就是让这些实体来完成这个任务,根据任务的完成情况用相同标准打分。
3:接下来是进化环节,按照得分的高低,得出每个个体被选出的概率,得分越高越容易被选出,先选出两个个体,对其基因进行交叉,再按照设定的概率对其基因进行突变,来生成新个体,不停重复直到生成足够数量的新个体,这便是一次进化过程。按照这个方法不停的进化,若干代之后就能得到理想的个体。

下面简单介绍下吃豆人实验:

吃豆人首先生存在一个10*10个格子组成的矩形空间中,将50个豆子随机放在这100个格子中,每个格子要嘛为空,要嘛就有一颗豆子。吃豆人出生的时候随机出现在一个任意方格中,接下来吃豆人需要通过自己的策略来吃豆子,一共只有200步,吃到一颗+10分,撞墙-5分,发出吃豆子的动作却没吃到豆子-1分。另外吃豆人只能看到自己所在格子和上下左右一共5个格子的情况。

整理一下
吃豆人的所有动作:上移、下移、左移、由移、吃豆、不动、随机移动,一共7种
吃豆人所能观察到的状态:每个格子有,有豆子,无豆子,墙3种状态,而一共有5个格子,那就是3^5=243种状态。

为此,吃豆人个体的基因可以用243长度的基因表示,分别对应所处的243种状态,每个基因有7种情况,分别表示所处状态下产生的反应。

代码

Main.java

public class Main {public static void main(String[] args) {Population population = new Population(1000, false);System.out.println(population);long count = 1;while (true){                           Population newPopulation = Algorithm.evolve(population);if (count % 5 == 0) {System.out.println("The " + count + "'s evolve");System.out.println(newPopulation);  }population = newPopulation;count++;            }}
}

Individual.java

public class Individual {//吃豆人一共会有3^5种状态,它能观察的位置一共有上下左右和当前格子,一个共5个,每个格子有墙,豆子,无豆子3种状态。private static int length = 243;/*吃豆人一共有7总动作* 0 :上    4 : 随机移动* 1 : 左   5 : 吃* 2 : 下   6 : 不动  * 3 : 右    */private static byte actionNum = 7;private byte genes[] = null;private int fitness = Integer.MIN_VALUE;public Individual() {genes = new byte[length];       }public void generateGenes(){        for (int i = 0; i < length; i++) {byte gene = (byte) Math.floor(Math.random() * actionNum);genes[i] = gene;}}public int getFitness() {if (fitness == Integer.MIN_VALUE) {fitness = FitnessCalc.getFitnessPall(this);}return fitness;}public int getLength() {return length;}public byte getGene(int index) {return genes[index];}public void setGene(int index, byte gene) {this.genes[index] = gene;fitness = Integer.MIN_VALUE;}//状态码的转换:5个3进制位,第一个代表中,第二个代表上,第三个代表右,第四个代表下,第五个代表左public byte getActionCode(State state) {        int stateCode = (int) (state.getMiddle() * Math.pow(3, 4) + state.getUp() * Math.pow(3, 3) + state.getRight() * Math.pow(3, 2) + state.getDown() * 3 + state.getLeft());return genes[stateCode];}@Overridepublic String toString() {  StringBuffer bf = new StringBuffer();for (int i = 0; i < length; i++) {bf.append(genes[i]);}return bf.toString();}public static void main(String[] args) {Individual ind = new Individual();ind.generateGenes();System.out.println(ind);System.out.println(ind.getFitness());System.out.println(FitnessCalc.getFitnessPall(ind));}
}

State.java

public class State {//0为墙,1为有豆子,2为无豆子   private byte middle;private byte up;private byte right;private byte down;private byte left;public State(byte middle, byte up, byte right, byte down, byte left) {this.middle = middle;this.up = up;this.right = right;this.down = down;this.left = left;}public byte getMiddle() {return middle;}public void setMiddle(byte middle) {this.middle = middle;}public byte getUp() {return up;}public void setUp(byte up) {this.up = up;}public byte getRight() {return right;}public void setRight(byte right) {this.right = right;}public byte getDown() {return down;}public void setDown(byte down) {this.down = down;}public byte getLeft() {return left;}public void setLeft(byte left) {this.left = left;}}

Algorithm.java

public class Algorithm {/* GA 算法的参数 */private static final double uniformRate = 0.5; //交叉概率private static final double mutationRate = 0.0001; //突变概率private static final int tournamentSize = 3; //淘汰数组的大小public static Population evolve(Population pop) {Population newPopulation = new Population(pop.size(), true);for (int i = 0; i < pop.size(); i++) {//随机选择两个 优秀的个体Individual indiv1 = tournamentSelection(pop);Individual indiv2 = tournamentSelection(pop);           //进行交叉Individual newIndiv = crossover(indiv1, indiv2);newPopulation.saveIndividual(i, newIndiv);  }// Mutate population  突变for (int i = 0; i < newPopulation.size(); i++) {mutate(newPopulation.getIndividual(i));}   return newPopulation;       }       // 随机选择一个较优秀的个体,用了进行交叉private static Individual tournamentSelection(Population pop) {// Create a tournament populationPopulation tournamentPop = new Population(tournamentSize, true);//随机选择 tournamentSize 个放入 tournamentPop 中for (int i = 0; i < tournamentSize; i++) {int randomId = (int) (Math.random() * pop.size());tournamentPop.saveIndividual(i, pop.getIndividual(randomId));}// 找到淘汰数组中最优秀的Individual fittest = tournamentPop.getFittest();return fittest;}// 进行两个个体的交叉 。 交叉的概率为uniformRateprivate static Individual crossover(Individual indiv1, Individual indiv2) {Individual newSol = new Individual();// 随机的从 两个个体中选择 for (int i = 0; i < indiv1.getLength(); i++) {if (Math.random() <= uniformRate) {newSol.setGene(i, indiv1.getGene(i));} else {newSol.setGene(i, indiv2.getGene(i));}}return newSol;}// 突变个体。 突变的概率为 mutationRateprivate static void mutate(Individual indiv) {for (int i = 0; i < indiv.getLength(); i++) {if (Math.random() <= mutationRate) {// 生成随机的 0-6byte gene = (byte) Math.floor(Math.random() * 7);indiv.setGene(i, gene);}}}
}

Population.java

public class Population {private Individual[] individuals;public Population(int size, boolean lazy) {individuals = new Individual[size];if (!lazy) {for (int i = 0; i < individuals.length; i++) {Individual ind = new Individual();ind.generateGenes();individuals[i] = ind;}}}public void saveIndividual(int index, Individual ind) {individuals[index] = ind;}public Individual getIndividual(int index) {return individuals[index];}public Individual getFittest() {Individual fittest = individuals[0];// Loop through individuals to find fittestfor (int i = 1; i < size(); i++) {if (fittest.getFitness() <= getIndividual(i).getFitness()) {fittest = getIndividual(i);}}return fittest;}public Individual getLeastFittest() {Individual ind = individuals[0];for (int i = 1; i < size(); i++) {if (ind.getFitness() > getIndividual(i).getFitness()) {ind = getIndividual(i);}}return ind;}public double getAverageFitness() {double sum = 0;for (int i = 0; i < size(); i++) {sum += individuals[i].getFitness();}return sum / size();}public int size() {return individuals.length;}@Overridepublic String toString(){StringBuffer bf = new StringBuffer();bf.append("Population size: " + size() + "\n");bf.append("Max Fitnewss: " + getFittest().getFitness() + "\n");bf.append("Least Fitness: " + getLeastFittest().getFitness() + "\n");bf.append("Average Fitness: " + getAverageFitness() + "\n");        return bf.toString();}public static void main(String[] args) {Population population = new Population(8000, false);System.out.println(population);    }
}

MapMgr.java

public class MapMgr {private static int x = 10;private static int y = 10;private static int beanNum = 50;private static int mapNum = 100;private static MapMgr manager = null;       private Map[] maps = null;private MapMgr() {maps = new Map[mapNum];for (int i = 0; i < mapNum; i++) {Map map = new Map(x, y);map.setBeans(beanNum);maps[i] = map;}}synchronized public static MapMgr getInstance() {if (manager == null) manager = new MapMgr();return manager;}public Map getMap(int index) {Map map = null;index = index % mapNum;try {map = maps[index].clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return map;     }public static void main(String[] args) {MapMgr mgr = MapMgr.getInstance();mgr.getMap(1).print();System.out.println("--------------");mgr.getMap(2).print();}
}

Map.java

import java.awt.Point;public class Map implements Cloneable{private int x = -1;private int y = -1;private int total = -1;private byte[][] mapGrid = null;public Map(int x, int y) {this.x = x;this.y = y;mapGrid = new byte[x][y];total = x * y;}public void setBeans(int num) {//check num if (num > total) {num = total;}for (int i = 0; i < num; i++) {int address, xp, yp;do{address = (int) Math.floor((Math.random() * total)); //生成0 - (total-1)的随机数          xp = address / y;yp = address % y;   //System.out.println(xp+ ":" + yp + ":" + address + ":" + total);} while (mapGrid[xp][yp] != 0);mapGrid[xp][yp] = 1;            }}public boolean isInMap(int x, int y) {      if (x < 0 || x >= this.x) return false;if (y < 0 || y >= this.y) return false;     return true;}public boolean hasBean(int x, int y) {boolean ret = mapGrid[x][y] == 0 ? false : true;return ret;}public boolean eatBean(int x, int y) {if(hasBean(x, y)) {mapGrid[x][y] = 0;return true;}return false;}public Point getStartPoint() {              int x = (int) Math.floor(Math.random() * this.x);int y = (int) Math.floor(Math.random() * this.y);       return new Point(x, y);}public State getState(Point p) {        byte middle = stateOfPoint(p);byte up = stateOfPoint(new Point(p.x, p.y - 1));byte right = stateOfPoint(new Point(p.x + 1, p.y));byte down = stateOfPoint(new Point(p.x, p.y + 1));byte left = stateOfPoint(new Point(p.x - 1, p.y));return new State(middle, up, right, down, left);}//0为墙,1为有豆子,2为无豆子private byte stateOfPoint(Point p) {byte ret;if (!isInMap(p.x, p.y)) ret = 0;            else if (mapGrid[p.x][p.y] == 0) ret =  2;else ret = 1;return ret;}@Overridepublic Map clone() throws CloneNotSupportedException {Map m = (Map) super.clone();byte[][] mapGrid = new byte[x][y];for (int i = 0; i < x; i++) {for (int j = 0; j < y; j++) {mapGrid[i][j] = this.mapGrid[i][j];}}m.mapGrid = mapGrid;return m;       }public void print() {for (int i = 0; i < y; i++) {for (int j = 0; j < x; j++) {System.out.print(mapGrid[j][i]);}System.out.println();}}public static void main(String[] args) {Map m = new Map(10, 5);Map m1 = null;try {m1 = m.clone();} catch (CloneNotSupportedException e) {// TODO Auto-generated catch blocke.printStackTrace();}m.setBeans(40);m.print();m1.setBeans(15);m1.print();}}

FitnessCalc

import java.awt.Point;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class FitnessCalc {/*动作结果说明:* 撞墙:-5分* 吃到豆子:10分* 吃空了:-1分* 其他:0分*/ //模拟进行的场数private static int DefaultSimTimes = 1000;//模拟进行的步数private static int simSteps = 200;private static int cores = 4;public static int getFitness(Individual ind) {return getFitness(ind, DefaultSimTimes);}public static int getFitness(Individual ind, int simTimes) {int fitness = 0;        MapMgr mgr = MapMgr.getInstance();  for (int i = 0; i < simTimes; i++) {Map map = mgr.getMap(i);Point point = map.getStartPoint();  for (int j = 0; j < simSteps; j++) {State state = map.getState(point);byte actionCode = ind.getActionCode(state);fitness += action(point, map, actionCode);//map.print();//System.out.println("---");}                               }       return fitness / simTimes;}public static int getFitnessPall(Individual ind) {int fitness = 0;        if (DefaultSimTimes < 100) {fitness = getFitness(ind);} else {                            FutureTask<Integer>[] tasks = new FutureTask[cores];            for (int i = 0; i < cores; i++) {FitnessPall pall = null;if (i == 0) {pall = new FitnessPall(ind, (DefaultSimTimes / cores) + DefaultSimTimes % cores);} else {pall = new FitnessPall(ind, DefaultSimTimes / cores);   }               tasks[i] = new FutureTask<Integer>(pall);Thread thread = new Thread(tasks[i]);thread.start();}       for (int i = 0; i < cores; i++) {try {fitness += tasks[i].get();} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}}fitness = fitness / cores;}return fitness;}private static int action(Point point, Map map, int actionCode) {int sorce = 0;switch (actionCode) {case 0:if (map.isInMap(point.x, point.y - 1)) {sorce = 0;point.y = point.y - 1;} else {sorce = -5;}           break;case 1:if (map.isInMap(point.x - 1, point.y)) {sorce = 0;point.x = point.x - 1;} else {sorce = -5;}break;case 2:if (map.isInMap(point.x, point.y + 1)) {sorce = 0;point.y = point.y + 1;} else {sorce = -5;}break;case 3: if (map.isInMap(point.x + 1, point.y)) {sorce = 0;point.x = point.x + 1;} else {sorce = -5;}break;case 4:int randomCode = (int) Math.floor(Math.random() * 4);sorce = action(point, map, randomCode);         break;case 5:if (map.eatBean(point.x, point.y)) {sorce = 10;             } else {sorce = -1;}break;case 6: sorce = 0;break;}return sorce;}}class FitnessPall implements Callable<Integer> {private int simTimes;private Individual ind;public FitnessPall(Individual ind, int simTimes) {this.ind = ind;this.simTimes = simTimes;       }@Overridepublic Integer call() throws Exception {return FitnessCalc.getFitness(ind, simTimes);       }
}

简单的遗传算法(Genetic algorithms)-吃豆人相关推荐

  1. 从零开始为《吃豆人》创建BT

    从零开始为<吃豆人>创建BT 这一次我们对<吃豆人>游戏创建一组逐渐复杂的BT. 如图所示BT通过包含多个幽灵和大量药丸的迷宫控制智能体,即吃豆人,这些药丸中大的药丸就是说为的 ...

  2. 一个关于遗传算法的java小实验(吃豆人)

    遗传算法就是利用遗传学中父代基因杂交产生子代的原理,通过良种配对.遗传进化来改良子代的算法. 遗传算法非常适合用来处理离散型的决策问题,通过对父代中优良模型的参数进行杂交,产生下一代模型,淘汰其中效果 ...

  3. JS实现简单的吃豆人小游戏

    吃豆人小游戏 今天练习了一下JS,写了一个吃豆人的小demo Html以及CSS部分 首先定义一个div,用来存放吃豆人的一些元素,我们给他加一个id="game",然后我们在这d ...

  4. c语言吃豆人游戏怎么理解,python 实现简单的吃豆人游戏

    效果展示: 程序简介 1.使用pygame模组 2.在material目录下有一些素材 3.吃豆人的游戏主体 4.吃豆人怪物的AI(未使用深度学习) 主要代码 main.py import pygam ...

  5. AI与游戏——吃豆人(4)方法综述

    这一部分先提一下一些基本的目前广泛用于游戏中的AI算法.这里最好现有点机器学习相关知识,不然可能会不知所云.后面提到具体算法我会尽量列出一些参考文献,例子也继续在吃豆人上面举例. 目前主流方法主要有, ...

  6. 玩了5万局游戏,英伟达让GameGAN自己生成「吃豆人」,世界首创无需游戏引擎...

    本文转载自新智元(AI_era).   新智元报道   编辑:元子 [新智元导读]近几年来,英伟达在GAN这个领域越走越远.英伟达推出"GameGAN",不需要任何底层游戏引擎,用 ...

  7. pacman吃豆人_通过Tensorflow和强化学习实现自动化吃豆人PacMan

    介绍 在涉及GradientCrescent强化学习基础的文章中,我们研究了基于模型和基于样本的强化学习方法. 简而言之,前一类的特征是需要了解所有可能状态转换的完整概率分布,并且可以通过马尔可夫决策 ...

  8. java吃豆人代码讲解_在吃豆人的这一关里,隐藏着来自程序员的深深恶意

    本文转载自公众号"把科学带回家"(ID:steamforkids) 作者 七君 玩过吃豆人吧.通关过吗? 通关是不可能的,这辈子都不可能的.因为吃豆人根本不可能通关. 不可能通关的 ...

  9. 吃豆人动态模型创建---canvas

    吃豆人模型 吃豆人是我们小时候常玩的街机游戏,常常能勾起我们童年的回忆,写这些文章也是为了记录学习,保留回忆的,如果可以帮助到你们也会很开心,可能内容有些太基础,希望不要介意. 因为不是一个完整的小游 ...

最新文章

  1. delphi listview动态添加图片_网站图片如何优化适合收录
  2. android 入门-工序
  3. 组策略 从入门到精通 (一) 组策略的还原与备份和汇入
  4. ArrayBlockingQueue原理分析-remove方法
  5. String.valueOf()方法与toString()方法的区别
  6. 12月29日二周五次【Python基础语法】
  7. ubuntu 10.04 CTS 环境搭建
  8. jedis mysql 数据结构_Redis的数据结构和内部编码
  9. 杭电3790最短路径问题
  10. Python的底气,是从哪儿来的?
  11. Q134:PBRT-V3,次表面散射(Subsurface Scattering)(15.5章节)
  12. CentOS 安装快速Nginx-1.12.0
  13. oracle中日期格式的注意事项
  14. easyui及eova下select:option、find无法直接取值的解决办法
  15. QQxml红包跳转群代码
  16. 实型变量的定义和应用
  17. 如何利用Tempo BI大数据分析工具快速完成数据同环比分析?
  18. 全球游戏人热评CGDC 09 盛赞中国网游产业
  19. 山东理工ACM 1115 C语言实验——交换两个整数的值(顺序结构)两种方法
  20. 基于51单片机的电子钟万年历LCD1602显示

热门文章

  1. setup Factory 卸载文件报错 invalid uninstall control file:c:\Program
  2. pytorch创建data.DataLoader时,参数pin_memory的理解
  3. 爬虫中“目标计算机积极拒绝”问题的解决
  4. 前端基础 - HTML简介及开发环境
  5. 02Flink实时数仓(尚硅谷)- DWD层数据准备
  6. 【MIUI】MIUI Issues
  7. html页面里放视频支持的格式
  8. SAP IRPA ---LoginSAP的更简单方式
  9. vf6.0计算机应用考试,vf期末考试题库含答案
  10. 计算机组成原理考试试题,计算机组成原理期末考试试题1