@本文来源于公众号:csdn2299,喜欢可以关注公众号 程序员学府
本文实例讲述了Python基于回溯法子集树模板解决野人与传教士问题。分享给大家供大家参考,具体如下:
问题
在河的左岸有N个传教士、N个野人和一条船,传教士们想用这条船把所有人都运过河去,但有以下条件限制:
(1)修道士和野人都会划船,但船每次最多只能运M个人;
(2)在任何岸边以及船上,野人数目都不能超过修道士,否则修道士会被野人吃掉。
假定野人会服从任何一种过河安排,请规划出一个确保修道士安全过河的计划。
分析
百度一下,网上全是用左岸的传教士和野人人数以及船的位置这样一个三元组作为状态,进行考虑,千篇一律。
我换了一种考虑,只考虑船的状态。
船的状态:(x, y) x表示船上x个传教士,y表示船上y个野人,其中 |x|∈[0, m], |y|∈[0, m], 0<|x|+|y|<=m, x*y>=0, |x|>=|y|
船从左到右时,x,y取非负数。船从右到左时,x,y取非正数
解的编码:[(x0,y0), (x1,y1), …, (xp,yp)] 其中x0+x1+…+xp=N, y0+y1+…+yp=N
解的长度不固定,但一定为奇数
开始时左岸(N, N), 右岸(0, 0)。最终时左岸(0, 0), 右岸(N, N)
由于船的合法状态是动态的、二维的。因此,使用一个函数get_states()来专门生成其状态空间,使得主程序更加清晰。
代码
n = 3 # n个传教士、n个野人
m = 2 # 船能载m人
x = [] # 一个解,就是船的一系列状态
X = [] # 一组解
is_found = False # 全局终止标志
# 计算船的合法状态空间(二维)
def get_states(k): # 船准备跑第k趟
global n, m, x
if k%2==0: # 从左到右,只考虑原左岸人数