I have a list of tuples of the form:
data = [(\'Abe\', \'Bob\', \'3\'),
(\'Abe\', \'Frank\', \'5\'),
(\'Abe\', \'George\', \'4\'),
(
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 = False
for first, second, weight in data:
for path in paths:
candidate = None
if (first in path[NODES]) and (second not in path[NODES]):
candidate = second
elif (first not in path[NODES]) and (second in path[NODES]):
candidate = first
if candidate:
new_path = list(path)
new_path.append(candidate)
new_path[WEIGHT] += weight
if new_path not in paths:
paths.append(new_path)
added = True
for path in sorted(paths):
if end in path[NODES]:
return path
return None
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")