Skip to content Skip to sidebar Skip to footer

Find Path From A List Of Tuples In Python

I have a list of tuples of the form: data = [('Abe', 'Bob', '3'), ('Abe', 'Frank', '5'), ('Abe', 'George', '4'), ('Carl', 'Bob', '1'), ('Dan', 'Car

Solution 1:

There are several packages that are already developed and debugged that do this, e.g., networkx

import networkx as nx

data = [('Abe', 'Bob', '3'), 
        ('Abe', 'Frank', '5'),
        ('Abe', 'George', '4'),
        ('Carl', 'Bob', '1'),
        ('Dan', 'Carl', '2')]

g = nx.Graph()
for e indata:
    g.add_edge(e[0], e[1], distance=int(e[2]))
>>> nx.shortest_path(g, 'Abe', 'Bob', 'distance'), nx.shortest_path_length(g, 'Abe', 'Bob', 'distance')
(['Abe', 'Bob'], 3)

Solution 2:

You could generate all the possible paths, and sort them by weight. Note I've changed the weights in the data to be numbers, not strings:

data = [
    ('Abe', 'Bob', 3), 
    ('Abe', 'Frank', 5),
    ('Abe', 'George', 4),
    ('Carl', 'Bob', 1),
    ('Dan', 'Carl', 2),
]

WEIGHT =0
NODES = slice(1, None)

def get_path_and_weight(data, start, end):

    paths = [[0, start]]
    added =True

    while added:
        added =Falseforfirst, second, weight in data:
            for path in paths:
                candidate =None

                if (firstin path[NODES]) and (secondnotin path[NODES]):
                    candidate =second
                elif (firstnotin path[NODES]) and (secondin path[NODES]):
                    candidate =first

                if candidate:
                    new_path = list(path)
                    new_path.append(candidate)
                    new_path[WEIGHT] += weight

                    if new_path notin paths:
                        paths.append(new_path)
                        added =Truefor path in sorted(paths):
        if endin path[NODES]:
            return path

    returnNone

You can then call this something like:

weight, *path = get_path_and_weight(data, "Abe", "Dan")

print(path, "with weight", weight)

Gives the result:

['Abe', 'Bob', 'Carl', 'Dan'] with weight 6

And since it returns a path or None, you can still use it as predicate function as well:

if get_path_and_weight(data, "Abe", "Dan"):
    print("connected")

Solution 3:

defget_rpath_with_weight(data,start,end):
    rpath = []
    reachable=False
    nxt_dst = start
    weight_ = 0
    rpath.append(nxt_dst)
    for datum in data:
        if nxt_dst in datum:
            #print datum
            fm_ = datum[0]
            to_ = datum[1]
            weight_ = weight_ + int(datum[2])
            if fm_ == nxt_dst:
               nxt_dst = to_
            else:
               nxt_dst = fm_
            if nxt_dst == end:
               reachable=True
            rpath.append(nxt_dst)
    print rpath,weight_,reachable


get_rpath_with_weight(data,'Abe','Dan')

get_rpath_with_weight(data,'Dan','Frank')

Sample Output

['Abe', 'Bob', 'Carl', 'Dan']6 True
['Dan', 'Carl']2 False

Above example can may get path and determine if reachable, but I think you need to further enhance it to handle multiple paths too.

Post a Comment for "Find Path From A List Of Tuples In Python"