示例圖1:
示例圖2:
實施代碼:
進口?Java . util . ArrayList;
進口?Java . util . collections;
進口?Java . util . iterator;
進口?Java . util . linked list;
進口?Java . util . list;
進口?Java . util . random;
/**
*使用遺傳算法走迷宮
*
* @作者Orisun
*
*/
公共?班級?嘎
int?基因_長度;?//基因長度
int?chrom _ len?//染色體長度
int?人口;?//人口規模
雙倍?交叉比;?//交叉率
雙倍?muta _ ratio?//變化率
int?iter _ limit?//進化最多的代數
列表& ltboolean[]& gt;個人;?//存儲當代種群的染色體。
迷宮迷宮;
int?寬度;?//壹條迷宮線有多少個方塊?
int?身高;?//迷宮裏有多少條線?
公共?班級?BI {
雙倍?健身;
boolean[]indv;
公共?BI(雙?f,?boolean[] ind) {
適應度= f;
indv = ind
}
公共?雙倍?getFitness() {
回歸?健身;
}
公共?boolean[] getIndv() {
回歸?indv
}
}
列表& ltBI & gt最佳_個人;?//存儲每壹代中最優秀的個體。
公共?GA(迷宮)
this .迷宮=迷宮;?
this.width =迷宮地圖[0]。長度;
this.height =迷宮.地圖.長度;
chrom_len =?4?*(寬度+高度);
gene_len =?2;
人口=?20;
cross_ratio =?0.83;
muta_ratio =?0.002;
iter_limit =?300;
個人=?新的?ArrayList & ltboolean[]& gt;(人口);
最佳_個人=?新的?ArrayList & ltBI & gt(ITER _ limit);
}
公共?int?getWidth() {
回歸?寬度;
}
公共?作廢?setWidth(int?寬度){
this.width =寬度;
}
公共?雙倍?getCross_ratio() {
回歸?交叉比;
}
公共?列表& ltBI & gtgetBest_individual() {
回歸?最佳_個人;
}
公共?迷宮getLabyrinth() {
回歸?迷宮;
}
公共?作廢?設置迷宮(迷宮){
this .迷宮=迷宮;
}
公共?作廢?setChrom_len(int?chrom_len) {
this.chrom _ len = chrom _ len
}
公共?作廢?setPopulation(int?人口){
this.population =人口;
}
公共?作廢?setCross_ratio(double?交叉比率){
this.cross_ratio =交叉比率;
}
公共?作廢?setMuta_ratio(double?muta_ratio) {
this.muta _ ratio = muta _ ratio
}
公共?作廢?setIter_limit(int?iter_limit) {
this.iter _ limit = iter _ limit
}
//初始化群體
公共?作廢?initPopulation() {
隨機r =?新的?random(system . current time millis());
為了什麽?(int?我=?0;我& lt人口;i++) {
int?len = gene _ len * chrom _ len
boolean[] ind =?新的?boolean[len];
為了什麽?(int?j =?0;j & ltlenj++)
ind[j]= r . nextboolean();
personals . add(ind);
}
}
//交叉
公共?作廢?cross(boolean[] arr1,?boolean[] arr2) {
隨機r =?新的?random(system . current time millis());
int?長度= arr 1 . length;
int?切片=?0;
做什麽?{
slice = r.nextInt(長度);
}?什麽時候?(slice ==?0);
如果?(切片& lt長度/?2) {
為了什麽?(int?我=?0;我& lt切片;i++) {
布爾?tmp = arr 1[I];
arr 1[I]= arr 2[I];
arr 2[I]= tmp;
}
}?不然呢?{
為了什麽?(int?i =切片;我& lt長度;i++) {
布爾?tmp = arr 1[I];
arr 1[I]= arr 2[I];
arr 2[I]= tmp;
}
}
}
//變化
公共?作廢?突變(布爾[]個體){
int?長度= individual.length
隨機r =?新的?random(system . current time millis());
個人[r.nextInt(length)] ^=?假的;
}
//輪盤賭方法選擇下壹代,返回當前代的最高適應度值。
公共?雙倍?選擇(){
boolean[][] next_generation =?新的?boolean[population][];?//下壹代
int?length = gene _ len * chrom _ len
為了什麽?(int?我=?0;我& lt人口;i++)
next_generation[i] =?新的?boolean[長度];
double[]累計=?新的?雙倍[人口];
int?best_index =?0;
雙倍?max _ fitness = get fitness(individuals . get(best _ index));
累計[0]= max _ fitness;
為了什麽?(int?我=?1;我& lt人口;i++) {
雙倍?fit = get fitness(personals . get(I));
累積[i] =累積?1]+fit;
//尋找當代最優秀的個人
如果?(fit & gtmax_fitness) {
best _ index = I;
max _ fitness = fit
}
}
隨機rand =?新的?random(system . current time millis());
為了什麽?(int?我=?0;我& lt人口;i++)
next _ generation[I]= individuals . get(findByHalf(累計,
rand.nextDouble() *累計[人口-?1]));
//將當代最優個體及其適應度放入best_individual。
畢比=?新的?BI(max_fitness,individuals . get(best _ index));
//print path(individuals . get(best _ index));
//system . out . println(max _ fitness);
best _ individual . add(bi);
//新壹代作為當前代
為了什麽?(int?我=?0;我& lt人口;i++)
individuals.set(i,next _ generation[I]);
回歸?max _ fitness
}
//半搜索
公共?int?findByHalf(double[] arr,?雙倍?查找){
如果?(查找& lt?0?|| find ==?0?||查找& gtarr[arr.length -?1])
回歸?-1;
int?min =?0;
int?max =數組長度-?1;
int?中=最小;
做什麽?{
如果?(medium == (min + max) /?2)
打破;
中=(最小+最大)/?2;
如果?(arr[medium]& lt;查找)
最小=中等;
不然呢?如果?(arr[medium]>查找)
max =中;
其他
回歸?中等;
}?什麽時候?(min & ltmax);
回歸?max
}
//計算適應度
公共?雙倍?getFitness(boolean[]個體){
int?長度= individual.length
//記錄當前位置,入口點為(1,0)。
int?x =?1;
int?y =?0;
//按照染色體中基因的指引向前移動。
為了什麽?(int?我=?0;我& lt長度;i++) {
布爾?b1 =個人[I];
布爾?b2 =個人[++ I];
// 00向左走。
如果?(b1 ==?假的?& amp& ampb2 ==?false) {
如果?(x & gt?0?& amp& amp迷宮.地圖[y][x -?1] ==?真){
x-;
}
}
// 01向右走
不然呢?如果?(b1 ==?假的?& amp& ampb2 ==?真){
如果?(x +?1?& lt寬度和尺寸。& amplabyrinth.map[y][x +?1] ==?真){
x++;
}
}
// 10往上走
不然呢?如果?(b1 ==?真的嗎?& amp& ampb2 ==?false) {
如果?(y & gt?0?& amp& amp迷宮.地圖[y -?1][x] ==?真){
y-;
}
}
// 11往下走
不然呢?如果?(b1 ==?真的嗎?& amp& ampb2 ==?真){
如果?(y +?1?& lt身高和體重。& amp迷宮.地圖[y +?1][x] ==?真){
y++;
}
}
}
int?n = math . ABS(x-labyrinth . x _ end)+math . ABS(y-labyrinth . y _ end)+?1;
//?如果(n==1)
//?printPath(個人);
回歸?1.0?/n;
}
//運行遺傳算法
公共?布爾?run() {
//初始化群體
init population();
隨機rand =?新的?random(system . current time millis());
布爾?成功=?假的;
什麽時候?(ITER _ limit-& gt;?0) {
//擾亂人口秩序
Collections.shuffle(個人);
為了什麽?(int?我=?0;我& lt人口?1;我+=?2) {
//交叉
如果?(rand . next double()& lt;交叉比率){
cross(individuals.get(i),individuals.get(i +?1));
}
//變化
如果?(rand . next double()& lt;muta_ratio) {
突變(individuals . get(I));
}
}
//人口替換
如果?(selection() ==?1) {
成功=?真實;
打破;
}
}
回歸?成功;
}
//?公共靜態void main(String[] args) {
//?GA ga =新GA(8,8);
//?如果(!ga.run()) {
//?System.out.println("沒有找到走出迷宮的路。");
//?}否則{
//?int gen = ga . best _ individual . size();
//?布爾[]個體= ga . best _ individual . get(gen-1)。indv
//?System.out.println(ga.getPath(個體));
//?}
//?}
//根據染色體打印方法
公共?string getPath(boolean[]individual){
int?長度= individual.length
int?x =?1;
int?y =?0;
LinkedList & lt字符串& gtstack=new?LinkedList & lt字符串& gt();
為了什麽?(int?我=?0;我& lt長度;i++) {
布爾?b1 =個人[I];
布爾?b2 =個人[++ I];
如果?(b1 ==?假的?& amp& ampb2 ==?false) {
如果?(x & gt?0?& amp& amp迷宮.地圖[y][x -?1] ==?真){
x-;
如果(!stack . isempty()& amp;& ampStack.peek()== "right ")
stack . poll();
其他
stack . push(" left ");
}
}?不然呢?如果?(b1 ==?假的?& amp& ampb2 ==?真){
如果?(x +?1?& lt寬度和尺寸。& amplabyrinth.map[y][x +?1] ==?真){
x++;
如果(!stack . isempty()& amp;& ampStack.peek()== "left ")
stack . poll();
其他
stack . push(" right ");
}
}?不然呢?如果?(b1 ==?真的嗎?& amp& ampb2 ==?false) {
如果?(y & gt?0?& amp& amp迷宮.地圖[y -?1][x] ==?真){
y-;
如果(!stack . isempty()& amp;& ampStack.peek()== "Down ")
stack . poll();
其他
stack . push(" up ");
}
}?不然呢?如果?(b1 ==?真的嗎?& amp& ampb2 ==?真){
如果?(y +?1?& lt身高和體重。& amp迷宮.地圖[y +?1][x] ==?真){
y++;
如果(!stack . isempty()& amp;& ampStack.peek()== "Up ")
stack . poll();
其他
stack . push(" down ");
}
}
}
StringBuilder sb=new?StringBuilder(長度/4);
叠代器& lt字符串& gtITER = stack . descending iterator();
while(iter.hasNext())
sb . append(ITER . next());
回歸?sb . tostring();
}
}