LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1041|回复: 3

python写的一个经典“过河程序”

[复制链接]
发表于 2005-6-3 12:54:03 | 显示全部楼层 |阅读模式

  1. # 老虎过河问题的求解
  2. # 老虎分别有三只大老虎和三只小的老虎,是三对母子
  3. # 大老虎都会划船,而小老虎中只有x会划船
  4. # 河边只有一只船,船每次最多只能过两只老虎
  5. # 当小老虎的妈妈不在身边是,会被其他的大老虎吃掉
  6. # 要求是:这三对老虎能安全的过河

  7. ###############算法描述###################
  8. # 假设从河的左边移动到右边
  9. # 用a,b,c,x,y,z表示三只大老虎和小老虎
  10. # 其中a,b,c,x会划船
  11. #
  12. #程序用state来记录过河过程中的每个状态
  13. # 如:起始状态为state.left=[a,b,c,x,y,z],state.right=[],state.boat_position='left'
  14. # 从起始状态开始,寻找所有可能过河的组合,并将过河后的状态记录下来
  15. # 例如:
  16. # 从起始状态开始,可以过河的组合有(x,y),当(x,y)过河之后,新状态是
  17. # state.left=[a,b,c,z], state.right=[x,y],state.boat_position='right'
  18. #
  19. # 然后不断的移动,如果找到了一个状态是
  20. # state.left=[], state.right=[a,b,c,x,y,z], state.boat_position='right'
  21. # 此时过河成功,打印出过河的步骤

  22. #########################################

  23. #分别代表三对老虎               
  24. a='a'
  25. b='b'
  26. c='c'
  27. x='x'
  28. y='y'
  29. z='z'

  30. # 所有可能过河的组合
  31. psb=[       (a,),(b,),(c,),(x,),
  32.         (a,b),(a,c),(a,x),        (b,a),(c,a),(x,a),
  33.         (b,c),(b,y),        (c,b),(y,b),
  34.                 (c,z),                        (z,c),
  35.         (x,y),(x,z),        (y,x),(x,z) ]
  36. def f(x):
  37.         if x in psb:
  38.                 return True
  39.         else:
  40.                 return False
  41. def findPossible(llist): #找出列表中由一个或两个元素的组合(可以过河的组合),并过虑
  42.         steps=[]
  43.         length=len(llist)
  44.         for item in llist:
  45.                 steps.append( (item,))
  46.         for i in range(0,length-1):
  47.                 for j in range(i+1,length):
  48.                         steps.append((llist[i],llist[j]))
  49.         return filter(f,steps)       
  50. class state:
  51.         def __init__(self):
  52.                 self.left=[]
  53.                 self.right=[]
  54.                 self.boat_position=''
  55.                 self.steps=[]
  56.                 self.current_step=()
  57.         def setState(self,left,right,boat_pos):
  58.                 self.left=left
  59.                 self.right=right
  60.                 self.boat_position=boat_pos
  61.                 self.left.sort()
  62.                 self.right.sort()
  63.                 self.findAllSteps()
  64.         def findAllSteps(self):
  65.                 if self.boat_position=='left':
  66.                         self.steps=findPossible(self.left)
  67.                 else:
  68.                         self.steps=findPossible(self.right)
  69.         def setCurrentStep(self):
  70.                 if self.steps==[]:
  71.                         self.current_step=()
  72.                 else:
  73.                         self.current_step=( self.steps.pop() )
  74.         def isLegal(self): #判断当前状态是否合法 0不合法 1合法 10找到了出口               
  75.                 if(self.left==[]) and (self.right==[a,b,c,x,y,z]):
  76.                         return 10
  77.                 if (a in self.left or b in self.left or c in self.left ): #左边有大老虎
  78.                         if ( (x in self.left) and (a not in self.left) ):
  79.                                 return 0
  80.                         if ( (y in self.left) and (b not in self.left) ):
  81.                                 return 0
  82.                         if ( (z in self.left) and (c not in self.left) ):
  83.                                 return 0
  84.                 左边没有大老虎,那么右边一定有大老虎
  85.                 if ( (x in self.right) and (a not in self.right) ):
  86.                         return 0
  87.                 f ( (y in self.right) and (b not in self.right) ):
  88.                         return 0
  89.                 if ( (z in self.right) and (c not in self.right) ):
  90.                         return 0
  91.                 return 1
  92.         def printState(self):
  93.                 print self.left,self.right,self.boat_position
  94.                 print self.steps
  95.                 print self.current_step
  96.         def move(self):
  97.                 self.setCurrentStep()
  98.                 if self.current_step==():
  99.                         print "No step ,but still to move"
  100.                         print "This infomation is for debug"
  101.                 new_state=state()
  102.                 if self.boat_position=='left':
  103.                         new_state.left=[item for item in self.left if(not item in self.current_step)]
  104.                         new_state.right=[item for item in self.right]
  105.                         for i in self.current_step:
  106.                                 new_state.right.append(i)               
  107.                         new_state.boat_position='right'
  108.                 else: #boat position is right
  109.                         new_state.right=[item for item in self.right if(not item in self.current_step)]
  110.                         new_state.left=[item for item in self.left ]
  111.                         for i in self.current_step:
  112.                                 new_state.left.append(i)
  113.                         new_state.boat_position='left'
  114.                 new_state.left.sort()
  115.                 new_state.right.sort()
  116.                 new_state.findAllSteps()
  117.                 return new_state
  118.                
  119. state_list=[] #过河的状态表,表中的每一个无素都是一个状态
  120. state_stack=[] #表示所有的已经经历过的状态
  121. def isOldState(sstate):
  122.         for item in state_list:
  123.                 if item.left==sstate.left and item.right==item.right and \
  124.                                 item.boat_position==item.boat_position:
  125.                         return True
  126.         return False
  127. def print_steps():
  128.         for item in state_stack:
  129.                 print item.left, item.right
  130.                 print item.left,
  131.                 if item.boat_position=='left':
  132.                         print str(item.current_step)+"-->",
  133.                 else:
  134.                         print "<--"+str(item.current_step),
  135.                 print item.right
  136.                 print

  137. # 主程序

  138. sstate=state()
  139. sstate.setState([a,b,c,x,y,z],[],'left')
  140. state_stack.append(sstate)
  141. state_list.append(sstate)
  142. c_state=sstate #栈顶初始值
  143. while(True) :
  144.         if c_state.steps==[]: #当前无路可走       
  145.                 state_stack.pop()
  146.                 if state_stack==[]:
  147.                         break
  148.                 c_state=state_stack[ len(state_stack)-1 ]
  149.                 continue
  150.         else: # 有路可走了
  151.                 next_state=c_state.move()
  152.                 if isOldState(next_state):
  153.                         continue
  154.                 if next_state.isLegal()==0:
  155.                         continue
  156.                 elif next_state.isLegal()==10:
  157.                         print "成功"
  158.                         state_stack.append(c_state)
  159.                         print_steps()
  160.                         break
  161.                 else: #下一个状态为合法
  162.                         state_stack.append(next_state)
  163.                         state_list.append(next_state)
  164.                         c_state=next_state

  165.                                
  166.                        
  167.                
  168.        


复制代码
 楼主| 发表于 2005-6-3 13:05:33 | 显示全部楼层
算法简单的描述是:
假设从河左边向右边过河

从起始状态开始,找出所有能过河的组合,并尝试过河,过河后得到新的状态.

得到新的状态之后,然后再尝试所有可能过河的状态,这样反复不断的尝试,一直找到一个状态是
左边没有一只老虎,而右边有6 只老虎,此时则表示过河成功


算法中,判断一个状态的合法性的算法,感觉很不好,但一时又找不到更好的算法.



程序最后的结果显示,无法安全过河!经过仔细检查,栈最多时达到了9
回复 支持 反对

使用道具 举报

发表于 2005-6-6 00:09:21 | 显示全部楼层
没学过phthon,但是感觉好象是有解的,请指教.

0 在此岸,1 在彼岸,前三个位置是大老虎,后三个位置是小老虎.
abc xyz     操作,                       船最后的位置.
000000     初试状态,                船在此岸       
010010         b 和 y 去彼岸      船在彼岸
000010         b 回来,                  船在此岸       
000111         x 和 z 去彼岸,        船在彼岸       
000011         x 回去 ,                 船在此岸       
011011         b,c 去彼岸,             船在彼岸       
001001        b,y 回来,                船在此岸       
101101    a,x 去彼岸,             船在彼岸
100100        c,z回来,                 船在此岸
111100        b号大老虎和c号大老虎到对岸  此岸留 y z 两个小老虎
111000        x号小老虎自己回到此岸,         彼岸留 abc 三个大老虎
111110        x号小老虎和y号小老虎到彼岸  此岸留 z 小老虎
110110        c号大老虎回此岸
111111    c号大老虎和z号小老虎到彼岸,完毕.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-6-6 21:16:57 | 显示全部楼层
算法经过修改,测试成功!

能够找到一个过河方案
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表