Reputation: 35
{'John': ['Bryant', 'Debra', 'Walter'], 'Bryant': ['Olive', 'Ollie', 'Freda', 'Mercedes'], 'Mercedes': ['Walter', 'Robin', 'Bryant'], 'Olive': ['John', 'Ollie'], 'Debra': ['Walter', 'Levi', 'Jennie', 'Robin'], 'Walter': ['John', 'Levi', 'Bryant'], 'Levi': ['Ollie', 'John', 'Walter'], 'Ollie': ['Mercedes', 'Freda', 'Bryant'], 'Jennie': ['Levi', 'John', 'Freda', 'Robin'], 'Robin': ['Ollie'], 'Freda': ['Olive', 'John', 'Debra']}
This dictionary will be the "network", the input in the path function which contains the users and their corresponding connections.
I have to define a function that finds a connection path from a userA to userB and return the path in a list using recursion. It should also return None if no path exists but I don't know how to achieve that.
Example Input: find_path_to_frind(network,"Levi", "Jennie")
Output: ['Levi', 'Ollie', 'Mercedes', 'Walter', 'John', 'Debra', 'Jennie']
This my attempt but it raises a RecursionError:
def find_path_to_friend(network, user_A, user_B):
path = [user_A]
connections = network[user_A]["is connected to "]
if user_B in connections:
path.append(user_B)
return path
for i in connections:
return find_path_to_friend(network, i, connections)
Upvotes: 1
Views: 637
Reputation: 35
After a day, I finally solved it using recursion but I don't what to do if there is no path found from user_A to user_B.
def find_path_to_friend(network, user_A, user_B):
res = [user_A]
connections = network[user_A]
if user_B in connections:
res.append(user_B)
return res
used = [user_A]
for i in connections:
if user_B in network[i]:
res = res + [i] + [user_B]
used.append(i)
return res
for i in connections:
return res + find_path_to_friend(network,i, user_B)
Upvotes: 0
Reputation: 803
Here is my solution with BFS
. You can also write recursive programs for that but as BFS
is not usually implemented recursively, I wrote it this way. But if you insist on recursion, I can change it:
from collections import defaultdict
def find_path_to_friend(network, src, dest):
queue = [src]
visited = defaultdict(bool)
path = []
while len(queue) != 0:
node = queue.pop(0)
path.append(node)
visited[node] = True
if node in network:
for adj in network[node]:
if adj == dest:
return path + [dest]
if not visited[adj]:
queue.append(adj)
return None
network = {'John': ['Bryant', 'Debra', 'Walter'], 'Bryant': ['Olive', 'Ollie', 'Freda', 'Mercedes'], 'Mercedes': ['Walter', 'Robin', 'Bryant'], 'Olive': ['John', 'Ollie'], 'Debra': ['Walter', 'Levi', 'Jennie', 'Robin'], 'Walter': ['John', 'Levi', 'Bryant'], 'Levi': ['Ollie', 'John', 'Walter'], 'Ollie': ['Mercedes', 'Freda', 'Bryant'], 'Jennie': ['Levi', 'John', 'Freda', 'Robin'], 'Robin': ['Ollie'], 'Freda': ['Olive', 'John', 'Debra']}
print(find_path_to_friend(network, 'John', 'Freda'))
# ['John', 'Bryant', 'Freda']
Here is the recursive approach to eliminate the outer for loop
in BFS:
def find_path_to_friend(network, src, dest):
visited = defaultdict(bool)
def rec(queue):
if len(queue) == 0:
return []
node = queue.pop(0)
path = [node]
visited[node] = True
if node in network:
for adj in network[node]:
if adj == dest:
return path + [dest]
if not visited[adj]:
queue.append(adj)
return path + rec(queue)
queue = [src]
return rec(queue)
Upvotes: 3