'Djisktra algo implementation returning array of all same values
This is a solution to city problem, where cities have at most 1 train station and 1 bus station, some cities have both. and from a starting city i will be finding all the shortest paths to other cities. For that I am running this code and trying to get the all shortest paths from every city, but without the recursion i get this object down below.
visitedCities = []
Cities = {"Istanbul" : 0, "Bursa" : 0, "Eskisehir" : 0}
totalCostsSaved = {"Istanbul" : Cities, "Bursa" : Cities, "Eskisehir" : Cities}
#To find Quickest Itenaries from city, just set these variables Istanbul-Bus instead of istanbul-harem for example
startCity = "Istanbul" #City C
startStation = "Bus" #Station of City
StationAverageTimeChange = { "Istanbul" : 30, "Eskisehir" : 10}
Bus = { "Istanbul-Bursa" : 100, "Bursa-Eskisehir" : 120 }
Train = { "Istanbul-Eskisehir" : 180 }
CitiesWithTrain = ["Istanbul", "Eskisehir"]
CitiesWithBus = ["Istanbul", "Bursa", "Eskisehir"]
def getCostToDestination(currentCity, currentStation, currentCost):
for city in totalCostsSaved.keys():
newCities = Cities
if currentCity == city:
continue
if currentStation == "Bus" and currentCity in CitiesWithTrain: #check if trainStationExists
for cityPairs in Train.keys():
if currentCity in cityPairs.split("-"):
for cit in cityPairs.split("-"):
if cit != currentCity:
costToNewCity = currentCost + Train[cityPairs] + StationAverageTimeChange[currentCity]
if totalCostsSaved[currentCity][cit] == 0 or costToNewCity < totalCostsSaved[currentCity][cit]:
totalCostsSaved[currentCity][cit] = costToNewCity
if cit not in visitedCities:
visitedCities.append(cit)
for cityPairs in Bus.keys():
if currentCity in cityPairs.split("-"):
for cit in cityPairs.split("-"):
if cit != currentCity:
costToNewCity = currentCost + Bus[cityPairs]
if totalCostsSaved[currentCity][cit] == 0 or costToNewCity < totalCostsSaved[currentCity][cit]:
totalCostsSaved[currentCity][cit] = costToNewCity
if cit not in visitedCities:
visitedCities.append(cit)
if currentStation == "Train" and currentCity in CitiesWithBus: #check if bus
for cityPairs in Bus.keys():
if currentCity in cityPairs.split("-"):
for cit in cityPairs.split("-"):
if cit != currentCity:
costToNewCity = currentCost + Bus[cityPairs] + StationAverageTimeChange[currentCity]
if totalCostsSaved[currentCity][cit] == 0 or costToNewCity < totalCostsSaved[currentCity][cit]:
totalCostsSaved[currentCity][cit] = costToNewCity
if cit not in visitedCities:
visitedCities.append(cit)
for cityPairs in Train.keys():
if currentCity in cityPairs.split("-"):
for cit in cityPairs.split("-"):
if cit != currentCity:
costToNewCity = currentCost + Train[cityPairs]
if totalCostsSaved[currentCity][cit] == 0 or costToNewCity < totalCostsSaved[currentCity][cit]:
totalCostsSaved[currentCity][cit] = costToNewCity
if cit not in visitedCities:
visitedCities.append(cit)
getCostToDestination(startCity, startStation, 0)
print(totalCostsSaved)
When I run this, I get
{'Istanbul': {'Istanbul': 0, 'Bursa': 100, 'Eskisehir': 210}, 'Bursa': {'Istanbul': 0, 'Bursa': 100, 'Eskisehir': 210}, 'Eskisehir': {'Istanbul': 0, 'Bursa': 100, 'Eskisehir': 210}}
But I am supposed to get
{'Istanbul': {'Istanbul': 0, 'Bursa': 100, 'Eskisehir': 210}, 'Bursa': {'Istanbul': 0, 'Bursa': 0, 'Eskisehir': 0}, 'Eskisehir': {'Istanbul': 0, 'Bursa': 0, 'Eskisehir': 0}}
How do I fix this, if i do recursive they all have the same values whereas they should be different.
Solution 1:[1]
The reason you are getting that result is because you are using the dictionary Cities as the value to each key in the totalCostsSaved dict, and since a dict is a mutable object updating one updates them all.
totalCostsSaved = {"Istanbul" : Cities, "Bursa" : Cities, "Eskisehir" : Cities}
For Example:
If you were to: totalCostsSaved['Istanbul']['Bursa'] = 100
That assignment will also adjust totalCostsSave['Bursa']['Bursa'] and totalCostsSave['Eskiesehir']['Bursa'] because they all using the same shared dictionary..
One way to avoid this would be to create new dictionaries for each key. For example:
totalCostsSaved = {
"Istanbul" : {
"Istanbul" : 0,
"Bursa" : 0,
"Eskisehir" : 0
},
"Bursa" : {
"Istanbul" : 0,
"Bursa" : 0,
"Eskisehir" : 0
},
"Eskisehir" : {
"Istanbul" : 0,
"Bursa" : 0,
"Eskisehir" : 0
}
}
Another way would be to make unique copy them:
from copy import copy
totalCostsSaved = {
"Istanbul" : copy(Cities),
"Bursa" : copy(Cities),
"Eskisehir" : copy(Cities)
}
Both of these options creates a unique dictionary so when updating the values it will not effect the others.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
