當前位置:商標查詢大全網 - 彩票開獎 - 如何用Java實現遺傳算法?

如何用Java實現遺傳算法?

通過遺傳算法走迷宮。雖然圖1和圖2都成功走出了迷宮,但是圖1的路徑比圖2的路徑要長得多,也復雜得多。遺傳算法可以計算出有多少種可能性,選擇最簡單的壹種作為運算結果。

示例圖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();

}

}