农夫过河问题实现

来源:互联网 发布:淘宝1920全屏海报代码 编辑:程序博客网 时间:2024/06/08 04:44
#include <iostream>
using namespace std;struct Condition{int farmer;int wolf;int sheep;int cabbage;};//定义状态数组Condition conditions[100];char* action[100];//产生某个动作之后在状态更新void takeWolfOver(int i){action[i]="take wolf over.";conditions[i+1].wolf=1;conditions[i+1].sheep=conditions[i].sheep;conditions[i+1].cabbage=conditions[i].cabbage;}void takeWolfBack(int i){action[i]="take wolf back.";conditions[i+1].wolf=0;conditions[i+1].sheep=conditions[i].sheep;conditions[i+1].cabbage=conditions[i].cabbage;}void takeSheepOver(int i){action[i]="take sheep over.";conditions[i+1].wolf=conditions[i].wolf;conditions[i+1].sheep=1;conditions[i+1].cabbage=conditions[i].cabbage;}void takeSheepBack(int i){action[i]="take sheep back.";conditions[i+1].wolf=conditions[i].wolf;conditions[i+1].sheep=0;conditions[i+1].cabbage=conditions[i].cabbage;}void takeCabbageOver(int i){action[i]="take cabbage over.";conditions[i+1].wolf=conditions[i].wolf;conditions[i+1].sheep=conditions[i].sheep;conditions[i+1].cabbage=1;}void takeCabbageBack(int i){action[i]="take cabbage back.";conditions[i+1].wolf=conditions[i].wolf;conditions[i+1].sheep=conditions[i].sheep;conditions[i+1].cabbage=0;}//农夫单独来回void getOverBarely(int i){action[i]="get over barely.";conditions[i+1].wolf=conditions[i].wolf;conditions[i+1].sheep=conditions[i].sheep;conditions[i+1].cabbage=conditions[i].cabbage;}void getBackBarely(int i){action[i]="get back barely.";conditions[i+1].wolf=conditions[i].wolf;conditions[i+1].sheep=conditions[i].sheep;conditions[i+1].cabbage=conditions[i].cabbage;}void showResult(int i){int c;for(c=0;c<i;c++){cout<<c+1<<"."<<action[c]<<endl;}cout<<"Nice job!"<<endl;}void tryOneStep(int i){int c,j;//到达成功状态if(conditions[i].farmer==1&&conditions[i].wolf==1&&conditions[i].sheep==1&&conditions[i].cabbage==1){showResult(i);return;}//到达非法状态if(conditions[i].farmer!=conditions[i].wolf&&conditions[i].wolf==conditions[i].sheep||conditions[i].farmer!=conditions[i].sheep&&conditions[i].sheep==conditions[i].cabbage){return;}//判断是否有重复状态for(c=0;c<i;c++){if(conditions[c].farmer==conditions[i].farmer&&conditions[c].wolf==conditions[i].wolf&&conditions[c].sheep==conditions[i].sheep&&conditions[c].cabbage==conditions[i].cabbage){return;}}j=i+1;if(conditions[i].farmer==0){conditions[j].farmer=1;getOverBarely(i);tryOneStep(j);if(conditions[i].wolf==0){takeWolfOver(i);tryOneStep(j);}if(conditions[i].sheep==0){takeSheepOver(i);tryOneStep(j);}if(conditions[i].cabbage==0){takeCabbageOver(i);tryOneStep(j);}}else{conditions[j].farmer=0;getBackBarely(i);tryOneStep(j);if(conditions[i].wolf==1){takeWolfBack(i);tryOneStep(j);}if(conditions[i].sheep==1){takeSheepBack(i);tryOneStep(j);}if(conditions[i].cabbage==1){takeCabbageBack(i);tryOneStep(j);}}}int main(){conditions[0].farmer=0;conditions[0].wolf=0;conditions[0].sheep=0;conditions[0].cabbage=0;tryOneStep(0);getchar();return 0;}


1. 过程回溯法。把人、狼、羊、白菜看成A、B、C、D。过河的时候从ABCD中选两个过河,在 *          选一个回来。若发生狼跟羊、羊跟白菜在同一个岸边,且农夫不在场,则回溯. * *       2. 图的遍历。设从南岸到北岸,在南岸ABCD的各个状态是(用二进制表示):0000,在 *          北岸的时候各个状态是:1111。所以过河问题就是从0000起始状态到1111最终状态的 *          过程。易得,总共有16中状态。然后把每一种状态看成图的一个结点,把可以连通的 *          结点用有向边连起来,就构成的一个有向图。从0000这个结点遍历(深度优先或者广 *          度优先)图,遍历到1111结点则找到解。 * *       3. 状态回溯法。设从南岸到北岸,在南岸ABCD的各个状态是(用二进制表示):0000,在 *          北岸的时候各个状态是:1111。所以过河问题就是从0000起始状态到1111最终状态的 *          过程。易得,总共有16中状态。从第一种状态0000开始搜索,搜索当前状态下可以到达的 *          状态,搜索到一个则把这个状态看成当前状态,继续搜索。若出现当前状态搜索无可到达 *          的状态或已遍历所有搜索出来的状态,则回溯。直到到达1111状态。 *        *       4. 状态队列搜索法。跟思路3类似,只是搜索的方式不一样。思路3中用栈的思想进行深度搜索 *          这里采用队列的思想进行广度搜索。