国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

C++基于人工智能搜索策略解決農夫過河問題示例

2020-05-23 13:32:05
字體:
來源:轉載
供稿:網友

本文實例講述了C++基于人工智能搜索策略解決農夫過河問題。分享給大家供大家參考,具體如下:

問題描述

一農夫帶著一頭狼,一只羊和一個白菜過河,小船只能一次裝載農夫和一樣貨物,狼會吃羊,羊會吃白菜,只有農夫在時才安全。現欲讓所有物品包括農夫都安全過道河對岸,求最佳答案。

狀態空間

用16*4的矩陣:a[16][4],存放每一步的狀態,第一列表示農夫的狀態,第二列表示菜的狀態,第三列表示羊的狀態,第四列表示狐貍的狀態,數組a里面的元素只為0或1,0代表在左岸,1代表在右岸。

初始狀態a[0][0]=a[0][1]=a[0][2]=a[0][3]=0,目標狀態是矩陣的某一行全為1。

操作規則

1. 農夫做往返運動,即第i步中,a[i][0] = i%2。
2. 每次農夫過河,可以選擇帶一件貨物,也可以選擇不帶。
3. 在農夫不在場的情況下,狼和羊不能在一起,羊和白菜不能在一起。

搜索策略

為了避免重復,我們將搜索過的狀態放到set中,之后避開搜索這個狀態即可。

我們使用深度優先搜索。搜索過程為:農夫做往返運動,當農夫從左岸到右岸時,優先選擇帶貨物過河,當農夫從右岸到左岸時,優先選擇不帶貨物過河。做出選擇之后,前進一步,看看是否達到目標狀態,如果沒有達到,則農夫繼續往返,知道搜索到目標狀態,或者找不到解為止。

C++代碼實現

#include <iostream>#include <cstring>#include <string>#include <set>using namespace std;void search(int i);int a[16][4];set<int> s;int b[16];string ss[2];string t[4];int k;int level;int count1(int a[])//將當前狀態轉化為10進制數 {  return a[0]*8+a[1]*4+a[2]*2+a[3];}void show(int a[])//顯示結果函數 {  cout<<"      左邊:";  for(int i=1;i<=3;i++)    if(a[i]==0)      cout<<t[i]<<" ";  cout<<"  ";  cout<<"右邊:";  for(int i=1;i<=3;i++)    if(a[i]==1)      cout<<t[i]<<" ";  cout<<endl<<endl; }void bringSomething(int i)//假設農夫會帶走某個東西 {  for(int j=1;j<=3;j++)  {    if(a[i][j]==a[i][0])//若j原來和農夫同一個位置,則農夫有可能將j帶走。     {      a[i+1][j]=a[i+1][0];//假設將j帶走       if((!(a[i+1][1]==a[i+1][2]&&a[i+1][1]!=a[i+1][0]||a[i+1][3]==a[i+1][2]&&a[i+1][2]!=a[i+1][0]))&&s.count(count1(a[i+1]))==0&&i>=level)//第i+1層將j帶走時滿足條件,則繼續搜索第i+1層       {        s.insert(count1(a[i+1]));        b[i]=1;        cout<<ss[a[i][0]]<<t[j]<<"  ";        show(a[i+1]);        level++;               search(i+1);      }      else //若不滿足條件則恢復       {        a[i+1][j]=a[i][j];      }          }  }}void bringNothing(int i)//假設農夫什么也不帶走 {  if((!(a[i+1][1]==a[i+1][2]&&a[i+1][1]!=a[i+1][0]||a[i+1][3]==a[i+1][2]&&a[i+1][2]!=a[i+1][0]))&&s.count(count1(a[i+1]))==0&&i>=level)  {      if(i==0)      cout<<"農夫從左邊去右邊,什么也不帶";    else       cout<<"農夫從右邊回左邊,什么也不帶";    show(a[i+1]);    s.insert(count1(a[i+1]));    search(i+1);    level++;  }  else     b[i]=0;}void search(int i)//從第i層開始搜索判斷第i+1層可能的情況 {   if(i>=16||count1(a[i])==15)    return;  for(int j=1;j<=3;j++)//用第i層來初始化第i+1層   {    a[i+1][j]=a[i][j];  }  b[i]=-1;  if(i%2==1)//在右岸,先考慮農夫什么也不帶走   {    bringNothing(i);    if(b[i]==0)      bringSomething(i);  }  else{//在左岸,先考慮農夫會帶走某一樣東西。     bringSomething(i);    if(b[i]!=1)      bringNothing(i);  }}int main(){    ss[0]="農夫從左邊去右邊,帶上";  ss[1]="農夫從右邊回左邊,帶上";  t[1]="菜";  t[2]="羊";  t[3]="狐貍";  memset(a,0,sizeof(a));  for(int i=0;i<16;i++)  {    a[i][0]=i%2;  }  s.clear();  k=0;  level=0;  s.insert(0);  //先將初始狀態儲存起來   search(0); //從第0層開始搜索   for(int i=0;i<16;i++)  {    for(int j=0;j<4;j++)      cout<<a[i][j]<<" ";    cout<<endl;    if(count1(a[i])==15)      break;  }  return 0;}

結果

農夫從右邊回左邊,什么也不帶 左邊:菜 狐貍 右邊:羊農夫從左邊去右邊,帶上菜 左邊:狐貍 右邊:菜 羊農夫從右邊回左邊,帶上羊 左邊:羊 狐貍 右邊:菜農夫從左邊去右邊,帶上狐貍 左邊:羊 右邊:菜 狐貍農夫從右邊回左邊,什么也不帶 左邊:羊 右邊:菜 狐貍農夫從左邊去右邊,帶上羊 左邊: 右邊:菜 羊 狐貍0 0 0 0 1 0 1 0 0 0 1 0 1 1 1 0 0 1 0 0 1 1 0 1 0 1 0 1 1 1 1 1

希望本文所述對大家C++程序設計有所幫助。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 荣成市| 宁国市| 安康市| 龙井市| 穆棱市| 扎鲁特旗| 蒙城县| 寿宁县| 侯马市| 凤山市| 马山县| 鸡西市| 寻甸| 资溪县| 景泰县| 横峰县| 屏山县| 津南区| 濉溪县| 阿克陶县| 泰兴市| 博兴县| 博白县| 白朗县| 乌鲁木齐市| 方城县| 天门市| 博罗县| 彩票| 成都市| 桂平市| 孙吴县| 黄龙县| 布拖县| 柳河县| 武山县| SHOW| 凤凰县| 长葛市| 雅江县| 大竹县|