遗传算法解决迷宫寻路问题(Java实现)
来源:互联网 发布:php 去除数组重复值 编辑:程序博客网 时间:2024/05/16 06:38
1.什么是遗传算法?
就个人理解,遗传算法是模拟神奇的大自然中生物“优胜劣汰”原则指导下的进化过程,好的基因有更多的机会得到繁衍,这样一来,随着繁衍的进行,生物种群会朝着一个趋势收敛。而生物繁衍过程中的基因杂交和变异会给种群提供更好的基因序列,这样种群的繁衍趋势将会是“长江后浪推前浪,一代更比一代强”,而不会是只受限于祖先的最好基因。而程序可以通过模拟这种过程来获得问题的最优解(但不一定能得到)。要利用该过程来解决问题,受限需要构造初始的基因组,并为对每个基因进行适应性分数(衡量该基因的好坏程度)初始化,接着从初始的基因组中选出两个父基因(根据适应性分数,采用轮盘算法进行选择)进行繁衍,基于一定的杂交率(父基因进行杂交的概率)和变异率(子基因变异的概率),这两个父基因会生成两个子基因,然后将这两个基因放入种群中,到这里繁衍一代完成,重复繁衍的过程直到种群收敛或适应性分数达到最大。
2.利用遗传算法解决迷宫寻路问题。
代码如下:
import java.awt.Color;import java.awt.Graphics;import java.awt.GridLayout;import java.util.ArrayList;import java.util.List;import java.util.Random;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;@SuppressWarnings("serial")public class MazeProblem extends JFrame{ //当前基因组 private static List<Gene> geneGroup = new ArrayList<>(); private static Random random = new Random(); private static int startX = 2; private static int startY = 0; private static int endX = 7; private static int endY = 14; //杂交率 private static final double CROSSOVER_RATE = 0.7; //变异率 private static final double MUTATION_RATE = 0.0001; //基因组初始个数 private static final int POP_SIZE = 140; //基因长度 private static final int CHROMO_LENGTH = 70; //最大适应性分数的基因 private static Gene maxGene = new Gene(CHROMO_LENGTH); //迷宫地图 private static int[][] map = {{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, {1,0,1,0,0,0,0,0,1,1,1,0,0,0,1}, {5,0,0,0,0,0,0,0,1,1,1,0,0,0,1}, {1,0,0,0,1,1,1,0,0,1,0,0,0,0,1}, {1,0,0,0,1,1,1,0,0,0,0,0,1,0,1}, {1,1,0,0,1,1,1,0,0,0,0,0,1,0,1}, {1,0,0,0,0,1,0,0,0,0,1,1,1,0,1}, {1,0,1,1,0,0,0,1,0,0,0,0,0,0,8}, {1,0,1,1,0,0,0,1,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}}; private static int MAP_WIDTH = 15; private static int MAP_HEIGHT = 10; private List<JLabel> labels = new ArrayList<>(); public MazeProblem(){ // 初始化 setSize(700, 700); setDefaultCloseOperation(DISPOSE_ON_CLOSE); setResizable(false); getContentPane().setLayout(null); JPanel panel = new JPanel(); panel.setLayout(new GridLayout(MAP_HEIGHT,MAP_WIDTH)); panel.setBounds(10, 10, MAP_WIDTH*40, MAP_HEIGHT*40); getContentPane().add(panel); for(int i=0;i<MAP_HEIGHT;i++){ for(int j=0;j<MAP_WIDTH;j++){ JLabel label = new JLabel(); Color color = null; if(map[i][j] == 1){ color = Color.black; } if(map[i][j] == 0){ color = Color.GRAY; } if(map[i][j] == 5 || map[i][j] ==8){ color = Color.red; } label.setBackground(color); label.setOpaque(true); panel.add(label); labels.add(label); } } } @Override public void paint(Graphics g) { super.paint(g); //画出路径 int[] gene = maxGene.getGene(); int curX = startX; int curY = startY; for(int i=0;i<gene.length;i+=2){ //上 if(gene[i] == 0 && gene[i+1] == 0){ if(curX >=1 && map[curX-1][curY] == 0){ curX --; } } //下 else if(gene[i] == 0 && gene[i+1] == 1){ if(curX <=MAP_HEIGHT-1 && map[curX+1][curY] == 0){ curX ++; } } //左 else if(gene[i] == 1 && gene[i+1] == 0){ if(curY >=1 && map[curX][curY-1] == 0){ curY --; } } //右 else{ if(curY <= MAP_WIDTH-1 && map[curX][curY+1] == 0){ curY ++; } } labels.get(curX*MAP_WIDTH+curY).setBackground(Color.BLUE); } } public static void main(String[] args) { //初始化基因组 init(); while(maxGene.getScore() < 1){ //选择进行交配的两个基因 int p1 = getParent(geneGroup); int p2 = getParent(geneGroup); //用轮盘转动法选择两个基因进行交配,杂交和变异 mate(p1,p2); } new MazeProblem().setVisible(true); } /** * 根据路径获得适应性分数 * @param path * @return */ private static double getScore(int[] gene){ double result = 0; int curX = startX; int curY = startY; for(int i=0;i<gene.length;i+=2){ //上 if(gene[i] == 0 && gene[i+1] == 0){ if(curX >=1 && map[curX-1][curY] == 0){ curX --; } } //下 else if(gene[i] == 0 && gene[i+1] == 1){ if(curX <=MAP_HEIGHT-1 && map[curX+1][curY] == 0){ curX ++; } } //左 else if(gene[i] == 1 && gene[i+1] == 0){ if(curY >=1 && map[curX][curY-1] == 0){ curY --; } } //右 else{ if(curY <= MAP_WIDTH-1 && map[curX][curY+1] == 0){ curY ++; } } } double x = Math.abs(curX - endX); double y = Math.abs(curY - endY); //如果和终点只有一格距离则返回1 if((x == 1&& y==0) || (x==0&&y==1)){ return 1; } //计算适应性分数 result = 1/(x+y+1); return result; } /** * 基因初始化 */ private static void init(){ for(int i=0;i<POP_SIZE;i++){ Gene gene = new Gene(CHROMO_LENGTH); double score = getScore(gene.getGene()); if(score > maxGene.getScore()){ maxGene = gene; } gene.setScore(score); geneGroup.add(gene); } } /** * 根据适应性分数随机获得进行交配的父类基因下标 * @param list * @return */ private static int getParent(List<Gene> list){ int result = 0; double r = random.nextDouble(); double score; double sum = 0; double totalScores = getTotalScores(geneGroup); for(int i=0;i<list.size();i++){ Gene gene = list.get(i); score = gene.getScore(); sum += score/totalScores; if(sum >= r){ result = i; return result; } } return result; } /** * 获得全部基因组的适应性分数总和 * @param list * @return */ private static double getTotalScores(List<Gene> list){ double result = 0; for(int i=0;i<list.size();i++){ result += list.get(i).getScore(); } return result; } /** * 两个基因进行交配 * @param p1 * @param p2 */ private static void mate(int n1,int n2){ Gene p1 = geneGroup.get(n1); Gene p2 = geneGroup.get(n2); Gene c1 = new Gene(CHROMO_LENGTH); Gene c2 = new Gene(CHROMO_LENGTH); int[] gene1 = new int[CHROMO_LENGTH]; int[] gene2 = new int[CHROMO_LENGTH]; for(int i=0;i<CHROMO_LENGTH;i++){ gene1[i] = p1.getGene()[i]; gene2[i] = p2.getGene()[i]; } //先根据杂交率决定是否进行杂交 double r = random.nextDouble(); if(r >= CROSSOVER_RATE){ //决定杂交起点 int n = random.nextInt(CHROMO_LENGTH); for(int i=n;i<CHROMO_LENGTH;i++){ int tmp = gene1[i]; gene1[i] = gene2[i]; gene2[i] = tmp; } } //根据变异率决定是否 r = random.nextDouble(); if(r >= MUTATION_RATE){ //选择变异位置 int n = random.nextInt(CHROMO_LENGTH); if(gene1[n] == 0){ gene1[n] = 1; } else{ gene1[n] = 0; } if(gene2[n] == 0){ gene2[n] = 1; } else{ gene2[n] = 0; } } c1.setGene(gene1); c2.setGene(gene2); double score1 = getScore(c1.getGene()); double score2 = getScore(c2.getGene()); if(score1 >maxGene.getScore()){ maxGene = c1; } if(score2 >maxGene.getScore()){ maxGene = c2; } c1.setScore(score1); c2.setScore(score2); geneGroup.add(c1); geneGroup.add(c2); }}/** * 基因 * @author ZZF * */class Gene{ //染色体长度 private int len; //基因数组 private int[] gene; //适应性分数 private double score; public Gene(int len){ this.len = len; gene = new int[len]; Random random = new Random(); //随机生成一个基因序列 for(int i=0;i<len;i++){ gene[i] = random.nextInt(2); } //适应性分数设置为0 this.score = 0; } public int getLen() { return len; } public void setLen(int len) { this.len = len; } public int[] getGene() { return gene; } public void setGene(int[] gene) { this.gene = gene; } public double getScore() { return score; } public void setScore(double score) { this.score = score; } public void print(){ StringBuilder sb = new StringBuilder(); for(int i=0;i<gene.length;i+=2){ if(gene[i] == 0 && gene[i+1] == 0){ sb.append("上"); } //下 else if(gene[i] == 0 && gene[i+1] == 1){ sb.append("下"); } //左 else if(gene[i] == 1 && gene[i+1] == 0){ sb.append("左"); } //右 else{ sb.append("右"); } } System.out.println(sb.toString()); }}
3.下面是运行结果截图
阅读全文
0 0
- 遗传算法解决迷宫寻路问题(Java实现)
- 遗传算法(Genetic Algorithm)解决迷宫寻路问题
- Java实现A*算法解决迷宫问题
- 遗传算法解迷宫问题
- 最大流问题 (使用遗传算法解决 --Python 实现)
- 遗传算法解决TSP问题(c++实现)
- 遗传算法解决TSP问题(c++实现)
- 用遗传算法走迷宫 [Java语言实现]
- 遗传算法Java实现以及TSP问题遗传算法求解
- 遗传算法Java实现以及TSP问题遗传算法求解
- 遗传算法解决旅行商问题JAVA
- 营救公主(Java实现A*算法解决迷宫问题)
- 遗传算法的应用(求解迷宫问题)
- 用遗传算法走出迷宫(Java版)
- 用遗传算法走出迷宫(Java版)
- dfs寻路算法---迷宫问题实现
- JAVA实现遗传算法
- 遗传算法java实现
- JS通用表单验证函数
- CentOS7 搭建vsftpd详细教程
- CRC校验
- APP(简易便签)
- 基于后缀树的字符串匹配算法
- 遗传算法解决迷宫寻路问题(Java实现)
- SDUT-2565 区间之和
- k数II
- 玲珑学院OJ 1132 Down the Rabbit Hole【Dfs序+暴力】
- Linux LVM硬盘扩容
- ThreadPoolExecutor的参数介绍
- 解决Invalid left-hand side in assignment页面报错问题
- 理解面向对象
- JavaScript常用的基础语法和技巧