这是一个8的难题,使用bfs和dfs来解决,找到解决方案,并打印出路径的目标。我有麻烦弹出和附加的孩子,使它可以找到解决方案。我的错误是,它只会打印出两个选项,而不是从可能的解决方案分支。终端仍然在进行,尽管没有打印出任何东西。
这是我的代码,底部是一个测试用例。
import copy
#This is the only file you need to work on. You do NOT need to modify other files
# Below are the functions you need to implement. For the first project, you only need to finish implementing bfs() and dfs()
#here you need to implement the Breadth First Search Method
def bfs(puzzle):
list = []
#initialization
state = copy.deepcopy(puzzle)
goal = [0,1,2,3,4,5,6,7,8]
possible_move = [[1,3],[0,2,4],[1,5],[0,4,6],[1,3,5,7],[2,4,8],[3,7],[4,6,8],[5,7]]
#appending the first state
queue = []
queue = [Node(state)]
for node in queue[:]:
print('the state of this game position is:\n ' + str(node.state))
loop = True
notFound = True
l = 0
while loop:
for node in queue:
#blank index in each state
blank = node.state.index(8)
print('the index of the blank is '+ str(blank))
#The possible position
possible_pos = possible_move[blank]
print('possible pos '+ str(possible_pos))
if state != goal:
for i in possible_pos:
possible_sw = copy.deepcopy(node.state)
print('index swap = '+ str(i))
temp = possible_sw[i]
possible_sw[i] = 8
possible_sw[blank] = temp
print('the child nodes is ' + str(possible_sw))
node.insertChild(possible_sw)
if possible_sw == goal:
print('end')
notFound = False
loop = False
#check each child and find the goal state
for node in queue[:]:
for child_state in node.children:
if child_state == [0,1,2,3,4,5,6,7,8]:
final_state = child_state
print('the final state is '+ str(final_state.state))
queue.pop(0)
#find the parent path
while node.parent and loop is False:
sol_path = final_state.state
list.append(sol_path.index(8))
if final_state.parent is not None:
final_state = final_state.parent
else:
parent = False
list.reverse()
list.pop(0)
print('moves list '+ str(list))
return list
#here you need to implement the Depth First Search Method
def dfs(puzzle):
list = []
return list
#This will be for next project
def astar(puzzle):
list = []
return list
def swap(list, pos1, pos2):
list[pos1],list[pos2] = list[pos2], list[pos1]
return list
class Node:
def __init__(self,state,parent = None):
self.parent = parent
self.state = state
self.children = []
def insertChild(self, child_state):
self.children.append(Node(child_state,self))
#test cases
# p =[0, 1, 2, 3, 4, 5, 8, 6, 7]
p = [0, 1, 2, 3, 4, 5, 6, 8, 7]
#p = [0, 1, 2, 3, 8, 4, 6, 7, 5]
#p =[0, 4, 1, 3, 8, 2, 6, 7, 5]
bfs(p)
print("+++++++++++++++++++++")
#dfs(p)
1条答案
按热度按时间cpjpxq1n1#
您的尝试存在几个问题:
queue.append
不会被调用,另一方面,queue[:]
上的内部循环清空了pop
队列,删除了它唯一的元素,从那一刻起,队列保持为空。Node
构造函数只被调用一次,因此永远不会有多个节点,并且测试node.parent
将始终为false,从而使最后一个while
循环无效,并且永远不会打印moveslist(如果有loop
名称将永远不会变为True。if state != goal
没有什么意义,因为state
名称在循环中从未改变。如果有任何改变,这应该引用node.state
,而不是state
。list.pop(0)
不必要地删除了一个移动,循环条件已经检查了节点是否有父节点--所以跳过根状态--所以您将错过 * 两个 * 状态。其他一些备注:
swap
永远不会被调用。l
、notFound
。list
,这是Python中的一个本地名称--选择一个不同的名称。Node
示例的children
属性没有用,尽管你可以迭代它来找到最终状态,但是识别目标是否达到的逻辑已经存在于代码的其他地方......它不需要children
。deepcopy
:你使用的列表并不"深"。2你可以简单地通过应用list
(本地)函数来复制它们,或者用[:]
对它们进行切片。queue
(在初始化中)会使第一次赋值无效,只需进行第二次赋值。puzzle
输出初始状态。但是也许你想输出状态 * 在循环中 *...temp
不需要执行交换,首先,Python可以进行元组赋值,但也可以:移动并不是"真正"交换两个未知值:您知道其中一个是空单元格(8),因此可以安全地用另一个单元格的值覆盖该单元格,然后将另一个单元格的值设置为8--不需要temp
。下面是使用上述注解更正的代码: