人工智慧實驗遺傳優化
㈠ 有哪款游戲是用到了人工智慧里的遺傳演算法,具體說明。謝謝了。
可能PS2的足球用到過。只是可能
㈡ 求一個關於人工智慧的小實驗
人工智慧第二次實驗報告
1.實驗題目:
遺傳演算法的設計與實現
2.實驗目的:
通過人工智慧課程的學習,熟悉遺傳演算法的簡單應用。
3.實驗內容
用遺傳演算法求解f (x) = x2 的最大值,x∈ [0,31],x取整數。
可以看出該函數比較簡單,只要是為了體現遺傳演算法的思想,在問題選擇上,選了一個比較容易實現的,把主要精力放在遺傳演算法的實現,以及核心思想體會上。
4. 實驗過程:
1. 實現過程
(1)編碼
使用二進制編碼,隨機產生一個初始種群。L 表示編碼長度,通常由對問題的求解精度決定,編碼長度L 越長,可期望的最優解的精度也就越高,過大的L 會增大運算量。針對該問題進行了簡化,因為題設中x∈ [0,31],所以將二進制長度定為5就夠用了;
(2)生成初始群體
種群規模表示每一代種群中所含個體數目。隨機產生N個初始串結構數據,每個串結構數據成為一個個體,N個個體組成一個初始群體,N表示種群規模的大小。當N取值較小時,可提高遺傳演算法的運算速度,但卻降低種群的多樣性,容易引起遺傳演算法早熟,出現假收斂;而N當取值較大時,又會使得遺傳演算法效率降低。一般建議的取值范圍是20—100。
(3)適應度檢測
根據實際標准計算個體的適應度,評判個體的優劣,即該個體所代表的可行解的優劣。本例中適應度即為所求的目標函數;
(4)選擇
從當前群體中選擇優良(適應度高的)個體,使它們有機會被選中進入下一次迭代過程,舍棄適應度低的個體。本例中採用輪盤賭的選擇方法,即個體被選擇的幾率與其適應度值大小成正比;
(5)交叉
遺傳操作,根據設置的交叉概率對交配池中個體進行基因交叉操作,形成新一代的種群,新一代中間個體的信息來自父輩個體,體現了信息交換的原則。交叉概率控制著交叉操作的頻率,由於交叉操作是遺傳演算法中產生新個體的主要方法,所以交叉概率通常應取較大值;但若過大的話,又可能破壞群體的優良模式。一般取0.4到0.99。
(6)變異
隨機選擇中間群體中的某個個體,以變異概率大小改變個體某位基因的值。變異為產生新個體提供了機會。變異概率也是影響新個體產生的一個因素,變異概率小,產生新個體少;變異概率太大,又會使遺傳演算法變成隨機搜索。一般取變異概率為0.0001—0.1。
(7)結束條件
當得到的解大於等於900時,結束。從而觀看遺傳的效率問題
㈢ 人工智慧基礎(高中版)書中有很多的實驗是需要下載什麼操作程序才能完成么
把致同學閱讀一遍,你會發現目前還沒辦法操作
㈣ 人工智慧習題遺傳演算法是一種什麼樣的演算法
網路一下遺傳演算法吧。簡單說就是不同的解(解都是復雜參數控制項中的向量)互相交互一部分,看哪些解比較優秀繼續生存。。。
㈤ 怎麼學習遺傳演算法呢本人不是計算機專業,想用遺傳演算法做優化。但是毫無頭緒。
這個演算法入門非常簡單,推薦書《游戲編程中的人工智慧技術》,網上有pdf版,這部書第二章以淺顯的辦法專門說明了遺傳演算法的原理和實現方法
我只能跟你說,這個是人工智慧演算法中的一種,必須了解了才能夠使用(不必深入了解,數學原理也可以忽略),如果你不想了解的話,推薦你找個了解並會用遺傳演算法的人來幫你,你提出需求,他來幫你完成
這個演算法運行成功是概率性的,可能需要運行多次才能達到想要的結果,對於一個復雜的問題,有許多東西需要考慮,對演算法的了解程度和對問題的理解程度要高,不然效果會大打折扣
㈥ 求助:人工智慧「遺傳演算法求解f(x)=xcosx+2的最大值」
為了方便我只求了-3.14到3.14之間的最大值,你可以自己改一下,不過范圍大了之後,種群也因該擴大,我的種群只有66個
結果:極值點(-3.141593,5.141593)
我又算了一下-100到100之間的極大值
結果:極值點(-97.399473,99.394504)
-1000到1000之間的極大值
結果:(999,1001)
-2000到2000之間的極大值
結果:(1998.053550,2000.053163)
以上結果我用matlab畫圖驗證了,沒問題。
希望再給加點分,呵呵
//中國電子科技集團公司
//第一研究室
//呼文韜
//[email protected]
//隨機初始種群
//編碼方式為格雷碼
//選擇方法為隨機遍歷
//採用了精英保存策略
//採用了自適應的交叉率和變異率
//採用了與模擬退火演算法相結合的尺度變換
//採用了均勻交叉法
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <iostream.h>
#include <iomanip.h>
#include <time.h>
#include <windows.h>
#define IM1 2147483563
#define IM2 2147483399
#define AM (1.0/IM1)
#define IMM1 (IM1-1)
#define IA1 40014
#define IA2 40692
#define IQ1 53668
#define IQ2 52774
#define IR1 12211
#define IR2 3791
#define NTAB 32
#define NDIV (1+IMM1/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)
#define zhenjuli 0.005
#define PI 3.14159265358
#define T0 100000//溫度要取得很高才行。
#define zhongqunshu1 200
#define zuobianjie -2000
#define youbianjie 2000
unsigned int seed=0; //seed 為種子,要設為全局變數
void mysrand(long int i) //初始化種子
{
seed = -i;
}
long a[1];
//double hunn;
//double c=4;
//設置全局變數
struct indivial
{
unsigned *chrom; //染色體;
double geti;//變數值
double shiying; //目標函數的值;
double fitness; //變換後的適應度值;
};
indivial *zuiyougeti;//精英保存策略
int zhongqunshu; //種群大小
indivial *nowpop;//當前代
indivial *newpop;//新一代
double sumfitness;//當代的總適應度fitness
double sumshiying;//當代的總適應度shiying
double maxfitness;//最大適應度
double avefitness;//平均適應度
double maxshiying;//最大適應度
double avgshiying;//平均適應度
float pc;//交叉概率
float pm;//變異概率
int lchrom;//染色體長度
int maxgen;//最大遺傳代數
int gen;//遺傳代數
//函數
int flipc(double ,double );//判斷是否交叉
int flipm(double );//判斷是否變異
int rnd(int low,int high);//產生low與high之間的任意數
void initialize();//遺傳演算法初始化
void preselectfitness(); //計算sumfiness,avefitness,maxfitness
void generation();
double suijibianli();//產生隨機遍歷指針
int fu(float );//選擇要復制的個體
void crossover(indivial ,indivial ,indivial &,indivial &);//交叉
void bianyi(indivial &);//變異
void mubiaohanshu(indivial &);//計算適應度
void chibianhuan(indivial &);//對shiying進行尺度變換賦給fitness
double ran1(long *);//隨機數初始
void bianma(double bianliang,unsigned *p);//編碼
double yima(unsigned *p);
void guanjiancanshujisuan();//計算shiying,根據shiying計算sumshiying,對shiying進行尺度變換變成fitness,根據fitness計算sumfitness,avefitness,maxfitness
void jingyingbaoliu();
void glp(int n,int s,int *,int (*)[1],float (*)[1]);//glp生成函數
BOOL Exist(int Val, int Num, int *Array);//判斷一個數在前面是否出現過
int cmpfitness(const void *p1,const void *p2)
{
float i=((indivial *)p1)->shiying;//現在是按照"適應度"排序,改成"個體"的話就是按照"個體"排序
float j=((indivial *)p2)->shiying;
return i<j ? -1:(i==j ? 0:1);//現在是按升序牌排列,將1和-1互換後就是按降序排列
}
void main()
{
initialize();
cout<<zuiyougeti->geti<<" "<<zuiyougeti->shiying<<endl;/////////////
for(gen=1;gen<maxgen;gen++)
{ generation();
}
jingyingbaoliu();
cout<<setiosflags(ios::fixed)<<setprecision(6)<<zuiyougeti->geti<<" "<<setiosflags(ios::fixed)<<setprecision(6)<<(zuiyougeti->shiying)<<endl;////////////////
delete [] newpop;
delete [] nowpop;
delete [] zuiyougeti;
system("pause");
}
void initialize()
{
int q[zhongqunshu1][1],s=1;
float xx[zhongqunshu1][1];//生成的glp用x儲存
int h[1]={1};//生成向量
zuiyougeti=new indivial;//最優個體的生成
zhongqunshu=200;//種群數量
nowpop=new indivial[zhongqunshu1];//當代
newpop=new indivial[zhongqunshu1];//新一代
maxgen=150;//最大代數
gen=0;//起始代
lchrom=22;//基因數量的初始化
mysrand(time(0));//隨機數種子
a[0]=seed;//隨機數種子
//對最優個體的初始化
zuiyougeti->geti=0;
zuiyougeti->fitness=0;
zuiyougeti->shiying=0;
//
glp(zhongqunshu,s,h,q,xx);
//for(int i=0;i<zhongqunshu1;i++)//產生初始種群
//{
// for(int j=0;j<s;j++)
// {
// nowpop[i].geti=zuobianjie+(youbianjie-zuobianjie)*xx[i][j];
// }
//}
for(int i=0;i<zhongqunshu1;i++)//產生初始種群
{
nowpop[i].geti=zuobianjie+(youbianjie-(zuobianjie))*ran1(a);
}
//nowpop[0].geti=999;//////////////////////////
guanjiancanshujisuan();
jingyingbaoliu(); //精英保留的實現
guanjiancanshujisuan();//計算shiying,根據shiying計算sumshiying,對shiying進行尺度變換變成fitness,根據fitness計算sumfitness,avefitness,maxfitness
}
void jingyingbaoliu() //精英保留的實現
{
indivial *zuiyougetiguo;
zuiyougetiguo=new indivial[zhongqunshu1];//建立一個過渡數組
for(int i=0;i<zhongqunshu;i++)//將當代個體復制到過渡數組中
zuiyougetiguo[i]=nowpop[i];
qsort(zuiyougetiguo,zhongqunshu1,sizeof(indivial),&cmpfitness);//按fitness升序排序
// cout<<"zuiyougetiguo適應度:"<<zuiyougetiguo[zhongqunshu1-1].shiying<<endl;///////////
// cout<<"zuiyougeti適應度:"<<zuiyougeti->shiying<<endl;///////////////////
//system("pause");
if(zuiyougetiguo[zhongqunshu-1].shiying>zuiyougeti->shiying)
{
*zuiyougeti=zuiyougetiguo[zhongqunshu1-1];//如果最優個體的fitness比當代最大的fitness小則用當代的代替之
//cout<<"zuiyougetiguo個體:"<<zuiyougetiguo[zhongqunshu1-1].geti<<endl;/////////////
//cout<<"zuiyougeti個體:"<<zuiyougeti->geti<<endl;/////////////
}
else
nowpop[rnd(0,(zhongqunshu1-1))]=*zuiyougeti;//否則的話從當代中隨機挑選一個用最優個體代替之
delete [] zuiyougetiguo;//釋放過渡數組
}
void guanjiancanshujisuan()//計算shiying,根據shiying計算sumshiying,對shiying進行尺度變換變成fitness,根據fitness計算sumfitness,avefitness,maxfitness
{
for(int i=0;i<zhongqunshu;i++)//計算shiying
mubiaohanshu(nowpop[i]);
for(i=0;i<zhongqunshu;i++)//對shiying進行尺度變換變成fitness
chibianhuan(nowpop[i]);
preselectfitness();//根據fitness計算sumfitness,avefitness,maxfitness
}
void mubiaohanshu(indivial &bianliang)//計算shiying
{
bianliang.shiying=(bianliang.geti*cos(bianliang.geti)+2.0);//目標函數
}
void chibianhuan(indivial &bianliang)//對shiying進行尺度變換變成fitness
{
double T;//退火溫度
T=T0*(pow(0.99,(gen+1-1)));
double sum=0;
for(int j=0;j<zhongqunshu;j++)
sum+=exp(nowpop[j].shiying/T);
bianliang.fitness=exp(bianliang.shiying/T)/sum;//算出fitness
}
void preselectfitness()//根據fitness計算sumfitness,avefitness,maxfitness
{
int j;
sumfitness=0;
for(j=0;j<zhongqunshu;j++)
sumfitness+=nowpop[j].fitness;
indivial *guo;
guo=new indivial[zhongqunshu1];
for(j=0;j<zhongqunshu;j++)
guo[j]=nowpop[j];
qsort(guo,zhongqunshu1,sizeof(indivial),&cmpfitness);
maxfitness=guo[zhongqunshu1-1].fitness;
avefitness=sumfitness/zhongqunshu1;
delete [] guo;
}
void generation()
{
indivial fuqin1,fuqin2,*pipeiguo,*pipeichi;
int *peiishuzu;//用來存放產生的隨機配對
pipeiguo=new indivial[zhongqunshu1];
pipeichi=new indivial[zhongqunshu1];
peiishuzu=new int[zhongqunshu1];
int member1,member2,j=0,fujishu=0,i=0,temp=0,tt=0;
float zhen;
//隨機遍歷的實現
for(zhen=suijibianli();zhen<1;(zhen=zhen+zhenjuli))//設定指針1/66
{
pipeichi[fujishu]=nowpop[fu(zhen)];
fujishu++;
}
//交叉與變異的實現
//交叉
for(i=0;i<zhongqunshu1;i++)
{
peiishuzu[i]=-1;
}
for (i=0; i<zhongqunshu1; i++)
{
temp =rnd(0,zhongqunshu1-1); //產生值在0-zhongqunshu1-1的隨機數
while(Exist(temp, i, peiishuzu))//判斷產生的隨機數是否已經產生過,如果是,則再產生一個隨機數
{
temp =rnd(0,zhongqunshu1-1);
}
//如果沒有的話,則把產生的隨機數放在peiishuzu中
*(peiishuzu+i) = temp;
}
for(i=0;i<zhongqunshu1-1;i=i+2)
{
fuqin1=pipeichi[peiishuzu[i]];
fuqin2=pipeichi[peiishuzu[i+1]];
crossover(fuqin1,fuqin2,newpop[i],newpop[i+1]);
}
for(j=0;j<zhongqunshu1;j++)
{
//if(newpop[j].geti<-1000)
//cout<<"個體數值小於下界了";
nowpop[j].geti=newpop[j].geti;
}
//
guanjiancanshujisuan();
//變異的實現
for(j=0;j<zhongqunshu;j++)
{
bianyi(nowpop[j]);
}
//
guanjiancanshujisuan();
//精英保留的實現
jingyingbaoliu();
//
guanjiancanshujisuan();
delete [] peiishuzu;
delete [] pipeichi;
delete [] pipeiguo;
}
void crossover(indivial parent1,indivial parent2,indivial &child1,indivial &child2)//交叉
{
int j;
unsigned *panan;
panan=new unsigned[lchrom];
parent1.chrom=new unsigned[lchrom];
parent2.chrom=new unsigned[lchrom];
child1.chrom=new unsigned[lchrom];
child2.chrom=new unsigned[lchrom];
//cout<<"jiaocha"<<endl;///////////////////////
bianma(parent1.geti,parent1.chrom);
bianma(parent2.geti,parent2.chrom);
if(flipc(parent1.fitness,parent2.fitness))
{
for(j=0;j<lchrom;j++)
panan[j]=rnd(0,1);
//for(j=0;j<lchrom;j++)////////////////
// {
// cout<<panan[j];/////////////
// }
// cout<<endl;////////////////
// system("pause");////////////////
for(j=0;j<lchrom;j++)
{
if(panan[j]==1)
child1.chrom[j]=parent1.chrom[j];
else
child1.chrom[j]=parent2.chrom[j];
}
for(j=0;j<lchrom;j++)
{
if(panan[j]==0)
child2.chrom[j]=parent1.chrom[j];
else
child2.chrom[j]=parent2.chrom[j];
}
//for(j=0;j<lchrom;j++)////////////////
//{
// cout<<child1.chrom[j];/////////////
// }
//cout<<endl;////////////////
// system("pause");////////////////
child1.geti=yima(child1.chrom);
child2.geti=yima(child2.chrom);
delete [] child2.chrom;
delete [] child1.chrom;
delete [] parent2.chrom;
delete [] parent1.chrom;
delete [] panan;
}
else
{
for(j=0;j<lchrom;j++)
{
child1.chrom[j]=parent1.chrom[j];
child2.chrom[j]=parent2.chrom[j];
}
child1.geti=yima(child1.chrom);
child2.geti=yima(child2.chrom);
delete [] child2.chrom;
delete [] child1.chrom;
delete [] parent2.chrom;
delete [] parent1.chrom;
delete [] panan;
}
}
void bianyi(indivial &child)//變異
{
child.chrom=new unsigned[lchrom];
//cout<<"變異"<<endl;
bianma(child.geti,child.chrom);
for(int i=0;i<lchrom;i++)
if(flipm(child.fitness))
{
if(child.chrom[i]=0)
child.chrom[i]=1;
else
child.chrom[i]=0;
}
child.geti=yima(child.chrom);
delete [] child.chrom;
}
void bianma(double bianliang,unsigned *p)//編碼
{
unsigned *q;
unsigned *gray;
q=new unsigned[lchrom];
gray=new unsigned[lchrom];
int x=0;
int i=0,j=0;
if(bianliang<zuobianjie)///////////////////
{
cout<<"bianliang:"<<bianliang<<endl;/////////
system("pause");
}
//cout<<youbianjie-(zuobianjie)<<endl;
//system("pause");
x=(bianliang-(zuobianjie))*((pow(2,lchrom)-1)/(youbianjie-(zuobianjie)));
//cout<<x<<endl;///////////
if(x<0)
system("pause");///////////
for(i=0;i<lchrom;i++)
{
q[i]=0;
p[i]=0;
}
i=0;
while (x!=0&&(i!=lchrom))
{
q[i]=(unsigned)(x%2);
x=x/2;
i++;
}
// for(i=0;i<lchrom;i++)//////////////////
// cout<<q[i];///////////////
// cout<<endl;///////////
int w=lchrom-1;
if(q[w]!=0&&q[w]!=1)
system("pause");
for(j=0;j<lchrom&&w>0;j++)
{
p[j]=q[w];
w--;
}
//cout<<"yuanma"<<endl;
//for(j=0;j<lchrom;j++)///////////
// cout<<p[j];////////
//cout<<endl;////////////////////
gray[0]=p[0];
for(j=1;j<lchrom;j++)
{
if(p[j-1]==p[j])
gray[j]=0;
else if(p[j-1]!=p[j])
gray[j]=1;
}
for(j=0;j<lchrom;j++)
p[j]=gray[j];
//cout<<"geleima"<<endl;
//for(j=0;j<lchrom;j++)///////////
// cout<<p[j];////////
//cout<<endl;////////////////////
//system("pause");///////////
delete [] gray;
delete [] q;
}
double yima(unsigned *p) //解碼
{
int i=0;
// for(i=0;i<lchrom;i++)/////////
// {
// cout<<p[i];//////
// }
// cout<<endl;/////////
// system("pause");//////////
int x=0;
unsigned *q;
q=new unsigned[lchrom];
q[0]=p[0];
// cout<<q[0]<<endl;//////////////////
// system("pause");//////////
for(int j=1;j<lchrom;j++)
{
if(q[j-1]==p[j])
q[j]=0;
else if(q[j-1]!=p[j])
q[j]=1;
}
// for(i=0;i<lchrom;i++)//////
// {
// cout<<q[i];//////////
// if(q[i]!=0&&q[i]!=1)
// {
// cout<<q[i];
// system("pause");
// }
// }
// cout<<endl;////////
// system("pause");///////////////////
for(i=0;i<lchrom;i++)
x=x+q[i]*pow(2,(lchrom-i-1));
if(x<0)
{
cout<<"解碼出錯1"<<endl;
system("pause");
}
//cout<<"x:"<<x<<endl;
double bianliang;
//cout<<pow(2,22)<<endl;
//cout<<2000*x<<endl;
//cout<<(x*(2000/(pow(2,22)-1)))<<endl;
bianliang=(x*((youbianjie-(zuobianjie))/(pow(2,lchrom)-1)))+zuobianjie;
if(bianliang<zuobianjie)
{
cout<<"解碼出錯2"<<endl;
system("pause");
}
delete [] q;
return bianliang;
}
double ran1(long *im)
{
int j;
long k;
static long im2=123456789;
static long iy=0;
static long iv[NTAB];
float temp;
if (*im <= 0)
{
if (-(*im) < 1) *im=1;
else *im = -(*im);
im2=(*im);
for (j=NTAB+7;j>=0;j--)
{
k=(*im)/IQ1;
*im=IA1*(*im-k*IQ1)-k*IR1;
if (*im < 0) *im += IM1;
if (j < NTAB) iv[j] = *im;
}
iy=iv[0];
}
k=(*im)/IQ1;
*im=IA1*(*im-k*IQ1)-k*IR1;
if (*im < 0) *im += IM1;
k=im2/IQ2;
im2=IA2*(im2-k*IQ2)-k*IR2;
if (im2 < 0) im2 += IM2;
j=iy/NDIV;
iy=iv[j]-im2;
iv[j] = *im;
if (iy < 1) iy += IMM1;
if ((temp=AM*iy) > RNMX) return RNMX;
else return temp;
}
double suijibianli()//隨機遍歷
{
double i=ran1(a);
while(i>zhenjuli)
{
i=ran1(a);
}
//cout<<i<<endl;//////////////
return i;
}
int fu(float p)//復制
{
int i;
double sum=0;
if(sumfitness!=0)
{
for(i=0;(sum<p)&&(i<zhongqunshu);i++)
sum+=nowpop[i].fitness/sumfitness;
}
else
i=rnd(1,zhongqunshu1);
return(i-1);
}
int rnd(int low, int high) /*在整數low和high之間產生一個隨機整數*/
{
int i;
if(low >= high)
i = low;
else
{
i =(int)((ran1(a) * (high - low + 1)) + low);
if(i > high) i = high;
}
return(i);
}
int flipc(double p,double q)//判斷是否交叉
{
double pc1=0.9,pc2=0.6;
if((p-q)>0)
{
if(p>=avefitness)
{
pc=pc1-(pc1-pc2)*(p-avefitness)/(maxfitness-avefitness);
}
else
pc=pc1;
}
else
{
if(q>=avefitness)
{
pc=pc1-(pc1-pc2)*(q-avefitness)/(maxfitness-avefitness);
}
else
pc=pc1;
}
if(ran1(a)<=pc)
return(1);
else
return(0);
}
int flipm(double p)//判斷是否變異
{
double pm1=0.001,pm2=0.0001;
if(p>=avefitness)
{
pm=(pm1-(pm1-pm2)*(maxfitness-p)/(maxfitness-avefitness));
}
else
pm=pm1;
if(ran1(a)<=pm)
return(1);
else
return(0);
}
void glp(int n,int s,int *h,int (*q)[1],float (*xx)[1])//glp
{
int i=0,j=0;
//求解q
for(i=0;i<n;i++)
{
for(j=0;j<s;j++)
{
*(*(q+i)+j)=((i+1)*(*(h+j)))%n;
}
}
i=n-1;
for(j=0;j<s;j++)
{
*(*(q+i)+j)=n;
}
//求解x
for(i=0;i<n;i++)
{
for(j=0;j<s;j++)
{
*(*(xx+i)+j)=(float)(2*(*(*(q+i)+j))-1)/(2*n);
}
}
}
BOOL Exist(int Val, int Num, int *Array)//判斷一個數是否在一個數組的前Num個數中
{
BOOL FLAG = FALSE;
int i;
for (i=0; i<Num; i++)
if (Val == *(Array + i))
{
FLAG = TRUE;
break;
}
return FLAG;
}