商人过河问题数学建模深度优先搜索(dfs)python和c++代码
问题描述
三名商人各带–个随从乘船渡河,一只小船只能容纳二人,由他们自己划行.随从们密约,在河的任一岸,一旦随从的人数比商人多,就杀人越货,商人们怎样才能安全渡河呢?
问题建模
考虑用深度优先搜索解决此问题,提前记录在船承载量为2时候,所有可行的移动状态,以及所有安全的商人和随从的数量情况,用变量同时在搜索的过程中记录答案,一旦找到左岸已经完全没有人的情况立刻结束搜索,输出方案
变量声明
Ans为记录步骤的数组
Move对于某次决策有哪些移动方法
Sav用于判断此时的状态是否安全
Boat 表示当前这一步船是过去还是回来
运行结果
图片解释
共11步
- 1 两个随从过去
- 2 一个随从回来
- 3 再两个随从过去
- 4 一个随从回来
- 5 两个商人过去
- 6 一个随从和一个商人回来
- 7 两个商人过去
- 8 一个随从回来
- 9 两个随从过去
- 10 一个随从回来
- 11 最后两个随从过去
Code(c++)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int Move[5][2]= {{0, 2}, {1, 1}, {2, 0}, {0, 1}, {1, 0}};//对于某次决策有哪些移动方法 4 const bool Sav[4][4] = {{0, 0, 0, 0}, {1, 0, 1, 1}, {1, 1, 0, 1}, {0, 0, 0, 0}};//判断此时的状态是否安全 5 int Ans[1001][2], step = 1; 6 bool Boat[1001], flag; 7 bool rep (int a, int b, bool flag) {//repeat函数,判断是否有重复状态 8 for(int i = 0; i < step; i ++) { 9 if(a == Ans[i][0] && b == Ans[i][1] && Boat[i] == flag) return 1; 10 } 11 return 0; 12 } 13 bool UnSave (int Tr, int Co, int flag) { 14 if (Tr < 0||Tr > 3||Co < 0||Co > 3|| Sav[Tr][Co] || rep(Tr, Co, flag)) return 1; 15 return 0; 16 } 17 //判断是否不安全的函数 18 void dfs (int Trader, int Cortege) { //商人和随从 19 if(!Trader && !Cortege) { //如果找到了方案立刻输出 20 cout << step - 1 << endl; 21 cout << "(左岸商人" << "," << "左岸随从)" <<" " << "(右岸商人" << "," << "右岸随从)" << endl; 22 for (int i = 0;i < step; i++) { 23 cout << "(" << Ans[i][0] << "," << Ans[i][1] << ") "; 24 cout << "(" << 3 - Ans[i][0] << "," << 3 - Ans[i][1] << ")" << endl; 25 } 26 exit(0); //找到答案,直接退出搜索 27 } 28 else if (!flag) { 29 for (int i = 0; i <= 4; i ++) { 30 Trader -= Move[i][0], Cortege -= Move[i][1]; 31 if (UnSave(Trader, Cortege, flag)) { 32 Trader += Move[i][0], Cortege += Move[i][1]; 33 continue; 34 } 35 Ans[step][0] = Trader, Ans[step][1] = Cortege, Boat[step] = flag; 36 // 存储答案 37 step ++, flag = (!flag); 38 dfs (Trader, Cortege); 39 flag = (!flag); 40 Trader += Move[i][0]; 41 Cortege += Move[i][1];//回溯 42 step --; 43 } 44 } 45 //下面是划回去的状态,与上面同理 46 else { 47 for (int i = 0;i <= 4;i ++) { 48 Trader += Move[i][0]; 49 Cortege += Move[i][1]; 50 if (UnSave (Trader, Cortege, flag)) { 51 Trader -= Move[i][0], Cortege -= Move[i][1]; 52 continue; 53 } 54 Ans[step][0] = Trader, Ans[step][1] = Cortege, Boat[step] = flag; 55 step ++; 56 flag = (!flag); 57 dfs (Trader, Cortege); 58 flag = (!flag); 59 Trader -= Move[i][0]; 60 Cortege -= Move[i][1]; 61 step --; 62 } 63 } 64 } 65 int main() { 66 Ans[0][0] = Ans[0][1] = 3, Boat[0] = 1; 67 dfs (3, 3); 68 return 0; 69 }
Code(python)
Move = [(0, 2), (1, 1), (2, 0), (0, 1), (1, 0)] Sav = [[0, 0, 0, 0], [1, 0, 1, 1], [1, 1, 0, 1], [0, 0, 0, 0]] Ans = [[0, 0] for _ in range(1001)] Boat = [False] * 1001 step = 1 flag = False def rep(a, b, flag): for i in range(step): if a == Ans[i][0] and b == Ans[i][1] and Boat[i] == flag: return True return False def UnSave(Tr, Co, flag): if Tr < 0 or Tr > 3 or Co < 0 or Co > 3 or Sav[Tr][Co] or rep(Tr, Co, flag): return True return False def dfs(Trader, Cortege): global step, flag if not Trader and not Cortege: print(step - 1) print("(左岸商人, 左岸随从) (右岸商人, 右岸随从)") for i in range(step): print(f"({Ans[i][0]}, {Ans[i][1]}) ({3 - Ans[i][0]}, {3 - Ans[i][1]})") exit(0) elif not flag: for i in range(5): Trader -= Move[i][0] Cortege -= Move[i][1] if UnSave(Trader, Cortege, flag): Trader += Move[i][0] Cortege += Move[i][1] continue Ans[step][0] = Trader Ans[step][1] = Cortege Boat[step] = flag step += 1 flag = not flag dfs(Trader, Cortege) flag = not flag Trader += Move[i][0] Cortege += Move[i][1] step -= 1 else: for i in range(5): Trader += Move[i][0] Cortege += Move[i][1] if UnSave(Trader, Cortege, flag): Trader -= Move[i][0] Cortege -= Move[i][1] continue Ans[step][0] = Trader Ans[step][1] = Cortege Boat[step] = flag step += 1 flag = not flag dfs(Trader, Cortege) flag = not flag Trader -= Move[i][0] Cortege -= Move[i][1] step -= 1 if __name__ == "__main__": Ans[0][0] = Ans[0][1] = 3 Boat[0] = True dfs(3, 3)