關鍵字:人工智能,遺傳算法,進化計算
Production system
Abstract: Genetic algorithm (geneticalgorithms, GA) is mimic biological genetics and natural selection mechanism, the random global search algorithm of adaptive (Holland, Mr Rand) and the nature of "natural selection" and "evolution" Darwin (Charles Darwin) and biological genetic theory (Gregor Johann Mendel in fruit, John Mendel) theory synthetically, through artificial means the constructed a kind of random adaptive global optimization search algorithm, is a kind of mathematical simulation of biological evolution process, is the most important form of evolutionary computation. Genetic algorithm (ga) for those who are hard to find the problem of traditional mathematical model points out a solution. Evolutionary computation and genetic algorithm is used to refer to some knowledge of the biological sciences, this also reflected the characteristics of artificial intelligence in the interdisciplinary. This paper mainly discusses the computer science and technology under the junior in professional class "artificial intelligence" sixth experiment algorithm.
Keywords: Artificial intelligence, genetic
algorithms, evolutionary computation
1,編碼與譯碼
借用生物的術語,把位串形式的解的編碼表示叫染色體或基因型(基因表達),或叫個體。原問題結構即一個染色體解碼後所對應的解稱爲表現型。編碼空間也稱爲基因型空間或搜索空間。解空間也稱爲表現型空間。
進化算法不是直接作用在問題的解空間上,而是交替地作用在編碼空間和解空間上。在編碼空間對個體進行遺傳操作,在解空間對問題的解進行評估。
2,適應度函數
爲了體現染色體的適應能力,引入了對問題中的每一個染色體都能進行度量的函數,叫適應度函數。通過適應度函數來決定染色體的優、劣程度,它體現了自然進化中的優勝劣汰原則。對優化問題,適應度函數就是目標函數。TSP的目標是路徑總長度爲最短,路徑總長度的倒數就可以爲TSP的適應度函數。
其中wn+1=
w1。適應度函數要有效反映每一個染色體與問題的最優解染色體之間的差距,一個染色體與問題的最優解染色體之間的差距小,則對應的適應度函數值之差就小,否則就大。適應度函數的取值大小與求解問題對象的意義有很大的關係。
3,遺傳操作
1)計算各染色體適應度值
2)累計所有染色體適應度值(或選擇概率),記錄每個個體的適應度累加值(或概率累加值)
3) 產生一個隨機數 r,0< r < sumN(或0< r < 1)
4)若sumk-1<
r £ sumk(或qk-1<
r £ qk ),則選擇第k個個體進入交配池。
5) 重複(3)和(4),直到獲得足夠的染色體。
4,程序流程
一般遺傳算法的主要步驟如下:
(1) 隨機產生一個由確定長度的特徵字符串組成的初始羣體。
(2) 對該字符串羣體迭代的執行下面的步①和② ,直到滿足停止標準:
①計算羣體中每個個體字符串的適應值;
②應用選擇、交叉和變異等遺傳算子產生下一代羣體。
(3) 把在後代中出現的最好的個體字符串指定爲遺傳算法的執行結果,這個結果可以表示問題的一個解。
5,問題解析
6,程序設計
#include<iostream>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<iomanip>
using namespace std;
const int NUM=1000; //最大迭代次數
const int POP_SIZE=50; //種羣規模:個體數量
const int GENE=33; //每個個體染色體個數
const int GB1=18; //染色體手段基因片段(二進制)
const int GB2=15; //染色體末端基因片段(二進制)
const int GD=6; //十進制保留小數點位數
const double PI=3.1415926;
void initialize(int v[][GENE]) //初始化羣體
{
int ii,ij;
srand(time(0));
cout<<"基因初始化:"<<endl;
for(ii=0;ii<POP_SIZE;ii++)
{
cout<<endl<<"個體"<<setw(2)<<ii+1<<"基因型 ";
for(ij=0;ij<GENE;ij++)
{
v[ii][ij]=2*rand()/RAND_MAX;
cout<<v[ii][ij];
}
}
cout<<endl;
}
void evaluation(int v[][GENE],double eval[]) //評估函數
{
int ii,ij;
double x1,x2;
for(ii=0;ii<POP_SIZE;ii++)
{
x1=x2=0;
for(ij=0;ij<GB1;ij++) //二進制片段轉爲十進制編碼
{
x1+=v[ii][ij]*pow(2,(GB1-(ij+1)));
}
for(ij=GB1;ij<GENE;ij++)
{
x2+=v[ii][ij]*pow(2,(GENE-(ij+1)));
}
x1=-3.0+x1*(12.1-(-3.0))/(pow(2,GB1)-1); //十進制編碼轉爲十進制值
x2=4.1+x2*(5.8-4.1)/(pow(2,GB2)-1);
eval[ii]=21.5+x1*sin(4*PI*x1)+x2*sin(20*PI*x2);
}
}
int best_eval(double eval[]) //找出每代中最優秀個體基因值
{
int ii,cursor=0;
for(ii=0;ii<POP_SIZE;ii++)
{
if(eval[ii]>eval[cursor])
{
cursor=ii;
}
}
return cursor;
}
int worst_eval(double eval[]) //找出每代中最差個體基因值
{
int ii,cursor=0;
for(ii=0;ii<POP_SIZE;ii++)
{
if(eval[ii]<eval[cursor])
{
cursor=ii;
}
}
return cursor;
}
void selection(double eval[],int v[][GENE],int v_next[][GENE])
{
int ii,ij,ik;
double value;
double p[POP_SIZE]; //選擇概率
double pp[POP_SIZE]={0}; //累積概率
double total_value=0;
for(ii=0;ii<POP_SIZE;ii++)
{
total_value+=eval[ii];
}
for(ii=0;ii<POP_SIZE;ii++)
{
p[ii]=eval[ii]/total_value;
}
pp[0]=p[0];
for(ii=1;ii<POP_SIZE;ii++)
{
pp[ii]=pp[ii-1]+p[ii];
}
for(ii=0;ii<POP_SIZE;ii++) //對於每個次代個體的基因型
{
value=(double)rand()/RAND_MAX; //轉動輪盤
for(ij=0;ij<POP_SIZE;ij++) //搜索命中區域
{
if(value<pp[ij]) //找到後複製、跳出
{
for(ik=0;ik<GENE;ik++)
{
v_next[ii][ik]=v[ij][ik];
}
break;
}
}
}
}
void crossover(int v[][GENE])
{
int ii,ij,ik;
double p=0.8,value1;
int n=0,tmp,value2;
int cursor[POP_SIZE]={-1}; //被選中的染色體下標
for(ii=0;ii<POP_SIZE;ii++) //找被選中的染色體下標
{
value1=(double)rand()/RAND_MAX;
if(value1<p)
{
cursor[n++]=ii;
}
}
for(ii=0;ii<n;ii+=2) //兩兩配對,進行交叉
{
value2=(int)(GENE-1)*rand()/RAND_MAX+1;
for(ij=value2;ij<GENE;ij++)
{
tmp=v[cursor[ii]][ij];
v[cursor[ii]][ij]=v[cursor[ii+1]][ij];
v[cursor[ii+1]][ij]=tmp;
}
}
}
void mutation(int v[][GENE])
{
int ii,ij,ik;
int sum,gene; //基因變異數目
double pm=0.01; //變異概率
sum=(int)(POP_SIZE*GENE*pm)+1;
for(ii=0;ii<sum;ii++)
{
gene=(int)(POP_SIZE*GENE)*rand()/RAND_MAX;
ij=gene/(POP_SIZE*GENE);
ik=gene%(POP_SIZE*GENE);
v[ij][ik]=1-v[ij][ik];
}
}
int main(int argc,char **argv)
{
int ii,ij,ik,max=0;
int v[POP_SIZE][GENE]; //本代羣體基因庫
int v_next[POP_SIZE][GENE]; //次代羣體基因庫
double eval[POP_SIZE]; //本代羣體評估值
double eval_next[POP_SIZE]; //次代羣體評估值
int best_cursor; //本代最優個體適值下標
int best_next_cursor; //次代最優個體適值下標
int worst_next_cursor; //次代最差個體適值下標
int best_gene[GENE]; //本代最優個體基因型
initialize(v);
for(ii=0;ii<NUM&&max<50;ii++)
{
evaluation(v,eval); //本代基因評估
best_cursor=best_eval(eval); //本代最優個體
cout<<endl<<"第"<<setw(3)<<ii+1<<"代最優基因:";
for(ij=0;ij<GENE;ij++) //保存本代最優基因
{
best_gene[ij]=v[best_cursor][ij];
cout<<best_gene[ij];
}
cout<<" 適值:"<<eval[best_cursor];
selection(eval,v,v_next); //選擇
crossover(v_next); //交叉
mutation(v_next); //變異
evaluation(v_next,eval_next);
worst_next_cursor=worst_eval(eval_next);
for(ij=0;ij<GENE;ij++)
{
v_next[worst_next_cursor][ij]=best_gene[ij];
}
evaluation(v_next,eval_next);
best_next_cursor=best_eval(eval_next);
eval[best_cursor]==eval_next[best_next_cursor]?max++:max=0;
for(ij=0;ij<POP_SIZE;ij++)
{
for(ik=0;ik<GENE;ik++)
{
v[ij][ik]=v_next[ij][ik];
}
}
}
cout<<endl<<"最優基因適值爲:"<<eval[best_cursor]<<endl;
cout<<"迭代次數爲:"<<ii<<endl;
system("pause");
return 0;
}
/*
**本題最優值是38.818208
(1) 初始化羣體;
(2) 計算羣體上每個個體的適應度值;
(3) 按由個體適應度值所決定的某個規則選
擇將進入下一代的個體;
(4) 按概率Pc進行交叉操作;
(5) 按概率Pm進行突變操作;
(6) 若沒有滿足某種停止條件,則轉第(2)步,
否則進入下一步。
(7) 輸出羣體中適應度值最優的染色體作爲問題的
滿意解或最優解。
*/