如何用Java实现遗传算法?

如何用Java实现遗传算法?,第1张

通过遗传算法走迷宫。虽然图1和图2均成功走出迷宫,但是图1比图2的路径长的多,且复杂,遗传算法可以计算出有多少种可能性,并选择其中最简洁的作为运算结果。

示例图1:

示例图2:

实现代码:

import java.util.ArrayList

import java.util.Collections

import java.util.Iterator

import java.util.LinkedList

import java.util.List

import java.util.Random

/**

* 用遗传算法走迷宫

*

* @author Orisun

*

*/

public class GA {

int gene_len // 基因长度

int chrom_len // 染色体长度

int population // 种群大小

double cross_ratio // 交叉率

double muta_ratio // 变异率

int iter_limit // 最多进化的代数

List<boolean[]>individuals // 存储当代种群的染色体

Labyrinth labyrinth

int width      //迷宫一行有多少个格子

int height     //迷宫有多少行

public class BI {

double fitness

boolean[] indv

public BI(double f, boolean[] ind) {

fitness = f

indv = ind

}

public double getFitness() {

return fitness

}

public boolean[] getIndv() {

return indv

}

}

List<BI>best_individual // 存储每一代中最优秀的个体

public GA(Labyrinth labyrinth) {

this.labyrinth=labyrinth

this.width = labyrinth.map[0].length

this.height = labyrinth.map.length

chrom_len = 4 * (width+height)

gene_len = 2

population = 20

cross_ratio = 0.83

muta_ratio = 0.002

iter_limit = 300

individuals = new ArrayList<boolean[]>(population)

best_individual = new ArrayList<BI>(iter_limit)

}

public int getWidth() {

return width

}

public void setWidth(int width) {

this.width = width

}

public double getCross_ratio() {

return cross_ratio

}

public List<BI>getBest_individual() {

return best_individual

}

public Labyrinth getLabyrinth() {

return labyrinth

}

public void setLabyrinth(Labyrinth labyrinth) {

this.labyrinth = labyrinth

}

public void setChrom_len(int chrom_len) {

this.chrom_len = chrom_len

}

public void setPopulation(int population) {

this.population = population

}

public void setCross_ratio(double cross_ratio) {

this.cross_ratio = cross_ratio

}

public void setMuta_ratio(double muta_ratio) {

this.muta_ratio = muta_ratio

}

public void setIter_limit(int iter_limit) {

this.iter_limit = iter_limit

}

// 初始化种群

public void initPopulation() {

Random r = new Random(System.currentTimeMillis())

for (int i = 0i <populationi++) {

int len = gene_len * chrom_len

boolean[] ind = new boolean[len]

for (int j = 0j <lenj++)

ind[j] = r.nextBoolean()

individuals.add(ind)

}

}

// 交叉

public void cross(boolean[] arr1, boolean[] arr2) {

Random r = new Random(System.currentTimeMillis())

int length = arr1.length

int slice = 0

do {

slice = r.nextInt(length)

} while (slice == 0)

if (slice <length / 2) {

for (int i = 0i <slicei++) {

boolean tmp = arr1[i]

arr1[i] = arr2[i]

arr2[i] = tmp

}

} else {

for (int i = slicei <lengthi++) {

boolean tmp = arr1[i]

arr1[i] = arr2[i]

arr2[i] = tmp

}

}

}

// 变异

public void mutation(boolean[] individual) {

int length = individual.length

Random r = new Random(System.currentTimeMillis())

individual[r.nextInt(length)] ^= false

}

// 轮盘法选择下一代,并返回当代最高的适应度值

public double selection() {

boolean[][] next_generation = new boolean[population][] // 下一代

int length = gene_len * chrom_len

for (int i = 0i <populationi++)

next_generation[i] = new boolean[length]

double[] cumulation = new double[population]

int best_index = 0

double max_fitness = getFitness(individuals.get(best_index))

cumulation[0] = max_fitness

for (int i = 1i <populationi++) {

double fit = getFitness(individuals.get(i))

cumulation[i] = cumulation[i - 1] + fit

// 寻找当代的最优个体

if (fit >max_fitness) {

best_index = i

max_fitness = fit

}

}

Random rand = new Random(System.currentTimeMillis())

for (int i = 0i <populationi++)

next_generation[i] = individuals.get(findByHalf(cumulation,

rand.nextDouble() * cumulation[population - 1]))

// 把当代的最优个体及其适应度放到best_individual中

BI bi = new BI(max_fitness, individuals.get(best_index))

// printPath(individuals.get(best_index))

//System.out.println(max_fitness)

best_individual.add(bi)

// 新一代作为当前代

for (int i = 0i <populationi++)

individuals.set(i, next_generation[i])

return max_fitness

}

// 折半查找

public int findByHalf(double[] arr, double find) {

if (find < 0 || find == 0 || find >arr[arr.length - 1])

return -1

int min = 0

int max = arr.length - 1

int medium = min

do {

if (medium == (min + max) / 2)

break

medium = (min + max) / 2

if (arr[medium] <find)

min = medium

else if (arr[medium] >find)

max = medium

else

return medium

} while (min <max)

return max

}

// 计算适应度

public double getFitness(boolean[] individual) {

int length = individual.length

// 记录当前的位置,入口点是(1,0)

int x = 1

int y = 0

// 根据染色体中基因的指导向前走

for (int i = 0i <lengthi++) {

boolean b1 = individual[i]

boolean b2 = individual[++i]

// 00向左走

if (b1 == false &&b2 == false) {

if (x > 0 &&labyrinth.map[y][x - 1] == true) {

x--

}

}

// 01向右走

else if (b1 == false &&b2 == true) {

if (x + 1 <width &&labyrinth.map[y][x + 1] == true) {

x++

}

}

// 10向上走

else if (b1 == true &&b2 == false) {

if (y > 0 &&labyrinth.map[y - 1][x] == true) {

y--

}

}

// 11向下走

else if (b1 == true &&b2 == true) {

if (y + 1 <height &&labyrinth.map[y + 1][x] == true) {

y++

}

}

}

int n = Math.abs(x - labyrinth.x_end) + Math.abs(y -labyrinth.y_end) + 1

//      if(n==1)

//          printPath(individual)

return 1.0 / n

}

// 运行遗传算法

public boolean run() {

// 初始化种群

initPopulation()

Random rand = new Random(System.currentTimeMillis())

boolean success = false

while (iter_limit-- > 0) {

// 打乱种群的顺序

Collections.shuffle(individuals)

for (int i = 0i <population - 1i += 2) {

// 交叉

if (rand.nextDouble() <cross_ratio) {

cross(individuals.get(i), individuals.get(i + 1))

}

// 变异

if (rand.nextDouble() <muta_ratio) {

mutation(individuals.get(i))

}

}

// 种群更替

if (selection() == 1) {

success = true

break

}

}

return success

}

//  public static void main(String[] args) {

//      GA ga = new GA(8, 8)

//      if (!ga.run()) {

//          System.out.println("没有找到走出迷宫的路径.")

//      } else {

//          int gen = ga.best_individual.size()

//          boolean[] individual = ga.best_individual.get(gen - 1).indv

//          System.out.println(ga.getPath(individual))

//      }

//  }

// 根据染色体打印走法

public String getPath(boolean[] individual) {

int length = individual.length

int x = 1

int y = 0

LinkedList<String>stack=new LinkedList<String>()

for (int i = 0i <lengthi++) {

boolean b1 = individual[i]

boolean b2 = individual[++i]

if (b1 == false &&b2 == false) {

if (x > 0 &&labyrinth.map[y][x - 1] == true) {

x--

if(!stack.isEmpty() &&stack.peek()=="右")

stack.poll()

else

stack.push("左")

}

} else if (b1 == false &&b2 == true) {

if (x + 1 <width &&labyrinth.map[y][x + 1] == true) {

x++

if(!stack.isEmpty() &&stack.peek()=="左")

stack.poll()

else

stack.push("右")

}

} else if (b1 == true &&b2 == false) {

if (y > 0 &&labyrinth.map[y - 1][x] == true) {

y--

if(!stack.isEmpty() &&stack.peek()=="下")

stack.poll()

else

stack.push("上")

}

} else if (b1 == true &&b2 == true) {

if (y + 1 <height &&labyrinth.map[y + 1][x] == true) {

y++

if(!stack.isEmpty() &&stack.peek()=="上")

stack.poll()

else

stack.push("下")

}

}

}

StringBuilder sb=new StringBuilder(length/4)

Iterator<String>iter=stack.descendingIterator()

while(iter.hasNext())

sb.append(iter.next())

return sb.toString()

}

}

题目好像是让你做个增强版的List ,简单的都实现了 程序架子大概是这样,排序查找什么的百度搜下 算法很多,套着每样写个方法就行了,测试就在main‘方法里写

public class MyList {

    private String[] arr

    private int count 

    public MyList (int count){

        arr = new String[count]

        this.count = count

    }

    public MyList (int[] intArr){

        arr = new String[intArr.length]

        this.count = intArr.length

        for(int i=0i<intArr.lengthi++){

            arr[i] = intArr[i]+""

        }

    }

    

    public MyList (String[] stringArr){

        arr = stringArr

        this.count = stringArr.length

    }

    public int getLength(){

        return count

    }

//清空容器内的数组。

    public void clearAll(){

        arr = new String[count]

    }

//通过给定元素下标来删除某一元素

    public void removeBySeqn(int seqn){

        if(seqn >= 0 && seqn<count){

                    arr[seqn] = null

        }

    }

public static void main(String[] args){

    MyList  list = new MyList (40)

    MyList  list1 = new MyList ({3,2,125,56,123})

    MyList  list2 = new MyList ({"123",""ad})

    list2.removeBySeqn(0)

    list1.clearAll()

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7819872.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-10
下一篇 2023-04-10

发表评论

登录后才能评论

评论列表(0条)

保存