函数更改列表值,尽管列表未传递给函数

我在尝试实现一个类似广度优先搜索的I.A.算法来解决水壶问题时遇到了这个问题:

每次我向数组中添加新元素时,它会将数组中的所有元素都变成与新元素相同。

换句话说…

“frontier”数组在每次“jug”函数调用之间会改变其内部的所有元素。

能有人分享一些关于这段代码的见解吗?

(我更担心实现逻辑,所以它没有被优化)

代码如下:

J1SIZE = 3J2SIZE = 4frontier = []explored = []def IsEmpty(array):    result = False    if len(array) == 0:        result = True    return result#填满一个水壶def fillJug(tempNode, jug):    copyNode = tempNode    copyNode = copyNode    if jug == 1:        copyNode[0] = J1SIZE    elif jug == 2:        copyNode[1] = J2SIZE    print(copyNode)    return copyNode#清空一个水壶def emptyJug(tempNode, jug):    copyNode = tempNode    if jug == 1:        copyNode[0] = 0    elif jug == 2:        copyNode[1] = 0    print(copyNode)    return copyNode#将一个水壶的内容传递给另一个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#检查是否找到解决方案def goalTest(goalNode,currentNode):    result = False    if goalNode == currentNode:        result = True    return resultdef BFS(start,end,frontier,explored):    start_node = start    frontier = [start_node] + frontier    if goalTest(end,(frontier[0])):        print('解决方案:', frontier[0])        exit()    #循环开始    while IsEmpty(frontier) == False:        tempNode = frontier.pop(0)        #生成节点(状态)        if tempNode[0] < J1SIZE:            newNode = fillJug(tempNode, 1)            if newNode not in explored:                frontier = [newNode] + frontier                print('前沿1: ', frontier)        if tempNode[1] < J2SIZE:            newNode = fillJug(tempNode, 2)            if newNode not in explored:                frontier = [newNode] + frontier                print('前沿2: ', frontier)        if tempNode[0] == J1SIZE:            newNode = emptyJug(tempNode, 1)            if newNode not in explored:                frontier = [newNode] + frontier                print('前沿3: ', frontier)        if tempNode[1] == J2SIZE:            newNode = emptyJug(tempNode, 2)            if newNode not in explored:                frontier = [newNode] + frontier                print('前沿4: ', frontier)        if (tempNode[0] > 0) and (tempNode[1] < J2SIZE):            newNode = passJug(tempNode, 1)            if newNode not in explored:                frontier = [newNode] + frontier                print('前沿5: ', 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('前沿6: ', frontier)        print('前沿: ', frontier)        print('已探索: ', explored)        for node in frontier:            if goalTest(end, node):                print('解决方案:', frontier[0])                exit()            if node not in explored:                explored = [node] + exploredBFS([0,0],[0,2],frontier,explored)

修复后的代码:

http://codepaste.net/auun4u


回答:

我制作了一个更小的代码示例来重现你的错误:

J1SIZE = 3J2SIZE = 4def fillJug(tempNode, jug):    copyNode = tempNode    copyNode = copyNode    if jug == 1:        copyNode[0] = J1SIZE    elif jug == 2:        copyNode[1] = J2SIZE    return copyNodefrontier = [[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相同的对象)设置为frontier的第一个项目。然后,在我标记为(2)的那一行,你在fillJug中更改了tempNode。所以frontier中的值发生了变化。具体来说,你让copyNode引用与tempNode相同的对象,然后你更改了copyNode(以及tempNode)引用的数据。

你应该重新定义copyNode

copyNode = tempNode[:]

这将使copyNodetempNode引用内存中的不同对象(具有相同的值)。(另一种选择是将copyNode设置为copy.copy(tempNode),在导入copy之后。)

所以新的fillJug将是

def fillJug(tempNode, jug):    copyNode = tempNode[:]    if jug == 1:        copyNode[0] = J1SIZE    elif jug == 2:        copyNode[1] = J2SIZE    return copyNode

同样的修复方法适用于其他Jug函数。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注