请帮助我,我真的很绝望,我不知道该怎么做。
所以我们在大学里完成了在python中编程dijkstra算法的任务。
INVALID_NODE = -1 #Define the initial variables to -1 and a very high number.
INFINITY = 1000000
#A = 0, B = 1, C = 2, D = 3, E = 4, F = 5, G = 6
#network[0][1] is the cell that contains edge value for going from A to B
class Node:
previous = INVALID_NODE #With each node created, define it's initial variables to -1 and a very high number.
distFromSource = INFINITY
visited = False #Every node except starting node should be univisited by default.
def populateNetwork(filename):
network = [] #Create an empty array to store the network file.
networkfile = open(filename, "r") #Open the network file.
for line in networkfile: #For every line in network file, remove \n's and split the data on every comma, then add everything to the array.
line = line.replace("\n","")
line = line.split(',')
line = map(int, line)
network.append(line)
return network
def populateNodeTable(network, startNode): #Populate the nodeTable with node objects based on the network file.
nodeTable = []
for node in network:
nodeTable.append(Node())
nodeTable[startNode].distFromSource = 0 #Initialize the startNode distance from source and mark it as visited.
nodeTable[startNode].visited = True
return nodeTable
def findNeighbours(network, nodeTable, currentNode): #Function to find neighbours of the currentNode.
nearestNeighbour = [] #Empty array to store neighbour indexes.
columnIndex = 0
for entry in network[currentNode]: #check each node if it has a link to the currentNode and if it's unvisited, if both are true, add to the array.
if entry != 0 and nodeTable[columnIndex].visited == False:
nearestNeighbour.append(columnIndex)
columnIndex += 1
return nearestNeighbour
def calculateTentative(network, nodeTable, currentNode, nearestNeighbours):
#Calculate the distance from currentNode to each node in neighborous list
#Work out distance from source for each node
#If lower than current entry in nodeTable for that node, update
for neighbour in nearestNeighbours:
tentativeDistance = nodeTable[currentNode].distFromSource + network[currentNode][neighbour]
if nodeTable[neighbour].distFromSource > tentativeDistance:
nodeTable[neighbour].distFromSource = tentativeDistance
nodeTable[neighbour].previous = currentNode
return nodeTable
def findNextNode(nodeTable): #Find the next node from the neighbouring nodes with the lowest distFromSource.
currentDistance = INFINITY
nodeIndex = 0
currentNode = INVALID_NODE
for node in nodeTable: #If it's distFromSource is less than distFromSource of the currentNode, make it the currentNode.
if(node.distFromSource < currentDistance) and (node.visited == False):
currentNode = nodeIndex
currentDistance = node.distFromSource
nodeIndex += 1
return currentNode
####################
#Pseudocode from the internet for reference
#function Dijkstra(network, start):
# for each node v in network:
# distFromSource[v]:=infinity #initial distance from source to vertex v is set to infinite
# previous[v]:=undefined (-1) #previous node in optimal path from source
#
# distFromSource[source]:= 0 #distance from source to source
# Q:= the set of all nodes in Graph #all nodes in the graph are unoptimized - thus are in Q
#
# while Q is not empty: #main loop
# u:=node in Q with smallest dist[]
# remove u from Q
#
# for each neighbour v of u: #where v has not yet been removed from Q
# alt:=dist[u] + dist_between(u,v)
# if alt < dist[v]
# dist[v]:=alt #relax(u,v)
# previous[v]:=u
# return previous[]
#
####################
#Files
network = populateNetwork("network.txt") #Populate the network array with network defined in netwowrk.txt file.
routefile = "route.txt" #Load the route information.
letters = ["A", "B", "C", "D", "E",
"F", "G", "H", "I", "J", "K", "L", #Array of letters for easy conversion between integers and letters.
"M", "N", "O", "P", "Q", "R", "S",
"T", "U", "V", "W", "X", "Y", "Z"]
options = { "A": 0, "B": 1, #Dictionary to convert the initial route file to integers for much easier manipulation
"C": 2, "D": 3, #within the program.
"E": 4, "F": 5,
"G": 6, "H": 7,
"I": 8, "J": 9,
"K": 10, "L": 11,
"M": 12, "N": 13,
"O": 14, "P": 15,
"Q": 16, "R": 17,
"S": 18, "T": 19,
"U": 20, "V": 21,
"W": 22, "X": 23,
"Y": 24, "Z": 25,
}
####################
#Initial data and initialisation
print("Network file:") #Print the entire network.txt file to the screen line by line.
itr = 0 #Iterator for line labeling.
for line in network:
print(letters[itr], ".", line) #Prints letters associated with each node.
itr = itr + 1
with open(routefile, "r") as rfile: #Open route.txt and split it into two variables.
routeData = rfile.read().split(">")
routeData[0] = routeData[0].rstrip("\n") #Strip route data from additional \n's that can occur at the end of the file.
routeData[1] = routeData[1].rstrip("\n")
startNode = options[routeData[0]] #Save both numbers as start and end nodes.
endNode = options[routeData[1]]
print("\nRoute:\n%s to %s\n" %(letters[startNode], letters[endNode])) #Print start and end nodes to the user to make sure that
#the file was loaded correctly.
#Populate node table with the network data and starting node.
currentNode = startNode #Initialize currentNode to the start node.
print("Starting node: %s\nDestination node: %s" %(network[startNode], network[endNode])) #Prints the starting and end nodes.
####################
nodeTable = populateNodeTable(network, currentNode) #Populates nodeTable with node objects from the network.
while currentNode is not endNode: #While loop running as long as the currentNode isn't the destination.
neighbours = findNeighbours(network, nodeTable, currentNode) #Examine neighbours of the currentNode.
nodeTable = calculateTentative(network, nodeTable, currentNode, neighbours) #Calculate tentative distances for the neighbours of the currentNode.
nodeTable[currentNode].visited = True #Mark current node as visited.
currentNode = findNextNode(nodeTable) #Jump to the next neighbour.
#print "\nChecking node: " #Print node the program is currently working on.
#print letters[currentNode]
####################
#New variable for the while loop.
routeList = [] #Array to store final route data.
routeList.append(letters[currentNode]) #Add the final node to the array.
while currentNode is not startNode: #Add all the nodes used in the final travel to the array using the nodetable[i].previous variable.
routeList.append(letters[nodeTable[currentNode].previous])
currentNode = nodeTable[currentNode].previous
print("\nShortest route between start and end nodes: ")
for entry in reversed(routeList): #Print the array backwards for more intuitive output.
print(entry,)
print("\n\nTotal distance traveled:",) #Print the total distance traveled.
print(nodeTable[endNode].distFromSource)
####################
#Utility
print("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") #separator line for easier debugging
我是在我的笔记本电脑上做的(它正在运行debian)并且它运行得非常好,脚本正在做它应该做的事情并给我正确的输出。
当我运行时,它说:
TypeError: 'map' object is not subscriptable
但问题是:我在3小时内得到了它,我现在要上传它,我尝试在台式机(Windows 10)上运行它,以确保我得到了正确的文件。
但它正在表现并且它吐出一个错误我完全不知道它是什么因为我只是python的初学者,这是我第一次使用它...
请帮帮我!我试图找出为什么它不能在Windows上工作,但这超出了我的知识。
虽然它在Linux上100%正常工作......
请帮助我,即使我做了所有工作,我也真的不想让模块失败......
答案 0 :(得分:2)
- line = map(int, line)
# in Python 3+ you will get the map object <map object at 0x.....>
+ line = list(map(int, line))
答案 1 :(得分:1)
尝试使用line.strip()
代替line = line.replace("\n","")
。
Windows行结尾是&#39; \ r \ n&#39; ...
答案 2 :(得分:1)
Python 3,map()
返回一个地图对象,见:
x=[1,2,4,5,6,7,8,8,9]
y = map(str,x)
z=[]
z.append(y)
print(z)
#[<map object at 0x7f1e65205ac8>]
在Python 2中,您可以获得相同的代码:
#[['1', '2', '4', '5', '6', '7', '8', '8', '9']]
解决方案,在Python 3中将地图对象转换回列表。此解决方案也适用于Python 2,并且它向后兼容:
x=[1,2,4,5,6,7,8,8,9]
y = map(str,x)
z=[]
z.append(list(y))
print(z)
#[['1', '2', '4', '5', '6', '7', '8', '8', '9']]