我试图实施I.A.解决Water Jugs问题的广度优先搜索算法,但我遇到了这个问题:
每次我向数组添加一个新元素时,它都会更改数组中的所有元素。就像它一样。
换句话说......
"边疆"数组正在改变每个" jug"之间的所有元素。函数调用。
有人可以分享一些有关此代码的见解吗?
(我更担心实现逻辑,所以它没有被优化)
代码:
J1SIZE = 3
J2SIZE = 4
frontier = []
explored = []
def IsEmpty(array):
result = False
if len(array) == 0:
result = True
return result
#Fill up a jug
def fillJug(tempNode, jug):
copyNode = tempNode
copyNode = copyNode
if jug == 1:
copyNode[0] = J1SIZE
elif jug == 2:
copyNode[1] = J2SIZE
print(copyNode)
return copyNode
#Empty a jug
def emptyJug(tempNode, jug):
copyNode = tempNode
if jug == 1:
copyNode[0] = 0
elif jug == 2:
copyNode[1] = 0
print(copyNode)
return copyNode
#Pass the content of a jug to another
def passJug(tempNode, jug):
copyNode = tempNode
if jug == 1:
copyNode[1] = copyNode.j1
copyNode[0] = 0
if copyNode[1] > J2SIZE:
copyNode[1] = J2SIZE
elif jug == 2:
copyNode[0] = copyNode[1]
copyNode[1] = 0
if copyNode[0] > J1SIZE:
copyNode[0] = J1SIZE
print(copyNode)
return copyNode
#Check if solution was found
def goalTest(goalNode,currentNode):
result = False
if goalNode == currentNode:
result = True
return result
def BFS(start,end,frontier,explored):
start_node = start
frontier = [start_node] + frontier
if goalTest(end,(frontier[0])):
print('Solution:', frontier[0])
exit()
#Loop start
while IsEmpty(frontier) == False:
tempNode = frontier.pop(0)
#Generate nodes (states)
if tempNode[0] < J1SIZE:
newNode = fillJug(tempNode, 1)
if newNode not in explored:
frontier = [newNode] + frontier
print('Frontier1: ', frontier)
if tempNode[1] < J2SIZE:
newNode = fillJug(tempNode, 2)
if newNode not in explored:
frontier = [newNode] + frontier
print('Frontier2: ', frontier)
if tempNode[0] == J1SIZE:
newNode = emptyJug(tempNode, 1)
if newNode not in explored:
frontier = [newNode] + frontier
print('Frontier3: ', frontier)
if tempNode[1] == J2SIZE:
newNode = emptyJug(tempNode, 2)
if newNode not in explored:
frontier = [newNode] + frontier
print('Frontier4: ', frontier)
if (tempNode[0] > 0) and (tempNode[1] < J2SIZE):
newNode = passJug(tempNode, 1)
if newNode not in explored:
frontier = [newNode] + frontier
print('Frontier5: ', frontier)
if (tempNode[1] > 0) and (tempNode[0] < J1SIZE):
new_node = passJug(tempNode, 2)
if new_node not in explored:
frontier = [new_node] + frontier
print('Frontier6: ', frontier)
print('Frontier: ', frontier)
print('Explored: ', explored)
for node in frontier:
if goalTest(end, node):
print('Solution:', frontier[0])
exit()
if node not in explored:
explored = [node] + explored
BFS([0,0],[0,2],frontier,explored)
固定代码:
答案 0 :(得分:1)
我制作了一个较小的代码示例来重现您的错误:
J1SIZE = 3
J2SIZE = 4
def fillJug(tempNode, jug):
copyNode = tempNode
copyNode = copyNode
if jug == 1:
copyNode[0] = J1SIZE
elif jug == 2:
copyNode[1] = J2SIZE
return copyNode
frontier = [[0, 0]]
tempNode = frontier.pop(0)
newNode = fillJug(tempNode, 1)
frontier = [newNode] + frontier # (1)
newNode = fillJug(tempNode, 2) # (2)
frontier = [newNode] + frontier
问题是,在我标记为(1)
的行中,您设置了newNode
,它将与tempNode
相同的对象作为{{1}中的第一项}}。然后,在我标记为frontier
的行中,您正在更改(2)
- 在tempNode
内。所以fillJug
中的值会发生变化。具体来说,您frontier
引用与copyNode
相同的对象,然后您要更改tempNode
(和copyNode
)引用的数据。
您应该将tempNode
重新定义为
copyNode
这将导致copyNode = tempNode[:]
和copyNode
引用内存中的不同对象(具有相同的值)。 (另一种选择是在导入copy
后将tempNode
设置为copyNode
。)
所以新的copy.copy(tempNode)
将是
fillJug
同样的修复适用于其他def fillJug(tempNode, jug):
copyNode = tempNode[:]
if jug == 1:
copyNode[0] = J1SIZE
elif jug == 2:
copyNode[1] = J2SIZE
return copyNode
函数。