目錄 遺傳算法 (genetic algorithm)是模擬達爾文的遺傳選擇和自然淘汰的生物進化過程的計算模型,是一種通過模擬自然進化過程搜索最優解的方法,它是有美國michigan大學j.holland教授於1975年首先提出來的,並出版了頗有影響的專著《adaptation in natural and artificial systems》,ga這個名稱纔逐漸為人所知,j.hilland教授所提出的ga通常為簡單遺傳算法 (sga)。
遺傳算法 是從代表問題可能潛在的解集的一個種群(population)開始的,而一個種群則由經過基因(gene)編碼的一定數目的個體(individual)組成。每個個體實際上是染色體(chromosome)帶有特徵的實體。染色體作為遺傳物質的主要載體,即多個基因的集合,其內部表現(即基因型)是某種基因組合,它决定了個體的形狀的外部表現,如黑頭髮的特徵是由染色體中控製這一特徵的某種基因組合决定的。因此,在一開始需要實現從表現型到基因型的映射即編碼工作。由於仿照基因編碼的工作很復雜,我們往往進行簡化,如二進製編碼,初代種群産生之後,按照適者生存和優勝劣汰的原理,逐代(generation)演化産生出越來越好的近似解,在每一代,根據問題域中個體的適應度(fitness)大小挑選(_select_ion)個體,並藉助於自然遺傳學的遺傳算子(genetic operators)進行組合交叉(crossover)和變異(mutation),産生出代表新的解集的種群。這個過程將導致種群像自然進化一樣的後生代種群比前代更加適應於環境,末代種群中的最優個體經過解碼(decoding),可以作為問題近似最優解。 遺傳算法 是一類可用於復雜係統優化的具有魯棒性的搜索算法,與傳統的優化算法相比,主要有以下特點:
1、 遺傳算法 以决策變量的編碼作為運算對象。傳統的優化算法往往直接决策變量的實際植本身,而遺傳算法 處理决策變量的某種編碼形式,使得我們可以藉鑒生物學中的染色體和基因的概念,可以模仿自然界生物的遺傳和進化機理,也使得我們能夠方便的應用遺傳操作算子。
2、 遺傳算法 直接以適應度作為搜索信息,無需導數等其它輔助信息。
3、 遺傳算法 使用多個點的搜索信息,具有隱含並行性。
4、 遺傳算法 使用概率搜索技術,而非確定性規則。 由於遺傳算法 的整體搜索策略和優化搜索方法在計算是不依賴於梯度信息或其它輔助知識,而衹需要影響搜索方向的目標函數和相應的適應度函數,所以遺傳算法 提供了一種求解復雜係統問題的通用框架,它不依賴於問題的具體領域,對問題的種類有很強的魯棒性,所以廣泛應用於許多科學,下面我們將介紹遺傳算法 的一些主要應用領域:
1、 函數優化。
函數優化是遺傳算法 的經典應用領域,也是遺傳算法 進行性能評價的常用算例,許多人構造出了各種各樣復雜形式的測試函數:連續函數和離散函數、凸函數和凹函數、低維函數和高維函數、單峰函數和多峰函數等。對於一些非綫性、多模型、多目標的函數優化問題,用其它優化方法較難求解,而遺傳算法 可以方便的得到較好的結果。
2、 組合優化
隨着問題規模的增大,組合優化問題的搜索空間也急劇增大,有時在目前的計算上用枚舉法很難求出最優解。對這類復雜的問題,人們已經意識到應把主要精力放在尋求滿意解上,而遺傳算法 是尋求這種滿意解的最佳工具之一。實踐證明,遺傳算法 對於組合優化中的np問題非常有效。例如遺傳算法 已經在求解旅行商問題、 背包問題、裝箱問題、圖形劃分問題等方面得到成功的應用。
此外,ga也在生産調度問題、自動控製、機器人學、圖象處理、人工生命、遺傳編碼和機器學習等方面獲得了廣泛的運用。 進入90年代,遺傳算法 迎來了興盛發展時期,無論是理論研究還是應用研究都成了十分熱門的課題。尤其是遺傳算法 的應用研究顯得格外活躍,不但它的應用領域擴大,而且利用遺傳算法 進行優化和規則學習的能力也顯著提高,同時産業應用方面的研究也在摸索之中。此外一些新的理論和方法在應用研究中亦得到了迅速的發展,這些無疑均給遺傳算法 增添了新的活力。遺傳算法 的應用研究已從初期的組合優化求解擴展到了許多更新、更工程化的應用方面。
隨着應用領域的擴展,遺傳算法 的研究出現了幾個引人註目的新動嚮:一是基於遺傳算法 的機器學習,這一新的研究課題把遺傳算法 從歷來離散的搜索空間的優化搜索算法擴展到具有獨特的規則生成功能的嶄新的機器學習算法。這一新的學習機製對於解决人工智能中知識獲取和知識優化精煉的瓶頸難題帶來了希望。二是遺傳算法 正日益和神經網絡、模糊推理以及混沌理論等其它智能計算方法相互滲透和結合,這對開拓21世紀中新的智能計算技術將具有重要的意義。三是並行處理的遺傳算法 的研究十分活躍。這一研究不僅對遺傳算法 本身的發展,而且對於新一代智能計算機體係結構的研究都是十分重要的。四是遺傳算法 和另一個稱為人工生命的嶄新研究領域正不斷滲透。所謂人工生命即是用計算機模擬自然界豐富多彩的生命現象,其中生物的自適應、進化和免疫等現象是人工生命的重要研究對象,而遺傳算法 在這方面將會發揮一定的作用,五是遺傳算法 和進化規劃(evolution programming,ep)以及進化策略(evolution strategy,es)等進化計算理論日益結合。ep和es幾乎是和遺傳算法 同時獨立發展起來的,同遺傳算法 一樣,它們也是模擬自然界生物進化機製的衹能計算方法,即同遺傳算法 具有相同之處,也有各自的特點。目前,這三者之間的比較研究和彼此結合的探討正形成熱點。
1991年d.whitey在他的論文中提出了基於領域交叉的交叉算子(adjacency based crossover),這個算子是特別針對用序號表示基因的個體的交叉,並將其應用到了tsp問題中,通過實驗對其進行了驗證。
d.h.ackley等提出了隨即迭代遺傳爬山法(stochastic iterated genetic hill-climbing,sigh)采用了一種復雜的概率選舉機製,此機製中由m個“投票者”來共同决定新個體的值(m表示群體的大小)。實驗結果表明,sigh與單點交叉、均勻交叉的神經遺傳算法 相比,所測試的六個函數中有四個表現出更好的性能,而且總體來講,sigh比現存的許多算法在求解速度方面更有競爭力。
h.bersini和g.seront將遺傳算法 與單一方法(simplex method)結合起來,形成了一種叫單一操作的多親交叉算子(simplex crossover),該算子在根據兩個母體以及一個額外的個體産生新個體,事實上他的交叉結果與對三個個體用選舉交叉産生的結果一致。同時,文獻還將三者交叉算子與點交叉、均勻交叉做了比較,結果表明,三這交叉算子比其餘兩個有更好的性能。
國內也有不少的專傢和學者對遺傳算法 的交叉算子進行改進。2002年,戴曉明等應用多種群遺傳並行進化的思想,對不同種群基於不同的遺傳策略,如變異概率,不同的變異算子等來搜索變量空間,並利用種群間遷移算子來進行遺傳信息交流,以解决經典遺傳算法 的收斂到局部最優值問題
2004年,趙宏立等針對簡單遺傳算法 在較大規模組合優化問題上搜索效率不高的現象,提出了一種用基因塊編碼的並行遺傳算法 (building-block coded parallel ga,bcpga)。該方法以粗粒度並行遺傳算法 為基本框架,在染色體群體中識別出可能的基因塊,然後用基因塊作為新的基因單位對染色體重新編碼,産生長度較短的染色體,在用重新編碼的染色體群體作為下一輪以相同方式演化的初始群體。
2005年,江雷等針對並行遺傳算法 求解tsp問題,探討了使用彈性策略來維持群體的多樣性,使得算法跨過局部收斂的障礙,嚮全局最優解方向進化。 遺傳算法 是基於生物學的,理解或編程都不太難。下面是遺傳算法 的一般算法:
創建一個隨機的初始狀態
初始種群是從解中隨機選擇出來的,將這些解比喻為染色體或基因,該種群被稱為第一代,這和符號人工智能係統的情況不一樣,在那裏問題的初始狀態已經給定了。
評估適應度
對每一個解(染色體)指定一個適應度的值,根據問題求解的實際接近程度來指定(以便逼近求解問題的答案)。不要把這些“解”與問題的“答案”混為一談,可以把它理解成為要得到答案,係統可能需要利用的那些特性。
繁殖(包括子代突變)
帶有較高適應度值的那些染色體更可能産生後代(後代産生後也將發生突變)。後代是父母的産物,他們由來自父母的基因結合而成,這個過程被稱為“雜交”。
下一代
如果新的一代包含一個解,能産生一個充分接近或等於期望答案的輸出,那麽問題就已經解决了。如果情況並非如此,新的一代將重複他們父母所進行的繁衍過程,一代一代演化下去,直到達到期望的解為止。
並行計算
非常容易將遺傳算法 用到並行計算和群集環境中。一種方法是直接把每個節點當成一個並行的種群看待。然後有機體根據不同的繁殖方法從一個節點遷移到另一個節點。另一種方法是“農場主/勞工”體係結構,指定一個節點為“農場主”節點,負責選擇有機體和分派適應度的值,另外的節點作為“勞工”節點,負責重新組合、變異和適應度函數的評估。
術語說明
由於遺傳算法 是由進化論和遺傳學機理而産生的搜索算法,所以在這個算法中會用到很多生物遺傳學知識,下面是我們將會用來的一些術語說明:
一、染色體(chronmosome)
染色體又可以叫做基因型個體(individuals),一定數量的個體組成了群體(population),群體中個體的數量叫做群體大小。
二、基因(gene)
基因是串中的元素,基因用於表示個體的特徵。例如有一個串s=1011,則其中的1,0,1,1這4個元素分別稱為基因。它們的值稱為等位基因(alletes)。
三、基因地點(locus)
基因地點在算法中表示一個基因在串中的位置稱為基因位置(gene position),有時也簡稱基因位。基因位置由串的左嚮右計算,例如在串 s=1101 中,0的基因位置是3。
四、基因特徵值(gene feature)
在用串表示整數時,基因的特徵值與二進製數的權一致;例如在串 s=1011 中,基因位置3中的1,它的基因特徵值為2;基因位置1中的1,它的基因特徵值為8。
五、適應度(fitness)
各個個體對環境的適應程度叫做適應度(fitness)。為了體現染色體的適應能力,引入了對問題中的每一個染色體都能進行度量的函數,叫適應度函數. 這個函數是計算個體在群體中被使用的概率。 ---------來個例子,大傢好理解------------
基於遺傳算法 的人工生命模擬
#include<stdio.h>
#include<stdlib.h>
#include<graphics.h>
#include<math.h>
#include<time.h>
#include<string.h>
#include "graph.c"
/* 宏定義 */
#define tl1 20 /* 植物性食物限製時間 */
#define tl2 5 /* 動物性食物限製時間 */
#define newfoods 3 /* 植物性食物每代生成數目*/
#define mutation 0.05 /* 變異概率 */
#define g_length32 /* 個體染色體長度*/
#define max_pop100 /* 個體總數的最大值*/
#define max_food 100 /* 食物總數的最大值*/
#define max_wx 60 /* 虛擬環境的長度最大值 */
#define max_wy 32 /* 虛擬環境的寬度最大值 */
#define sx1 330 /* 虛擬環境圖左上角點x坐標*/
#define sy1 40 /* 虛擬環境圖左上角點y坐標*/
#define gx 360 /* 個體數進化圖形窗口的左上角點x坐標*/
#define gy 257 /* 個體數進化圖形窗口的左上角點y坐標*/
#define gxr 250 /* 個體數進化圖形窗口的長度 */
#define gyr 100 /* 個體數進化圖形窗口的寬度 */
#define gstep 2 /* 個體數進化圖形窗口的x方向步長 */
#define r_life0.05 /* 初期産生生物數的環境比率 */
#define r_food0.02 /* 初期産生食物數的環境比率 */
#define sl_min 10 /* 個體壽命最小值 */
/* 全局變量 */
unsignedchargene[max_pop][g_length]; /* 遺傳基因 */
unsignedchariflg[max_pop]; /* 個體死活狀態標志變量*/
unsignedcharfflg[max_food]; /* 食物有無狀態標志變量*/
unsignedcharworld[max_wx][max_wy]; /* 虛擬環境的數據 */
unsigned char /* 各中行為模式數據 */
life1={{0,0,1,0,0},{0,1,0,1,0},{1,0,0,0,1},{0,1,0,1,0},{0,0,1,0,0}};
unsigned char
life2={{1,1,1,1,1},{1,0,0,0,1},{1,0,0,0,1},{1,0,0,0,1},{1,1,1,1,1}};
unsigned char
food1={{0,0,0,1,0},{0,0,1,1,0},{0,1,0,1,0},{0,0,1,1,0},{0,0,0,1,0}};
unsigned char
food2={{0,0,0,1,0},{0,0,1,1,0},{0,1,1,1,0},{0,0,1,1,0},{0,0,0,1,0}};
int pop_size; /* 個體總數 */
int iatr[max_pop]; /* 個體屬性 */
/* iatr[][0]個體當前位置x坐標*/
/* iatr[]個體當前位置y坐標*/
/* iatr[]內部能量*/
/* iatr[]年齡屬性*/
int food_size; /* 食物總數*/
int fatr[max_food]; /* 食物屬性*/
/* fatr[][0]食物當前位置x坐標*/
/* fatr[]食物當前位置y坐標*/
/* fatr[]=0 : 植物性 =1:動物性 */
/* fatr[]新鮮程度 */
int wx,wy; /* 虛擬環境的長寬度*/
void uni_crossover(gene,g1,g2,g3,ratio1,g_length) /* 均勻交叉 */
unsigned char *gene; /* 遺傳基因 */
int g1,g2,g3; /* g1 g2 父個體編號g3 子個體編號*/
double ratio1; /*父個體g1被選中的概率*/
int g_length; /* 個體遺傳基因的位長*/
{
unsigned char *gene1; /*父1遺傳基因的指針 */
unsigned char *gene2; /*父2遺傳基因的指針 */
unsigned char *gene3; /*子遺傳基因的指針 */
double rnd,r1;
int i;
gene1=gene+g_length*g1;
gene2=gene+g_length*g2;
gene3=gene+g_length*g3;
r1=(int)(10000.0*ratio1);
for(i=0;i<g_length;i++)
{rnd=random(10000);
if(rnd<=r1) *(gene3+i)=*(gene1+i);
else *(gene3+i)=*(gene2+i);
}
}
void g_disp_unit(x,y,n)
/* 繪製虛擬環境的一個單元*/
int x,y; /* x=0,1,2....,wx-1; y=0,1,2,....,wy-1*/
int n; /* n=0: =1: 生物1=2:生物2 =3:植物性食物=4:障礙物=5:動物性食物 */
{
int gx,gy,i,j;
unsigned char col;
gx=sx1+5*x;gy=sy1+5*y;
for(i=0;i<5;i++)
for(j=0;j<5;j++)
{switch(n)
{ case 0: col=0; break;
case 1: col=life1[j][ i]*2; break;
case 2: col=life2[j][ i]*4; break;
case 3: col=food1[j][ i]*6; break;
case 4: col=7; break;
case 5: col=food2[j][ i]*11;
}
g_pset(gx+j,gy+i,col);
}
}
void g_draw_world() /* 顯示虛擬環境畫面*/
{
int i,j;
for(i=0;i<wy;i++)
for(j=0;j<wx;j++)
g_disp_unit(j,i,world[j] [ i]);
}
void g_draw_frame(x1,y1,x2,y2,c1,c2,c3,c4,text)
int x1,y1,x2,y2,c1,c2,c3,c4;
char *text;
{int n,x3;
g_rectangle(x1,y1,x2,y2,c1,1);
g_rectangle(x1,y1,x2,y2,c2,0);
g_rectangle(x1,y1,x2,y1+16,c3,1);
g_rectangle(x1,y1,x2,y1+16,c2,0);
n=strlen(text);
x3=x1+((x2-x1-n*8)/2);
disp_hz16(text,x3,y1,c4);
}
void g_init_frames() /*初始化畫面*/
{
int i,j,cx,cy,x,y;
char text;
g_draw_frame(0,0,639,399,15,0,4,15,
"基於遺傳算法 的人工生命模擬");
g_draw_frame(0,16,320,170,7,0,8,15,"設定參數");
y=48;
setcolor(9);
disp_hz16("植物食物限製時間",16,y,15);
sprintf(text,"%d",tl1);
g_text(200,y+8,4,text);
y=y+24;
setcolor(9);
disp_hz16("動物食物限製時間",16,y,15);
sprintf(text,"%d",tl2);
g_text(200,y+8,4,text);
y=y+24;
setcolor(9);
disp_hz16("植物食物每代生成個數",16,y,15);
sprintf(text,"%d",newfoods);
g_text(200,y+8,4,text);
y=y+24;
setcolor(9);
disp_hz16("變異概率",16,y,15);
i=(int)(mutation*100.0);
sprintf(text,"%d",i);
g_text(152,y+8,4,text);
g_draw_frame(0,170,320,399,7,0,8,15,"最佳基因型");
x=16;y=194;
setcolor(9);
disp_hz16("sp:物種號........",x,y,15);y=y+16;
disp_hz16("sl:壽命..........",x,y,15);y=y+16;
disp_hz16("vf:視野..........",x,y,15);y=y+16;
disp_hz16("tm:基本移動模式..",x,y,15);y=y+16;
disp_hz16("cm:移動特點......",x,y,15);y=y+16;
disp_hz16("lm:移動能耗......",x,y,15);y=y+16;
disp_hz16("ca:行動特點......",x,y,15);y=y+16;
disp_hz16("cr:善變性........",x,y,15);y=y+16;
disp_hz16("sa:攻擊速度......",x,y,15);y=y+16;
disp_hz16("da:防禦能力......",x,y,15);y=y+16;
disp_hz16("la:攻擊能耗......",x,y,15);y=y+16;
disp_hz16("ef:食物吸取效率..",x,y,15);y=y+16;
g_draw_frame(320,16,639,207,7,0,8,15,"虛擬世界");
g_draw_frame(320,207,639,399,7,0,8,15,"世代個體數目變化");
}
void g_init_graph()
/*個體數進化圖初始化*/
{
g_rectangle(gx,gy,gx+gxr,gy+gyr,0,1);
g_rectangle(gx,gy,gx+gxr,gy+gyr,6,0);
setcolor(1);
disp_hz16( "生物 1",gx+5,gy-18,15);
g_line(gx+90,gy-10,gx+110,gy-10,1);
setcolor(4);
disp_hz16( "生物 2",gx+120,gy-18,15);
g_line(gx+205,gy-10,gx+225,gy-10,4);
setcolor(0);
disp_hz16("世代數",gx+168,gy+gyr+10,15);
g_text(gx-25,gy,0,"100");
g_text(gx-14,gy+gyr,0,"0");
}
void g_plot_population(gen_num,n1,n2,n1old,n2old)
int gen_num,n1,n2,n1old,n2old;
{
int x,y,gx,gy,x_old,y_old;
char text;
if(gen_num%10==0)
{
x=gx+(gen_num-1)*gstep;
g_line(x,gy+1,x,gy+gyr-1,1);
sprintf(text,"%d",gen_num);
if(gen_num<100||gen_num%20==0)
g_text(x-8,gy+gyr+5,15,text);
}
x_old=gx+(gen_num-1)*gstep;
x=x_old+gstep;
y_old=gy+gyr-n1old;
y=gy+gyr-n1;
g_line(x_old,y_old,x,y,1);
y_old=gy+gyr-n2old;
y=gy+gyr-n2;
g_line(x_old,y_old,x,y,4);
}
void g_disp_genotype() /* 顯示最佳個體的遺傳基因型*/
{
int i,j,n0,n1,x,y;
unsigned char g[g_length];
unsigned char bits=
{ {0,0},{1,4},{5,6},{7,8},{9,11},{12,12},{13,15},
{16,18},{19,21},{22,24},{25,27},{28,31}};
/*畫面消除*/
g_rectangle(200,187,319,398,7,1);
if(pop_size!=0)
{
/* 獲取各遺傳因子 */
for(i=0;i<g_length;i++)
{
n0=0;n1=0;
for(j=0;j<pop_size;j++)
if(gene[j] [ i]==0) n0++;
elsen1++;
if(n0>=n1) g [ i]=0; else g [ i]=1;
}
x=220;
for(i=0;i<12;i++)
{
y=202+i*16;
for(j=bits [ i][0];j<=bits [ i];j++)
if(g[j]==0)
g_text(x+(j-bits [ i][0])*16,y,4,"0");
else
g_text(x+(j-bits [ i][0])*16,y,4,"1");
}
}
}
void g_disp_char(x,y,x1,y1,x2,y2,v)
int x,y,x1,y1,x2,y2;
unsigned char v;
{
char c;
if(x>=x1&& x<=x2-8 && y>=y1 && y<=y2-10)
{
switch(v)
{
case 0: strcpy(c,"0 ");break;
case 1: strcpy(c,"+ ");break;
case 2: strcpy(c,"- ");break;
case 3: strcpy(c,"x ");
}
g_text(x,y,15,c);
}
}
void remove_life(n) /* 消除第n個個體*/
int n;
{
iflg[n]=0;
world[iatr[n][0]][iatr[n]]=0;
g_disp_unit(iatr[n][0],iatr[n],0);
if(food_size+1<=max_food)
{
food_size++;
fatr[food_size-1][0]=iatr[n][0];
fatr[food_size-1]=iatr[n];
fatr[food_size-1]=1;
fatr[food_size-1]=0;
fflg[food_size-1]=1;
world[iatr[n][0]][iatr[n]]=5;
g_disp_unit(iatr[n][0],iatr[n],5);
}
}
voidremove_food(n) /* 消除第n個食物 */
int n;
{
fflg[n]=0;
world[fatr[n][0]][fatr[n]]=0;
g_disp_unit(fatr[n][0],fatr[n],0);
}
void make_lives_and_foods() /* 設置虛擬環境中生物與食物*/
{
int x,y,i,j;
pop_size=0;
food_size=0;
for(y=0;y<wy;y++)
for(x=0;x<wx;x++)
{
if(world[x][y]==1||world[x][y]==2)
{
if(pop_size+1<=max_pop)
{
pop_size++;
/* 生成遺傳因子 */
gene[pop_size-1][0]=world[x][y]-1;
for(i=1;i<g_length;i++)
gene[pop_size-1] [ i]=random(2);
/*設定屬性*/
iatr[pop_size-1][0]=x;
iatr[pop_size-1]=y;
iatr[pop_size-1]=70+random(30);
iatr[pop_size-1]=random(sl_min);
}
}
if(world[x][y]==3||world[x][y]==5)
{
if(food_size+1<=max_food)
{
food_size++;
/* 設定屬性*/
fatr[food_size-1][0]=x;
fatr[food_size-1]=y;
if(world[x][y]==3)
fatr[food_size-1]=0;
else
fatr[food_size-1]=1;
fatr[food_size-1]=random(tl1-1)+1;
}
}
}
}
void find_empty(x,y) /* 尋找虛擬環境中的空處,返回坐標*/
int *x,*y;
{
int ok;
ok=0;
while(ok==0)
{
*x=random(wx);*y=random(wy);
if(world[*x][*y]==0) ok=1;
}
}
void make_world() /* 隨機設定人工環境*/
{
int i,j,k,num,x,y;
int ok,overlap;
char choice;
double size;
wx=0;
while(wx<10||wx>max_wx)
{
setcolor(15);
disp_hz16("虛擬環境長度(10-60)",10,210,20);
gscanf(300,210,4,0,3,"%s",choice);
wx=atoi(choice);
}
wy=0;
while(wy<10||wy>max_wy)
{
setcolor(15);
disp_hz16("虛擬環境寬度(10-32)",10,240,20);
gscanf(300,240,4,0,3,"%s",choice);
wy=atoi(choice);
}
for(i=0;i<wy;i++)
for(j=0;j<wx;j++)
if(i==0||i==wy-1||j==0||j==wx-1)
world[j] [ i]=4;
else world[j] [ i]=0;
/* 設定障礙物*/
size=(double)(wx*wy);
num=(int)(size/40.0);
if(num>max_pop)num=max_pop;
for(i=0;i<num;i++)
{
find_empty(&x,&y);
world[x][y]=4;
}
num=(int)(size/5.0);
if(num>max_food) num=max_food;
for(i=0;i<num;i++)
{
ok=0;
while(ok==0)
{
x=random(wx);y=random(wy);
if((world[x][y]!=4) &&
(world[x][y-1]==4 || world[x][y+1]==4 ||
world[x-1][y]==4 || world[x+1][y]==4))
{world[x][y]=4;
ok=1;
}
}
}
for(y=0;y<wy;y++)
for(x=0;x<wx;x++)
if(world[x][y]==0)
{
num=0;
for(i=-1;i<=1;i++)
for(j=-1;j<=1;j++)
if(get_world(x+j,y+i)==4)
num++;
if(num>=6) world[x][y]=4;
}
/*設定生物*/
num=(int)(size*r_life);
for(i=0;i<num;i++)
{find_empty(&x,&y);
world[x][y]=random(2)+1;
}
/* 設定食物*/
num=(int)(size*r_food);
for(i=0;i<num;i++)
{
find_empty(&x,&y);
world[x][y]=3;
}
}
void load_world_file() /* 讀取虛擬環境數據文件設定*/
{
file *fopen(),*fpt;
char st[100],c;
int i,j;
if((fpt=fopen("gaworld","r"))==null) exit(-1);
else
{
fscanf(fpt,"%d",&wx);
fscanf(fpt,"%d",&wy);
for(i=0;i<wy;i++)
for(j=0;j<wx;j++)
fscanf(fpt,"%d",&world[j] [ i]);
fclose(fpt);
}
}
int get_world(x,y) /*坐標(x,y)處環境值*/
int x,y;
{
if(x>=0 && x<wx && y>=0 && y<wy)
return(world[x][y]);
else
return(-1);
}
intdecode_gene(n,sb,bw) /* 第n個個體基因型解碼*/
intn,sb,bw; /*sb開始位bw位長 */
{
int i,sum;
sum=0;
for(i=sb;i<sb+bw;i++)
sum=sum*2+gene[n] [ i];
return(sum);
}
voidmove_pos(n,x1,y1,x2,y2) /* 個體n從(x1,y1)移動到(x2,y2) */
int n,x1,y1,x2,y2;
{
int sp,loss;
loss=decode_gene(n,12,1)+1; /* 移動消耗 */
iatr[n]=iatr[n]-loss; /*內部能量更新 */
if(iatr[n]<=0)remove_life(n);
else
{
/* 個體屬性更新 */
iatr[n][0]=x2;iatr[n]=y2; /* x,y坐標更新 */
/* 顯示更新 */
sp=gene[n][0]+1;
g_disp_unit(x1,y1,0); /*當前位置(x,y)圖形消除 */
world[x1][y1]=0;
g_disp_unit(x2,y2,sp); /*新位置圖形表示 */
world[x2][y2]=sp;
}
}
voidmove_randomly(n) /*個體n按照移動模式隨機移動 */
int n;
{
/* 基本移動模式1*/
intpat1={{1,0},{1,1},{0,1},{-1,1},
{-1,0},{-1,-1},{0,-1},{1,-1}};
/* 基本移動模式2與3*/
int pat2_3={{{1,0},{0,1},{-1,0},{0,-1}},
{{1,1},{-1,1},{-1,-1},{1,-1}}};
int pat,x1,y1,x2,y2,rndnum;
pat=decode_gene(n,7,2);
/* pat(0,1,2,3): 表示基本移動模式*/
x1=iatr[n][0]; /* 當前x坐標 */
y1=iatr[n]; /* 當前y坐標 */
if(pat<=1) /* 基本移動模式1*/
{
rndnum=random(8);
x2=x1+pat1[rndnum][0]; /* 移動目的點x坐標 */
y2=y1+pat1[rndnum]; /* 移動目的點y坐標 */
}
else /* 基本移動模式2與3*/
{
rndnum=random(4);
x2=x1+pat2_3[pat-2][rndnum][0];
y2=y1+pat2_3[pat-2][rndnum];
}
if(x2>=0 && x2<wx && y2>=0 && y2<wy)
if(get_world(x2,y2)==0)
move_pos(n,x1,y1,x2,y2);
/* 非法目的點的場合不作移動 */
}
voidmove_individual(n) /* 個體n移動 */
int n;
{
int cx,cy,dx,dy,sp,vf,sumx,sumy;
int i,j,a,sgn,num;
doublevect={{1,0},{1,1},{0,1},{-1,1},
{-1,0},{-1,-1},{0,-1},{1,-1}};
double vx,vy,d1,d2;
double _cos,cos_max;
cx=iatr[n][0]; /* 當前x坐標 */
cy=iatr[n];& 選擇(復製):
根據各個個體的適應度,按照一定的規則或方法,從第t代群體P(t)中選擇出一些優良的個體遺傳到下 一代群體P(t+1)中;
交叉:
將群體P(t)內的各個個體隨機搭配成對,對每一對個體,以某個概率(稱為交叉概率)交換它們之間的部分染色體;
變異:
對群體P(t)中的每一個個體,以某一概率(稱為變異概率)改變某一個或某一些基因座上的基因值為其他基因值。 科學 光學 分光光度法 模擬退火算法 退火算法 遺傳病 遺傳學 血型遺傳 遺傳所 量子計算
量子遺傳算法 遺傳算法定義 遺傳算法特點 遺傳算法實例 遺傳算法的應用 遺傳算法的現狀 模擬退火遺傳算法 機械優化設計遺傳算法 遺傳算法的數學基礎 遺傳算法的一般算法 交互式遺傳算法 原理及其應用 協同進化遺傳算法 理論及應用