[Python-de] dijkstra algorithmus
sackbard
sackbard at googlemail.com
Sa Feb 18 18:16:46 CET 2012
Hallo Python Community,
bin neu in der Liste und hab natürlich gleich eine Frage. Ich versuche
den dijkstra algorithmus in Python zu implementieren. Gegeben sind zwei
Dateien: die network.txt die die distanzen der einzelnen nodes angibt
und die route.txt die mir anfangs und endpunkt ausgibt.
Beispiel network.txt (in diesem Beispiel nodes A-G):
0,2,4,1,6,0,0
2,0,0,0,5,0,0
4,0,0,0,0,5,0
1,0,0,0,1,1,0
6,5,0,1,0,5,5
0,0,5,1,5,0,0
0,0,0,0,5,0,0
Beispiel route.txt:
B>F
Am ende soll eine neue txt datei erstellt werden welche die route und
die total path length enthält.
Bis auf den letzten Schritt funktioniert auch alles soweit (python 3.1.1). Ich bin nur
noch nicht dahinter gekommen wie ich am Ende am besten die Route und die
Total path length berechne. Hatte überlegt den weg vom letzten zum
ersten node einfach zurückzugehen aber das scheint mir umständlich und
kompliziert.
Hier das script soweit ich das hinbekommen habe:
import sys
invalid_node = -1
class Node:
previous = invalid_node
distFromSource = sys.maxsize
visited = False
#print ("\nReading the file into a list.")
txtfile = open("network.txt", "r")
numberOfNodes = 0
network = [] # array containing array of values for each line
# reading file line by line
for line in txtfile:
# increment nodeCount
numberOfNodes += 1
# remove end chars
line = line.replace("\n","")
line = line.replace("\r","")
# split by comma
chars = line.split(",")
ints = []
# convert string to int
for char in chars:
ints.append(int(char))
# append the list of ints to the array
network.append(ints)
# read start (dist value = 0) and end node
route = open("route.txt", "r")
for line in route:
nodes = line.split(">")
startNode = nodes[0]
endNode = nodes[1]
# get the ascii value and minus 65
startNode =(ord(startNode) - 65)
endNode =(ord(endNode) - 65)
#print ("Start node: " + str(startNode))
#print ("End node: " + str(endNode))
# set currentNode to startNode
currentNode = startNode
# create another 2d array with previous node, distFromSource and visited
# use sys.maxint for distFromSource
nodeTable = [] # array containing nodeTable visited/unvisited,prevNode
and distFromSrc
i = 0
while i <= numberOfNodes:
nodeTable.append(Node())
i += 1
# set distFromSource of startNode to 0
nodeTable[startNode].distFromSource = 0
nodeTable[startNode].visited = True
#write a function to find the neighbour of current node
def findNeighbours(currentNode):
# find nearest neighbour of currentNode
currentRow = network[currentNode]
currentNeighbours = []
i = 0
for distance in currentRow:
#get back the index number / position if distance = 0
if distance != 0:
#save the location
currentNeighbours.append(i)
i += 1
return currentNeighbours
#print ("\nCurrent Neighbours (of node " + str(currentNode) + "): ")
currentNeighbours = findNeighbours(currentNode)
#print (currentNeighbours)
# go through currentNeighbour and see if they have been visited or not
# set dustFromSource and previousNode for unvisited
def checkNeighbours():
for neighbour in currentNeighbours:
if nodeTable[neighbour].visited == True:
pass
#print ("True")
else:
# calculate their tentative distances from starting node
# add distFromSource from currentNode with distance between
currentNode and neighbour
# check if less than current
newDistance = nodeTable[currentNode].distFromSource +
network[currentNode][neighbour]
if (nodeTable[neighbour].distFromSource > newDistance):
nodeTable[neighbour].distFromSource = newDistance
nodeTable[neighbour].previous = currentNode
checkNeighbours()
#printNodeTb()
# go through all distances of unvisited, find lowest and mark as visited
def setNewCurrentNode():
global currentNode
index = 0
currentDist = sys.maxsize
for node in nodeTable:
if node.visited == False and node.distFromSource < currentDist:
currentNode = index
currentDist = node.distFromSource
index+=1
nodeTable[currentNode].visited = True
print ("\nNew Current Node: " + str(currentNode))
setNewCurrentNode()
#total path length
tpl = 0
f = open("09023429spf.txt", "w")
f.write(str(chr(startNode+65)))
# check if destination node reached
while currentNode != endNode:
#print ("\nCurrent Neighbours (of node " + str(currentNode) + "): ")
currentNeighbours = findNeighbours(currentNode)
#print (currentNeighbours)
checkNeighbours()
f.write(str(chr(currentNode+65)))
setNewCurrentNode()
#add total path length
tpl += nodeTable[nodeTable[currentNode].previous].distFromSource
f.write(str(chr(endNode+65)))
f.write(" " + str(tpl))
f.close()
print ("\nTotal path length: " + str(tpl) + "\n")
for node in nodeTable:
print (str(node.previous) + " | " + str(node.distFromSource) + " | "
+ str(node.visited))
Wäre für jede Hilfe dankbar.
Dankeschön.
Gruß
Andi
Mehr Informationen über die Mailingliste python-de