传教士与野人问题
传教士与野人问题:三个传教士,三个野人,一条船,船最多搭载两个人,传教士和野人都能划船,如何用求解这个问题?
根据<人工智能>的搜索算法,定义目标函数,初始状态,计算出状态空间,然后进行搜索,由于路径耗散是常量,省略了路径耗散函数
这个问题的推广:nn野人问题,在n>3时是无解的
#ifndef te_acrossRiver_MOC_H20132417 #define te_acrossRiver_MOC_H20132417 #include "te_common.h" class AcrossRiver:public Singaleton<AcrossRiver> { class StateNode { public: int goodManLeft; int badManLeft; int goodManRight; int badManRight; bool boatAtLeft; StateNode* clone() { StateNode* p1=new StateNode(); p1->goodManLeft=goodManLeft; p1->goodManRight=goodManRight; p1->badManLeft=badManLeft; p1->badManRight=badManRight; return p1; } bool isSameState(StateNode* p1) { return p1->goodManRight==goodManRight&&p1->goodManLeft==goodManLeft&&p1->badManLeft==badManLeft&&p1->badManRight==badManRight &&p1->boatAtLeft==boatAtLeft; } //后继状态 vector<StateNode*> linkNodes; }; bool targetTest(StateNode* p) { return p->goodManLeft==0&&p->badManLeft==0; } //node是否合法 bool nodeTest(StateNode* p,vector<StateNode*>* states) { auto it1=find_if(states->begin(),states->end(),[&](StateNode* p1){ return p->isSameState(p1); }); bool b1=it1==states->end(); bool bleft=(p->goodManLeft==0)||(p->goodManLeft>=p->badManLeft); bool bright=(p->goodManRight==0)||(p->goodManRight>=p->badManRight); bool b3=p->goodManLeft>=0&&p->goodManRight>=0&&p->badManLeft>=0&&p->badManRight>=0; return b1&&bleft&&bright&&b3; } void genStatesColection(StateNode* initial,vector<StateNode*>* states) { if(targetTest(initial)) { return; }else { auto perNodeFunc=[&](StateNode* v){ if(nodeTest(v,states)) { CCLOG("add state %d %d %d %d",v->goodManLeft,v->badManLeft,v->goodManRight,v->badManRight); initial->linkNodes.push_back(v); }else { delete v; } }; if(initial->boatAtLeft) { //右移一个goodman { StateNode* n1=initial->clone(); n1->boatAtLeft=false; n1->goodManLeft--; n1->goodManRight++; perNodeFunc(n1); } //右移一个badman { StateNode* n1=initial->clone(); n1->boatAtLeft=false; n1->badManLeft--; n1->badManRight++; perNodeFunc(n1); } //右移两个good { StateNode* n1=initial->clone(); n1->boatAtLeft=false; n1->goodManLeft-=2; n1->goodManRight+=2; perNodeFunc(n1); } //右移两个bad { StateNode* n1=initial->clone(); n1->boatAtLeft=false; n1->badManLeft-=2; n1->badManRight+=2; perNodeFunc(n1); } //混合右移 { StateNode* n1=initial->clone(); n1->boatAtLeft=false; n1->goodManLeft--; n1->goodManRight++; n1->badManLeft--; n1->badManRight++; perNodeFunc(n1); } }else { //左移一个goodman { StateNode* n1=initial->clone(); n1->boatAtLeft=true; n1->goodManLeft++; n1->goodManRight--; perNodeFunc(n1); } //左移一个badman { StateNode* n1=initial->clone(); n1->boatAtLeft=true; n1->badManLeft++; n1->badManRight--; perNodeFunc(n1); } //左移两个good { StateNode* n1=initial->clone(); n1->boatAtLeft=true; n1->goodManLeft+=2; n1->goodManRight-=2; perNodeFunc(n1); } //左移两个bad { StateNode* n1=initial->clone(); n1->boatAtLeft=true; n1->badManLeft+=2; n1->badManRight-=2; perNodeFunc(n1); } //混合左移 { StateNode* n1=initial->clone(); n1->boatAtLeft=true; n1->goodManLeft++; n1->goodManRight--; n1->badManLeft++; n1->badManRight--; perNodeFunc(n1); } } states->push_back(initial); for_each(initial->linkNodes.begin(),initial->linkNodes.end(),[&](StateNode* n1){ genStatesColection(n1,states); }); } } bool containState(vector<StateNode*>* nodes,StateNode* node) { auto it1=find_if(nodes->begin(),nodes->end(),[&](StateNode* p1){ return p1->isSameState(node); }); return it1!=nodes->end(); } bool DFSSearch(vector<StateNode*>* path) { StateNode* curNode=path->back(); for (int i=0;i<curNode->linkNodes.size();i++) { StateNode* subNode=curNode->linkNodes[i]; path->push_back(subNode); if(targetTest(subNode)) { return true; }else { bool b1=DFSSearch(path); if(b1) return true; } path->pop_back(); } return false; } public: void run(int m,int n) { StateNode* node1=new StateNode(); node1->goodManLeft=m; node1->badManLeft=n; node1->badManRight=0; node1->goodManRight=0; node1->boatAtLeft=true; vector<StateNode*>* nodes=new vector<StateNode*>(); genStatesColection(node1,nodes); vector<StateNode*> path; path.push_back(node1); bool b=DFSSearch(&path); for_each(path.begin(),path.end(),[&](StateNode* p1){ CCLOG("%d %d %d %d %d",p1->goodManLeft,p1->badManLeft,p1->goodManRight,p1->badManRight,p1->boatAtLeft); }); CCLOG("state space %d",nodes->size()); } protected: }; #endif