Python Dijkstra:从未访问的错误中删除当前节点:list.remove(x):x不在列表中

Python Dijkstra:从未访问的错误中删除当前节点:list.remove(x):x不在列表中,list,dijkstra,remove-method,List,Dijkstra,Remove Method,我希望你能帮我解决一些困扰我的问题。我真的试着自己解决这个问题,但几个小时后我觉得完全卡住了 所以,我对python(我的第二语言)是新手,我正在写一个Dijkstra算法的实现,作为我本科研究的一部分 出于某种奇怪的原因,当我尝试使用unvisited.remove(current)从unvisited集中删除当前节点时,我得到以下错误: Traceback (most recent call last): Current Node: File "H:\DijkstraShortestP

我希望你能帮我解决一些困扰我的问题。我真的试着自己解决这个问题,但几个小时后我觉得完全卡住了

所以,我对python(我的第二语言)是新手,我正在写一个Dijkstra算法的实现,作为我本科研究的一部分

出于某种奇怪的原因,当我尝试使用unvisited.remove(current)从unvisited集中删除当前节点时,我得到以下错误:

Traceback (most recent call last):
Current Node: 
  File "H:\DijkstraShortestPath\src\Main.py", line 92, in <module>
    Unvisited.remove(Current)
ValueError: list.remove(x): x not in list
1
Unvisited Nodes: 
['1', '2', '3', '4', '5', '6', '7', '8']
Current Node: 
8
Unvisited Nodes: 
['2', '3', '4', '5', '6', '7', '8']
回溯(最近一次呼叫最后一次):
当前节点:
文件“H:\DijkstraShortestPath\src\Main.py”,第92行,在
未访问。删除(当前)
ValueError:list。删除(x):x不在列表中
1.
未访问的节点:
['1', '2', '3', '4', '5', '6', '7', '8']
当前节点:
8.
未访问的节点:
['2', '3', '4', '5', '6', '7', '8']
请注意,Current是从列表中提取的值,而Unvisited是列表

在浏览了这里的几个线程并浏览了互联网之后,我决定发布我的全部代码以避免任何混淆。我注意到list.remove(x)在嵌套在循环中时出现了一些问题(我的也嵌套在for循环中),但我不明白所有技术术语下面都发生了什么

有人能给我解释一下为什么这是个问题吗?我能做些什么来修复它

#Main File
#Excecutes the Dijkstra Shortest Path Algorithm

#import Create_Network #Generates Network with 5 OD pairs as replications

testfile = "\DijkstraShortestPath\Backup And Tests\TEST"
Arcfile = testfile + "\Arcs.txt"
ODfile = testfile + "\ODpairs.txt"
Nodefile = testfile + "\Nodes.txt"

#INITIALIZE ALGORITHM
#Populate label, visited, and unvisited sets
#For initial conditions, label is infinite for all nodes except origin
#For initial conditions, all nodes are unvisited (including origin)

LabelArray = [] #Stores the distance labels for each of the nodes; has length
                #equal to the number of nodes in the network
Unvisited = [] #Stores unvisited nodes, by NodeID
Visited = [] #Stores visited nodes, by NodeID
ODArray = [] #Stores Origin and Destination Pairs

#Get the origin and destination pair
with open(ODfile,'r') as f:
    for line in f:
        ODArray = line.strip().split(",")
Origin = ODArray[0]
Destination = ODArray[1]
#Set the first current node as the origin
Current = Origin

#Generate Unvisited nodes and Labels (all infinite, except origin)
with open(Nodefile,'r') as f:
    for line in f:
        LabelArray.append(float("inf")) #make all node distance labels infinite
        NodeID = line.strip().split(",")[0]
        Unvisited.append(NodeID) #Add NodeID to Unvisited

#Set distance for origin to zero
LabelArray[int(ODArray[0])-1] = float(0) #float(0) to match float("inf")

#Count number of lines and items in each line
#i.e., find out how many nodes and params for storage in ArcParams list
numarcs = 0
with open(Arcfile,'r') as f:
    for line in f:
        if line != '\n':
            numarcs = numarcs + 1 #integer
            numparams = len(line.strip().split(",")) #integer

#Store arc origin, destination, length to ArcParams list
ArcParams = [[0 for i in range(numparams)] for i in range(numarcs)]

with open(Arcfile,'r') as f:

    for line in f:
        params = line.strip().split(",")
        ArcParams[int(params[0])-1][0] = params[0]
        ArcParams[int(params[0])-1][1] = params[1]
        ArcParams[int(params[0])-1][2] = params[2]
        ArcParams[int(params[0])-1][3] = float(params[3])

#END INITIALIZATION

#BEGIN DIJKSTRA SHORTEST PATH, LOOPING OVER NODES IN NETWORK

for node in Unvisited:

    #Find the nodes adjacent to Current AND in Unvisited
    Adjacent = []

    for i in range(numarcs):
        if ArcParams[i][1] == Current: #search for origin = current
            if ArcParams[i][1] in Unvisited: #checks if nodes found are in Unvisited
                if ArcParams[i][1] != ArcParams[i][2]: #excludes Current as adjacent
                    Adjacent.append(ArcParams[i][2]) #Add node to Adjacent

    #For each adjacent node, update distance labels

    for node in Adjacent:
        temp = float(LabelArray[int(Current)-1]) + float(ArcParams[int(node)][3])

        if temp < LabelArray[int(node)-1]:
            LabelArray[int(node)-1] = temp

    #Add current node to Visited set
    print "Current Node: "
    print Current
    print "Unvisited Nodes: "
    print Unvisited

    Visited.append(Current)
    Unvisited.remove(Current)

    #Check for end-conditions; has destination entered Visited?
    #Or is the smallest tentative distance infinite? Stop both ways.

    if Destination in Visited:
        if LabelArray[int(Destination)-1] == inf:
            print "There is no feasible path"
        print "Shortest distance found!"
        print "Distance is: " + str(LabelArray[Destination-1])


    #Select the Unvisited node marked with smallest tentative distance
    MinDist = min(LabelArray[1:])
    MinNode = LabelArray.index(MinDist) + 1

    #Clear existing Current, set new Current
    Current = MinNode
#主文件
#执行Dijkstra最短路径算法
#导入创建网络#生成5个OD对作为复制的网络
testfile=“\DijkstraShortestPath\Backup And Tests\TEST”
Arcfile=testfile+“\Arcs.txt”
ODfile=testfile+“\ODpairs.txt”
Nodefile=testfile+“\Nodes.txt”
#初始化算法
#填充标签集、已访问集和未访问集
#对于初始条件,标签对于除原点之外的所有节点都是无限的
#对于初始条件,所有节点均未访问(包括原点)
LabelArray=[]#存储每个节点的距离标签;有长度
#等于网络中的节点数
Unvisited=[]#按节点ID存储未访问的节点
已访问=[]#按节点ID存储已访问的节点
ODArray=[]#存储源和目标对
#获取源和目标对
将open(ODfile,'r')作为f:
对于f中的行:
ODArray=line.strip().split(“,”)
原点=ODArray[0]
目的地=ODArray[1]
#将第一个当前节点设置为原点
电流=原点
#生成未访问的节点和标签(除原点外,所有节点和标签都是无限的)
将open(Nodefile,'r')作为f:
对于f中的行:
LabelArray.append(float(“inf”)#使所有节点距离标签无限大
NodeID=line.strip().split(“,”[0]
Unvisited.append(NodeID)#将NodeID添加到Unvisited
#将原点的距离设置为零
LabelArray[int(ODArray[0])-1]=浮点(0)#浮点(0)匹配浮点(“inf”)
#计算每行中的行数和项目数
#i、 例如,在ArcParams列表中找出要存储的节点和参数的数量
numarcs=0
将open(Arcfile,'r')作为f:
对于f中的行:
如果行!='\n':
numarcs=numarcs+1#整数
numparams=len(line.strip().split(“,”)#整数
#将圆弧起点、终点、长度存储到ArcParams列表
ArcParams=[[0表示范围内的i(numparams)]表示范围内的i(numarcs)]
将open(Arcfile,'r')作为f:
对于f中的行:
params=line.strip().split(“,”)
ArcParams[int(params[0])-1][0]=params[0]
ArcParams[int(params[0])-1][1]=params[1]
ArcParams[int(params[0])-1][2]=params[2]
ArcParams[int(params[0])-1][3]=浮点(params[3])
#结束初始化
#开始DIJKSTRA最短路径,在网络中的节点上循环
对于未访问的节点:
#查找与当前节点相邻且未访问的节点
相邻=[]
对于范围内的i(numarcs):
如果ArcParams[i][1]==当前:#搜索原点=当前
如果ArcParams[i][1]处于未访问状态:#检查找到的节点是否处于未访问状态
如果ArcParams[i][1]!=ArcParams[i][2]:#将电流排除为相邻
append(ArcParams[i][2])#将节点添加到相邻节点
#对于每个相邻节点,更新距离标签
对于相邻节点中的节点:
temp=float(LabelArray[int(当前)-1])+float(ArcParams[int(节点)][3])
如果温度
您的代码基本上是这样做的:

for item in container:
    # stuff
    container.remove(item)
    # more stuff
在遍历容器时修改它通常会破坏代码。Java标准库有一个特定的异常(ConcurrentModificationException),它通常会使您的程序摆脱这种问题,但不幸的是Python没有;你的循环只会做错事

这里的情况有点像一个老笑话,病人:“我这样做很痛。”医生:“不要那样做。”

请尝试以下方法:

container = [6, 7, 8]

while len(container) > 0:
    item = container.pop()
    # do something useful with item
这将首先处理最后使用的项目。例如,第一次迭代会得到8,然后是7,然后是6。如果希望从左向右处理,则应使用collections.deque类:

import collections

container = collections.deque([6, 7, 8])

while len(container) > 0:
    item = container.popleft()
    # do something useful with item
另外,关于您的代码,还有一些风格上的挑剔:

  • 您的代码违反了PEP 8编码风格指南。您的变量应该用单词_命名,并用下划线分隔。他们应该b