摘要:北京時間3月12日下午,谷歌人工智能AlphaGo與韓國棋手李世石今日進行了第三場較量,最終AlphaGo戰勝李世石,連續取得三場勝利。
隨着又一次的人工智能與人類智能的世紀大戰,我們不禁要思索,人工智能,是在呼喚上帝還是在召喚惡魔?此時正是時候研究一下人工智能相關理論,而本文主要論述計算機科學與技術專業大三下專業課《人工智能》第一個實驗算法。
關鍵字:人工智能,搜索問題,樹的深度優先搜索
The Missionaries and Cannibals Problem
Abstract: Beijing time on March 12 in the afternoon, Google AlphaGo and artificial intelligence, the third field of the south Korean chess player lee se-dol today, finally beat lee se-dol AlphaGo, won three consecutive victory.
Again, as the century of artificial intelligence and human intelligence war, we can not help but to think, artificial intelligence, in calling upon god or summon demons? Now is the time to study the related theory, artificial intelligence, this paper mainly discusses the computer science and technology under the junior in professional class "artificial intelligence" in the first experiment algorithm。
Keywords: artificial intelligence, search, depth first search tree
1.問題重述
在河的左岸有N個傳教士、N個野人和一條船,傳教士們想用這條船把所有人都運過河去,但有以下條件限制:
(1)修道士和野人都會划船,但船每次最多只能運K個人;
(2)在任何岸邊野人數目都不能超過修道士,否則修道士會被野人吃掉。
假定野人會服從任何一種過河安排,請規划出一個確保修道士安全過河的計划。
2.問題分析
2.1約束條件:
① M≧C 任何時刻兩岸、船上都必須滿足傳教士人數不少於野人數(M=0時除外,既沒有傳教士)
② M+C≦K 船上人數限制在K以內
2.2求解:
傳教士與野人全部安全渡到對岸的解決方案
3.求解過程
3.1變量假設:
設N=3,K=2(三個M和三個C,每次渡河二人以下)
L:左岸,R:右岸,
B:是否有船(0:無船,1:有船)
3.2狀態表示
定義:用三元組(ML,CL,BL)表示左岸狀態,其中:
0≦ML,CL≦3,BL∈{0,1}
如:(0,3,1)表示左岸有三個野人,船在左岸。
從(3,3,1)到(0,0,0)的狀態轉換
狀態空間:32 種狀態,其中:
12種不合理狀態:如(1,0,1)說明右岸有2個M,3個C;
4種不可能狀態:如(3,3,0)說明所有M和C都在左岸,而船在右岸
∴可用的狀態共16種,組成合理的狀態空間
狀態空間具體描述
3.2操作集
定義:Pmc操作:從左岸划向右岸
Qmc操作:從右岸划向左岸
船上人數組合(m,c)共5種(1,0),(1,1),(2,0),(0,1),(0,2)
∵每一種船上的人數組合同時對應P,Q二種操作
∴系統共有5×2=10種操作(規則)
如:P10:if (ML,CL,BL=1) then (ML-1,CL,BL-1)
如果船在左岸,那么一個傳教士划船到右岸
Q01:if (ML,CL,BL=0) then (ML,CL+1,BL+1)
如果船在右岸,那么一個野人划船回到左岸
總共有10種操作
F={P10,P20, P11, P01, P02, Q 10, Q 20, Q 11, Q 01, Q 02}
P10 if( ML ,CL , BL=1 ) then ( ML–1 , CL , BL–1 )
P01 if( ML ,CL , BL=1 ) then ( ML , CL–1 , BL–1 )
P11 if( ML ,CL , BL=1 ) then ( ML–1 , CL–1 ,BL –1 )
P20 if( ML ,CL , BL=1 ) then ( ML–2 , CL , BL–1 )
P02 if( ML ,CL , BL=1 ) then ( ML , CL–2 , BL–1 )
Q10 if( ML ,CL , BL=0 ) then ( ML+1 , CL ,BL+1 )
Q01 if( ML ,CL , BL=0 ) then ( ML , CL+1 , BL+1 )
Q11 if( ML ,CL , BL=0 ) then ( ML+1 , CL +1,BL +1 )
Q20 if( ML ,CL , BL=0 ) then ( ML+2 , CL +2,BL +1 )
Q02 if( ML ,CL , BL=0 ) then ( ML , CL +2, BL+1 )
3.3控制策略
最短路徑有4條,由11次操作構成。
(P11、Q10、P02、Q01、P20、Q11、P20、Q01、P02、Q01、P02)
(P11、Q10、P02、Q01、P20、Q11、P20、Q01、P02、Q10、P11)
(P02、Q01、P02、Q01、P20、Q11、P20、Q01、P02、Q01、P02)
(P02、Q01、P02、Q01、P20、Q11、P20、Q01、P02、Q10、P11)
3.4狀態空間圖
狀態空間圖是一個有向圖,圖中的節點代表狀態,節點之間的連線代表操作,箭頭代表狀態的轉換方向。
3.5狀態空間的一般搜索過程
OPEN表:用於存放剛生成的節點
CLOSE表:用於存放將要擴展或已擴展的節點
1) 把初始節點S0放入OPEN表,並建立只含S0的圖,記為G
OPEN:=S0,G:=G0(G0=S0)
2) 檢查OPEN表是否為空,若為空則問題無解,退出
LOOP:IF(OPEN)=() THEN EXIT(FAIL)
3) 把OPEN表的第一個節點取出放入CLOSE表,記該節點為節點n
N:=FIRST(OPEN),REMOVE(n,OPEN),ADD(n,CLOSE)
4) 觀察節點n是否為目標節點,若是,則求得問題的解,退出
IF GOAL(n) THEN EXIT(SUCCESS)
5) 擴展節點n,生成一組子節點.把其中不是節點n先輩的那些子節點記作集合M,並把這些節點作為節點n的子節點加入G中.
EXPAND(n)-->M(mi),G:=ADD(mi,G)
針對M中子節點的不同情況,分別進行如下處理
對於那些未曾在G中出現過的M成員設置一個指向父節點(n)的指針,並把它放入OPEN表
對於那些先前已在G中出現過的M成員,確定是否要修改指向父節點的指針
對於那些先前已在G中出現,並且已經擴展了的M成員,確定是否需要修改其后繼結點指向父節點的指針
6) 按某種搜索策略對OPEN表中的節點進行排序
7) 轉第2步
針對本題,設置OPEN、CLOSED兩個隊列分別存放待擴展節點和已擴展節點;
對每個生成的新節點,要檢查上述兩表中是否已存在,是否是非法節點;
(合法節點滿足:
ML=0||ML=3||ML=CL)
每擴展一個節點應記錄產生合法后繼節點的操作,以便最后給出操作序列;
4.程序設計
4.1數據結構
節點狀態用列表(m,c,b)表示,其中m表示傳教士在左岸的人數; c表示野人在左岸的人數;b表示船是否在左岸,當b=1時,表示船在左岸,當b=0時,表式船在右岸。
初始狀態: (3,3,1)
目標狀態: (0,0,0)
操作算子: 船上人數組合(m,c)共5種 (1,0),(1,1),(2,0),(0,1),(0,2)
因此算法有10種
1) 從右岸向左岸過1個傳教士,0個野人
2) 從右岸向左岸過1個傳教士,1個野人
3) 從右岸向左岸過2個傳教士,0個野人
4) 從右岸向左岸過0個傳教士,1個野人
5) 從右岸向左岸過0個傳教士,2個野人
6) 從左岸向右岸過1個傳教士,0個野人
7) 從左岸向右岸過1個傳教士,1個野人
8) 從左岸向右岸過2個傳教士,0個野人
9) 從左岸向右岸過0個傳教士,1個野人
10) 從左岸向右岸過0個傳教士,2個野人
狀態節點:
typedef struct st
{
int m; //傳教士
int c; //野人
int b; //船左
}state; //狀態
將有效的狀態節點存儲在樹中
Tree 中的節點
typedef struct hnode
{
state s;
struct hnode *left;
struct hnode *right;
}node;
Open表,closed表 用隊列存儲
//定義隊列中的節點
typedef structQueuenode
{
node * np;
struct Queuenode*next;
}Qnode; //隊列中節點
//定義隊列
typedef structQueue
{
Qnode *front;
Qnode *rear;
}queue;
4.2代碼設計
4.2.1面向對象的迭代方法
1 #include <iostream>
2 using namespace std; 3
4 typedef struct MCNode 5 { 6 int m; 7 int c; 8 int b; 9 int num; 10 struct MCNode *next; 11 struct MCNode *last; 12 }MCNode; 13
14 class List 15 { 16 private: 17 MCNode *head; 18 MCNode *rear; 19 MCNode *current; 20 public: 21 List(); 22 friend bool operator==(MCNode &node1,MCNode &node2); 23 void push_front(MCNode cNode); 24 void push_back(MCNode cNode); 25 void pop_front(); 26 void pop_back(); 27 MCNode &front(); 28 MCNode &back(); 29 void print_list(); 30 bool hit_target(MCNode &cNode); 31 bool legal(MCNode &cNode); 32 bool empty(); 33 bool exist(MCNode &cNode); 34 }; 35
36 List::List() 37 { 38 head=new MCNode(); 39 rear=head; 40 head->m=3; 41 head->c=3; 42 head->b=1; 43 head->num=0; 44 head->last=NULL; 45 head->next=NULL; 46 } 47
48 bool operator==(MCNode &node1,MCNode &node2) 49 { 50 if(node1.m==node2.m&&node1.c==node2.c&&node1.b==node2.b) 51 return true; 52 else
53 return false; 54 } 55
56 void List::push_front(MCNode cNode) 57 { 58 (*head).last=new MCNode(); 59 head->last->next=head; 60 head=head->last; 61 head->m=cNode.m; 62 head->c=cNode.c; 63 head->b=cNode.b; 64 head->num=cNode.num; 65 head->last=NULL; 66 } 67
68 void List::push_back(MCNode cNode) 69 { 70 (*rear).next=new MCNode(); 71 rear->next->last=rear; 72 rear=rear->next; 73 rear->m=cNode.m; 74 rear->c=cNode.c; 75 rear->b=cNode.b; 76 rear->num=cNode.num; 77 rear->next=NULL; 78 } 79
80 void List::pop_front() 81 { 82 if(head->next!=NULL) 83 { 84 head=head->next; 85 head->last=NULL; 86 } 87 else
88 { 89 head=NULL; 90 rear=NULL; 91 } 92 } 93
94 void List::pop_back() 95 { 96 if(rear->last!=NULL) 97 { 98 rear=rear->last; 99 rear->next=NULL; 100 } 101 else
102 { 103 head=NULL; 104 rear=NULL; 105 } 106 } 107
108 MCNode &List::front() 109 { 110 return *head; 111 } 112
113 MCNode &List::back() 114 { 115 return *rear; 116 } 117
118 void List::print_list() 119 { 120 MCNode current; 121 current=*head; 122 while(true) 123 { 124 cout<<current.num<<","<<current.m<<","<<current.c<<","<<current.b<<endl; 125 if(current.next==NULL) 126 break; 127 else
128 { 129 current.c=current.next->c; 130 current.m=current.next->m; 131 current.b=current.next->b; 132 current.num=current.next->num; 133 current.next=current.next->next; 134 } 135 }system("pause"); 136 } 137
138 bool List::hit_target(MCNode &cNode) 139 { 140 MCNode goalNode; 141 goalNode.m=0; 142 goalNode.c=0; 143 goalNode.b=0; 144 if(cNode==goalNode) 145 return true; 146 else
147 return false; 148 } 149
150 bool List::legal(MCNode &cNode) 151 { 152 if(cNode.m>=0&&cNode.m<=3&&cNode.c>=0&&cNode.c<=3) 153 { 154 if((cNode.m==cNode.c)||(cNode.m==3)||(cNode.m==0)) 155 return true; 156 else
157 return false; 158 } 159 else
160 return false; 161 } 162
163 bool List::empty() 164 { 165 if(head==NULL) 166 return true; 167 else
168 return false; 169 } 170
171 bool List::exist(MCNode &cNode) 172 { 173 MCNode *current; 174 current=head; 175 while(current!=NULL) 176 { 177 if(cNode.b==current->b&&
178 cNode.c==current->c&&cNode.m==current->m) 179 return true; 180 else
181 current=current->next; 182 } 183 return false; 184 } 185
186 void print(MCNode &cNode) 187 { 188 cout<<"節點輸出:"<<endl; 189 cout<<cNode.num<<" "<<cNode.m<<","<<cNode.c<<","<<cNode.b<<endl; 190 system("pause"); 191 } 192
193 void expandNode(List &opend,List &closed) 194 { 195 int ii; 196 MCNode cNode=opend.front(); 197 MCNode node[5]; 198 if(cNode.b==1) 199 { 200 for(ii=0;ii<5;ii++) 201 { 202 node[ii].b=0; 203 } 204 node[0].m=cNode.m-1; 205 node[0].c=cNode.c; 206 node[1].m=cNode.m; 207 node[1].c=cNode.c-1; 208 node[2].m=cNode.m-1; 209 node[2].c=cNode.c-1; 210 node[3].m=cNode.m-2; 211 node[3].c=cNode.c; 212 node[4].m=cNode.m; 213 node[4].c=cNode.c-2; 214 } 215 else
216 { 217 for(ii=0;ii<5;ii++) 218 { 219 node[ii].b=1; 220 } 221 node[0].m=cNode.m+1; 222 node[0].c=cNode.c; 223 node[1].m=cNode.m; 224 node[1].c=cNode.c+1; 225 node[2].m=cNode.m+1; 226 node[2].c=cNode.c+1; 227 node[3].m=cNode.m+2; 228 node[3].c=cNode.c; 229 node[4].m=cNode.m; 230 node[4].c=cNode.c+2; 231 } 232 for(ii=opend.front().num;ii!=5;ii++) 233 { 234 opend.front().num++; 235 if(opend.legal(node[ii])&&!opend.exist(node[ii])) 236 { 237 opend.push_front(node[ii]); 238 opend.front().num=0; 239 closed.push_back(opend.front()); 240 return; 241 } 242 } 243 } 244
245 void proceeding(List &opend,List &closed) 246 { 247 int ii; 248 int NUM=0; 249 while(!opend.empty()) 250 { 251 //opend.print_list();
252 if(opend.hit_target(opend.front())) 253 { 254 NUM++; 255 cout<<"The "<<NUM<<"st route is found!"<<endl; 256 closed.print_list(); 257 cout<<endl; 258 opend.pop_front(); 259 closed.pop_front(); 260 } 261 else if(opend.front().num!=5) 262 { 263 expandNode(opend,closed); 264 } 265 else
266 { 267 opend.pop_front(); 268 closed.pop_back(); 269 } 270 } 271 } 272
273 int main(int argc,char** argv) 274 { 275 List opend,closed; 276 proceeding(opend,closed); 277 system("pause"); 278 return 0; 279 }
4.2.2單函遞歸法
1 #include<iostream>
2 using namespace std; 3
4 #define MAX 1024
5
6 typedef struct rule 7 { 8 int missionary; 9 int savage; 10 }Rule; 11
12 typedef struct node 13 { 14 int missionary; 15 int savage; 16 int boat; 17 int direct; 18 }Node; 19
20 typedef struct sequenceStack 21 { 22 Node data[MAX]; 23 int top; 24 }SequenceStack; 25
26 int NUM=0; 27
28 bool stack_empty(SequenceStack &stack) 29 { 30 if(stack.top==-1) 31 { 32 return true; 33 } 34 return false; 35 } 36
37 bool stack_full(SequenceStack &stack) 38 { 39 if(stack.top==MAX-1) 40 { 41 return true; 42 } 43 return false; 44 } 45
46 bool stack_push(SequenceStack &stack,Node &node) 47 { 48 if(stack_full(stack)) 49 { 50 cout<<"The stack is full,pushing failed!"<<endl; 51 return false; 52 } 53 stack.top++; 54 stack.data[stack.top].missionary=node.missionary; 55 stack.data[stack.top].savage=node.savage; 56 stack.data[stack.top].boat=node.boat; 57 stack.data[stack.top].direct=node.direct; 58 return true; 59 } 60
61 bool stack_pop(SequenceStack &stack) 62 { 63 if(stack_empty(stack)) 64 { 65 cout<<"The stack is empty,poping failed!"<<endl; 66 return false; 67 } 68 stack.top--; 69 return true; 70 } 71
72 bool node_reach(Node &node) 73 { 74 if(node.missionary==0&&node.savage==0&&node.boat==0) 75 { 76 return true; 77 } 78 return false; 79 } 80
81 bool node_equal(Node &node1,Node &node2) 82 { 83 if(node1.missionary==node2.missionary&&
84 node1.savage==node2.savage&&
85 node1.boat==node2.boat) 86 { 87 return true; 88 } 89 return false; 90 } 91
92 bool node_visited(SequenceStack &stack,Node &node) 93 { 94 int ii; 95 for(ii=0;ii<=stack.top;ii++) 96 { 97 if(node_equal(stack.data[ii],node)) 98 { 99 return true; 100 } 101 } 102 return false; 103 } 104
105 void stack_print(SequenceStack &stack) 106 { 107 int ii; 108 cout<<"The "<<++NUM<<"st method is:"<<endl; 109 for(ii=0;ii<=stack.top;ii++) 110 { 111 cout<<"("<<stack.data[ii].missionary; 112 cout<<","<<stack.data[ii].savage; 113 cout<<","<<stack.data[ii].boat<<")"<<endl; 114 } 115 cout<<endl; 116 system("pause"); 117 } 118
119 void rule_print(int ruleset_num,Rule *rule) 120 { 121 int ii; 122 for(ii=0;ii<ruleset_num;ii++) 123 { 124 cout<<"("<<rule[ii].missionary<<","<<rule[ii].savage<<")"<<endl; 125 } 126 cout<<endl; 127 system("pause"); 128 } 129
130 void rule_set(int &sample,int &capacity,Rule *rule) 131 { 132 int ii,ij,ik=0; 133 for(ii=0;ii<sample;ii++) 134 { 135 for(ij=0;ij<sample;ij++) 136 { 137 if(ii==0&&ij==0) 138 { 139 continue; 140 } 141 if(ii+ij<=capacity) 142 { 143 rule[ik].missionary=ii; 144 rule[ik++].savage=ij; 145 } 146 } 147 } 148 } 149
150 int ruleset_num_get(int &sample,int &capacity) 151 { 152 int ii,ij,num=0; 153 for(ii=0;ii<sample;ii++) 154 { 155 for(ij=0;ij<sample;ij++) 156 { 157 if(ii==0&&ij==0) 158 { 159 continue; 160 } 161 if(ii+ij<=capacity) 162 { 163 num++; 164 } 165 } 166 } 167 return num; 168 } 169
170 void init(SequenceStack &stack,int &ruleset_num,int &sample,int &capacity) 171 { 172 cout<<"Please enter the initial number of savages and missionaries:"<<endl; 173 cin>>sample; 174 cout<<"Please enter the ship's carrying capacity:"<<endl; 175 cin>>capacity; 176 ruleset_num=ruleset_num_get(sample,capacity); 177 cout<<"\nThere is a total of "<<ruleset_num<<" sets of rules:"<<endl; 178 stack.top=0; 179 stack.data[stack.top].missionary=sample; 180 stack.data[stack.top].savage=sample; 181 stack.data[stack.top].boat=1; 182 stack.data[stack.top].direct=0; 183 } 184
185 void processing(SequenceStack &stack,Rule *rule,int &ruleset_num,int &sample) 186 { 187 Node cNode; 188 if(node_reach(stack.data[stack.top])) 189 { 190 stack_print(stack); 191 } 192 else
193 { 194 while(stack.data[stack.top].direct<ruleset_num) 195 { 196 if(stack.data[stack.top].boat==1) 197 { 198 cNode.missionary=stack.data[stack.top].missionary-
199 rule[stack.data[stack.top].direct].missionary; 200 cNode.savage=stack.data[stack.top].savage-
201 rule[stack.data[stack.top].direct].savage; 202 cNode.boat=0; 203 cNode.direct=0; 204 if(node_visited(stack,cNode)==false&&
205 (cNode.missionary==cNode.savage||
206 cNode.missionary==0||cNode.missionary==sample)&&
207 (cNode.missionary>=0)&&(cNode.missionary<=sample)&&
208 (cNode.savage>=0)&&(cNode.savage<=sample)) 209 { 210 stack_push(stack,cNode); 211 processing(stack,rule,ruleset_num,sample); 212 stack_pop(stack); 213 } 214 } 215 else
216 { 217 cNode.missionary=stack.data[stack.top].missionary+
218 rule[stack.data[stack.top].direct].missionary; 219 cNode.savage=stack.data[stack.top].savage+
220 rule[stack.data[stack.top].direct].savage; 221 cNode.boat=1; 222 cNode.direct=0; 223 if(node_visited(stack,cNode)==false&&
224 (cNode.missionary==cNode.savage||
225 cNode.missionary==0||cNode.missionary==sample)&&
226 (cNode.missionary>=0)&&(cNode.missionary<=sample)&&
227 (cNode.savage>=0)&&(cNode.savage<=sample)) 228 { 229 stack_push(stack,cNode); 230 processing(stack,rule,ruleset_num,sample); 231 stack_pop(stack); 232 } 233 } 234 stack.data[stack.top].direct++; 235 } 236 } 237 } 238
239 int main(int argc,char **argv) 240 { 241 SequenceStack stack; 242 Rule *rule; 243 int ruleset_num,sample,capacity; 244 init(stack,ruleset_num,sample,capacity); 245 rule=new Rule[ruleset_num]; 246 rule_set(sample,capacity,rule); 247 rule_print(ruleset_num,rule); 248 processing(stack,rule,ruleset_num,sample); 249 system("pause"); 250 return 0; 251 }
4.2.3雙函遞歸法
1 #include<stdio.h>
2 #include<stdlib.h>
3 #define MAXSIZE 1024
4
5 typedef struct Rule 6 { 7 int mm; 8 int cc; 9 }Rule; 10 Rule rule[5]={{1,0},{0,1},{1,1},{2,0},{0,2}}; 11
12 typedef struct Node 13 { 14 int m; 15 int c; 16 int b; 17 }Node; 18
19 typedef Node elemtype; 20
21 typedef struct SequenStack 22 { 23 elemtype data[MAXSIZE]; 24 int top; 25 }SequenStack; 26
27 int NUM=0; 28
29 int visited(SequenStack *open,Node newnode) 30 { 31 int ii=0; 32 if(open->top!=-1) 33 { 34 for(ii=0;ii!=open->top;ii++) 35 { 36 if(newnode.m==open->data[ii].m&&
37 newnode.c==open->data[ii].c&&
38 newnode.b==open->data[ii].b) 39 { 40 return 1; 41 } 42 } 43 } 44 return 0; 45 } 46
47 int legal(SequenStack *open,Node newnode) 48 { 49 int i=visited(open,newnode); 50 if(i==0) 51 { 52 if(newnode.m>=0&&newnode.m<=3&&newnode.c>=0&&newnode.c<=3) 53 { 54 if(newnode.m==0||newnode.m==3||newnode.m==newnode.c) 55 { 56 return 1; 57 } 58 } 59 } 60 return 0; 61 } 62
63 int Pop_SequenStack(SequenStack *S) 64 { 65 if(S->top==-1) 66 { 67 printf("The linear list is empty,poping to stack failed!\n"); 68 return 0; 69 } 70 else
71 { 72 S->top--; 73 return 1; 74 } 75 } 76
77 int Push_SequenStack(SequenStack *S,Node node) 78 { 79 if(S->top>=MAXSIZE-1) 80 { 81 printf("The linear list is full,pushing to stack failed!\n"); 82 return 0; 83 } 84 S->top++; 85 S->data[S->top]=node; 86 return 1; 87 } 88
89 void print_result(SequenStack *open) 90 { 91 int ii; 92 printf("第%d種:\n",++NUM ); 93 if(open->top!=-1) 94 { 95 for(ii=0;ii<=open->top;ii++) 96 { 97 printf("(%d,%d,%d)\n",open->data[ii].m, 98 open->data[ii].c,open->data[ii].b); 99 } 100 } 101 printf("\n"); 102 system("pause"); 103 } 104
105 void print(SequenStack *open) 106 { 107 int ii; 108 if(open->top!=-1) 109 { 110 for(ii=0;ii<=open->top;ii++) 111 { 112 printf("(%d,%d,%d)-->",open->data[ii].m, 113 open->data[ii].c,open->data[ii].b); 114 } 115 } 116 printf("\n"); 117 system("pause"); 118 } 119 void DFS(SequenStack *open,Node newnode); 120
121 void processing(SequenStack *open,Node newnode) 122 { 123 int ii,flag; 124 Node node; 125 node.m=newnode.m; 126 node.c=newnode.c; 127 node.b=newnode.b; 128 if(node.b==1) 129 { 130 for(ii=0;ii<5;ii++) 131 { 132 node.m=newnode.m-rule[ii].mm; 133 node.c=newnode.c-rule[ii].cc; 134 node.b=0; 135 flag=legal(open,node); 136 if(flag==1) 137 { 138 Push_SequenStack(open,node); 139 DFS(open,node); 140 Pop_SequenStack(open); 141 } 142 } 143 } 144 else
145 { 146 for(ii=0;ii<5;ii++) 147 { 148 node.m=newnode.m+rule[ii].mm; 149 node.c=newnode.c+rule[ii].cc; 150 node.b=1; 151 flag=legal(open,node); 152 if(flag==1) 153 { 154 Push_SequenStack(open,node); 155 DFS(open,node); 156 Pop_SequenStack(open); 157 } 158 } 159 } 160 } 161
162 void DFS(SequenStack *open,Node node) 163 { 164 if(node.m==0&&node.c==0&&node.b==0) 165 { 166 print_result(open); 167 } 168 else
169 { 170 processing(open,node); 171 } 172 } 173
174 Node init_node() 175 { 176 Node node; 177 node.m=3; 178 node.c=3; 179 node.b=1; 180 return node; 181 } 182
183 SequenStack * Init_open() 184 { 185 SequenStack *open; 186 open=(SequenStack * )malloc(sizeof(SequenStack)); 187 open->top=-1; 188 return open; 189 } 190
191 int main(int argc,char **argv) 192 { 193 SequenStack *open=Init_open(); 194 Node node=init_node(); 195 Push_SequenStack(open,node); 196 DFS(open,node); 197 system("pause"); 198 return 0; 199 }
4.2.4類集框架迭代版
1 #include <iostream>
2 #include <vector>
3 #include <list>
4 using namespace std; 5
6 typedef struct MCNode 7 { 8 int m; 9 int c; 10 int b; 11 int num; 12 }MCNode; 13
14 int NUM=0; 15
16 bool operator==(MCNode &m1,MCNode &m2) 17 { 18 if(m1.m==m2.m&&m1.c==m2.c&&m1.b==m2.b) 19 return true; 20 else
21 return false; 22 } 23
24 bool goal(MCNode &cNode) 25 { 26 MCNode goalNode; 27 goalNode.m=0; 28 goalNode.c=0; 29 goalNode.b=0; 30 if(cNode==goalNode) 31 return true; 32 else
33 return false; 34 } 35
36 bool legal(MCNode &cNode) 37 { 38 if(cNode.m>=0&&cNode.m<=3&&cNode.c>=0&&cNode.c<=3) 39 { 40 if((cNode.m==cNode.c)||(cNode.m==3)||(cNode.m==0)) 41 return true; 42 else
43 return false; 44 } 45 else
46 return false; 47 } 48
49 bool visited(MCNode cNode,list<MCNode> &opend) 50 { 51 list<MCNode>::iterator it; 52 for(it=opend.begin();it!=opend.end();it++) 53 { 54 if(it->m==cNode.m&&it->c==cNode.c&&it->b==cNode.b) 55 return true; 56 } 57 return false; 58 } 59
60 void print_list(list<MCNode> &opend) 61 { 62 list<MCNode>::iterator it; 63 for(it=opend.begin();it!=opend.end();it++) 64 { 65 cout<<it->num<<","<<it->m<<","<<it->c<<","<<it->b<<endl; 66 } 67 system("pause"); 68 } 69
70 void print_result(vector<MCNode> &closed) 71 { 72 vector<MCNode>::iterator it; 73 for(it=closed.begin();it!=closed.end();it++) 74 { 75 cout<<it->num<<","<<it->m<<","<<it->c<<","<<it->b<<endl; 76 } 77 cout<<endl; 78 system("pause"); 79 } 80
81 void expandNode(list<MCNode> &opend,vector<MCNode> &closed) 82 { 83 int ii; 84 MCNode cNode=opend.front(); 85 MCNode node[5]; 86 if(cNode.b==1) 87 { 88 for(ii=0;ii<5;ii++) 89 { 90 node[ii].b=0; 91 } 92 node[0].m=cNode.m-1; 93 node[0].c=cNode.c; 94 node[1].m=cNode.m; 95 node[1].c=cNode.c-1; 96 node[2].m=cNode.m-1; 97 node[2].c=cNode.c-1; 98 node[3].m=cNode.m-2; 99 node[3].c=cNode.c; 100 node[4].m=cNode.m; 101 node[4].c=cNode.c-2; 102 } 103 else
104 { 105 for(ii=0;ii<5;ii++) 106 { 107 node[ii].b=1; 108 } 109 node[0].m=cNode.m+1; 110 node[0].c=cNode.c; 111 node[1].m=cNode.m; 112 node[1].c=cNode.c+1; 113 node[2].m=cNode.m+1; 114 node[2].c=cNode.c+1; 115 node[3].m=cNode.m+2; 116 node[3].c=cNode.c; 117 node[4].m=cNode.m; 118 node[4].c=cNode.c+2; 119 } 120 for(ii=opend.front().num;ii!=5;ii++) 121 { 122 opend.front().num++; 123 if(legal(node[ii])&&!visited(node[ii],opend)) 124 { 125 opend.push_front(node[ii]); 126 opend.front().num=0; 127 closed.push_back(opend.front()); 128 return; 129 } 130 } 131 } 132
133 void proceeding(list<MCNode> &opend,vector<MCNode> &closed) 134 { 135 int ii; 136 while(!opend.empty()) 137 { 138 //print_list(opend);
139 if(goal(opend.front())) 140 { 141 NUM++; 142 cout<<"The "<<NUM<<"st route is found!"<<endl; 143 print_result(closed); 144 opend.pop_front(); 145 closed.pop_back(); 146 } 147 else if(opend.front().num!=5) 148 { 149 expandNode(opend,closed); 150 } 151 else
152 { 153 opend.pop_front(); 154 closed.pop_back(); 155 } 156 } 157 } 158
159 MCNode initNode() 160 { 161 MCNode cNode; 162 cNode.m=3; 163 cNode.c=3; 164 cNode.b=1; 165 cNode.num=0; 166 return cNode; 167 } 168
169 int main(int argc,char** argv) 170 { 171 list<MCNode> opend; 172 vector<MCNode> closed; 173 opend.push_front(initNode()); 174 proceeding(opend,closed); 175 system("pause"); 176 return 0; 177 }