|
- # 老虎过河问题的求解
- # 老虎分别有三只大老虎和三只小的老虎,是三对母子
- # 大老虎都会划船,而小老虎中只有x会划船
- # 河边只有一只船,船每次最多只能过两只老虎
- # 当小老虎的妈妈不在身边是,会被其他的大老虎吃掉
- # 要求是:这三对老虎能安全的过河
- ###############算法描述###################
- # 假设从河的左边移动到右边
- # 用a,b,c,x,y,z表示三只大老虎和小老虎
- # 其中a,b,c,x会划船
- #
- #程序用state来记录过河过程中的每个状态
- # 如:起始状态为state.left=[a,b,c,x,y,z],state.right=[],state.boat_position='left'
- # 从起始状态开始,寻找所有可能过河的组合,并将过河后的状态记录下来
- # 例如:
- # 从起始状态开始,可以过河的组合有(x,y),当(x,y)过河之后,新状态是
- # state.left=[a,b,c,z], state.right=[x,y],state.boat_position='right'
- #
- # 然后不断的移动,如果找到了一个状态是
- # state.left=[], state.right=[a,b,c,x,y,z], state.boat_position='right'
- # 此时过河成功,打印出过河的步骤
- #########################################
- #分别代表三对老虎
- a='a'
- b='b'
- c='c'
- x='x'
- y='y'
- z='z'
- # 所有可能过河的组合
- psb=[ (a,),(b,),(c,),(x,),
- (a,b),(a,c),(a,x), (b,a),(c,a),(x,a),
- (b,c),(b,y), (c,b),(y,b),
- (c,z), (z,c),
- (x,y),(x,z), (y,x),(x,z) ]
- def f(x):
- if x in psb:
- return True
- else:
- return False
- def findPossible(llist): #找出列表中由一个或两个元素的组合(可以过河的组合),并过虑
- steps=[]
- length=len(llist)
- for item in llist:
- steps.append( (item,))
- for i in range(0,length-1):
- for j in range(i+1,length):
- steps.append((llist[i],llist[j]))
- return filter(f,steps)
- class state:
- def __init__(self):
- self.left=[]
- self.right=[]
- self.boat_position=''
- self.steps=[]
- self.current_step=()
- def setState(self,left,right,boat_pos):
- self.left=left
- self.right=right
- self.boat_position=boat_pos
- self.left.sort()
- self.right.sort()
- self.findAllSteps()
- def findAllSteps(self):
- if self.boat_position=='left':
- self.steps=findPossible(self.left)
- else:
- self.steps=findPossible(self.right)
- def setCurrentStep(self):
- if self.steps==[]:
- self.current_step=()
- else:
- self.current_step=( self.steps.pop() )
- def isLegal(self): #判断当前状态是否合法 0不合法 1合法 10找到了出口
- if(self.left==[]) and (self.right==[a,b,c,x,y,z]):
- return 10
- if (a in self.left or b in self.left or c in self.left ): #左边有大老虎
- if ( (x in self.left) and (a not in self.left) ):
- return 0
- if ( (y in self.left) and (b not in self.left) ):
- return 0
- if ( (z in self.left) and (c not in self.left) ):
- return 0
- 左边没有大老虎,那么右边一定有大老虎
- if ( (x in self.right) and (a not in self.right) ):
- return 0
- f ( (y in self.right) and (b not in self.right) ):
- return 0
- if ( (z in self.right) and (c not in self.right) ):
- return 0
- return 1
- def printState(self):
- print self.left,self.right,self.boat_position
- print self.steps
- print self.current_step
- def move(self):
- self.setCurrentStep()
- if self.current_step==():
- print "No step ,but still to move"
- print "This infomation is for debug"
- new_state=state()
- if self.boat_position=='left':
- new_state.left=[item for item in self.left if(not item in self.current_step)]
- new_state.right=[item for item in self.right]
- for i in self.current_step:
- new_state.right.append(i)
- new_state.boat_position='right'
- else: #boat position is right
- new_state.right=[item for item in self.right if(not item in self.current_step)]
- new_state.left=[item for item in self.left ]
- for i in self.current_step:
- new_state.left.append(i)
- new_state.boat_position='left'
- new_state.left.sort()
- new_state.right.sort()
- new_state.findAllSteps()
- return new_state
-
- state_list=[] #过河的状态表,表中的每一个无素都是一个状态
- state_stack=[] #表示所有的已经经历过的状态
- def isOldState(sstate):
- for item in state_list:
- if item.left==sstate.left and item.right==item.right and \
- item.boat_position==item.boat_position:
- return True
- return False
- def print_steps():
- for item in state_stack:
- print item.left, item.right
- print item.left,
- if item.boat_position=='left':
- print str(item.current_step)+"-->",
- else:
- print "<--"+str(item.current_step),
- print item.right
- print
- # 主程序
- sstate=state()
- sstate.setState([a,b,c,x,y,z],[],'left')
- state_stack.append(sstate)
- state_list.append(sstate)
- c_state=sstate #栈顶初始值
- while(True) :
- if c_state.steps==[]: #当前无路可走
- state_stack.pop()
- if state_stack==[]:
- break
- c_state=state_stack[ len(state_stack)-1 ]
- continue
- else: # 有路可走了
- next_state=c_state.move()
- if isOldState(next_state):
- continue
- if next_state.isLegal()==0:
- continue
- elif next_state.isLegal()==10:
- print "成功"
- state_stack.append(c_state)
- print_steps()
- break
- else: #下一个状态为合法
- state_stack.append(next_state)
- state_list.append(next_state)
- c_state=next_state
-
-
-
-
复制代码 |
|