0

I'm currently a student and am working on a small project. My aim is to be able to determine the shortest path between two given cities, but with the condition that one needs to go through a specified number of other cities (or as you might have understood, a certain number of nodes as I'm working with a graph). I have already coded most of the program following the basic headlines of dijkstra's algorithm (which is the only one I am allowed to use), but find myself unable to specify the number of nodes that it needs to go through, does one of you have any idea of how I might do it?

import sys
def shortestpath(graph,start,end,visited=[],distances={},predecessors={}):
"""Find the shortest path between start and end nodes in a graph"""
# we've found our end node, now find the path to it, and return
if start==end:
    path=[]
    while end != None:
        path.append(end)
        end=predecessors.get(end,None)
    return distances[start], path[::-1]
# detect if it's the first time through, set current distance to zero
if not visited: distances[start]=0
# process neighbors as per algorithm, keep track of predecessors
for neighbor in graph[start]:
    if neighbor not in visited:
        neighbordist = distances.get(neighbor,sys.maxsize)
        tentativedist = distances[start] + graph[start][neighbor]
        if tentativedist < neighbordist:
            distances[neighbor] = tentativedist
            predecessors[neighbor]=start
# neighbors processed, now mark the current node as visited
visited.append(start)
# finds the closest unvisited node to the start
unvisiteds = dict((k, distances.get(k,sys.maxsize)) for k in graph if k not in visited)
closestnode = min(unvisiteds, key=unvisiteds.get)
# now we can take the closest node and recurse, making it current
return shortestpath(graph,closestnode,end,visited,distances,predecessors)

if __name__ == "__main__":
graph = {'Paris':       {               'Marseille': 773,   'Lyon': 464,    'Toulouse': 677,    'Nice': 930,    'Nantes': 383,  'Angers': 294,      'Strasbourg': 492},
        'Marseille':    {'Paris': 773,                      'Lyon': 314,    'Toulouse': 403,    'Nice': 207,    'Nantes': 985,  'Angers': 905,      'Strasbourg': 802},
        'Lyon':         {'Paris': 464,  'Marseille': 314,                   'Toulouse': 537,    'Nice': 471,    'Nantes': 685,  'Angers': 596,      'Strasbourg': 493},
        'Toulouse':     {'Paris': 677,  'Marseille': 403,   'Lyon': 537,                        'Nice': 561,    'Nantes': 585,  'Angers': 642,      'Strasbourg': 969},
        'Nice':         {'Paris': 930,  'Marseille': 207,   'Lyon': 471,    'Toulouse': 561,                    'Nantes': 1143, 'Angers': 1063,     'Strasbourg': 785},
        'Nantes':       {'Paris': 383,  'Marseille': 985,   'Lyon': 685,    'Toulouse': 585,    'Nice': 1143,                   'Angers': 91,       'Strasbourg': 866},
        'Angers':       {'Paris': 294,  'Marseille': 905,   'Lyon': 596,    'Toulouse': 642,    'Nice': 1063,   'Nantes': 91,                       'Strasbourg': 777},
        'Strasbourg':   {'Paris': 492,  'Marseille': 802,   'Lyon': 493,    'Toulouse': 969,    'Nice': 785,    'Nantes': 866,  'Angers': 777}}
  • Hmm.. To specify how many other cities you must pass through on the way to the destination, I would guess you would need to keep a paths tree of every possible route (or at least one route for each number of intermediate visits) from startpoint to endpoint. This would be pretty inefficient, but doable. Someone else may have a better way. – Deem Apr 29 '17 at 23:52
  • Are you allowed to go through cities twice? Getting to the target in N steps is a lot easier than ensuring that you visit N *unique* cities on the way. – Matt Timmermans Apr 30 '17 at 03:32
  • @Windmill And do you have any idea on how to do what you propose or not? Because I am quite the beginner... – CelsiusOrKelvin May 01 '17 at 10:02
  • @MattTimmermans Well going through the same cities wouldn't be very interesting as the point is like doing a tour of the country! – CelsiusOrKelvin May 01 '17 at 10:03

0 Answers0