Posts: 6
Threads: 3
Joined: Jan 2024
Jan-27-2024, 09:45 AM
(This post was last modified: Jan-27-2024, 10:49 AM by nkiki.)
(V, E) be a graph and two vertices s and t. B ⊆ V be some set of vertices. How many vertices of the set B can there be at maximum on a shortest path from s to t? there may be several such paths. finding answer using python
code doesn't handle scenarios for multiple shortest paths from s to t. only considering first path found and returns the count for that path. code increments the count for vertices in set B inside the loop for neighbors. counting should be done only when the neighbor is in B and has not been visited before.
def max_vertices_in_shortest_path(G, s, t, B):
V, E = G
# Initialize the count array with all elements set to -1
count = [-1 for _ in range(len(V))]
# Initialize the queue with the starting vertex
queue = [s]
# Mark the starting vertex as visited
count[s] = 0
while queue:
current = queue.pop(0)
for neighbor in E[current]:
if count[neighbor] == -1:
count[neighbor] = count[current]
if neighbor in B:
count[neighbor] += 1
queue.append(neighbor)
return count[t] # Example usage:
V = [0, 1, 2, 3, 4, 5]
E = {0: [1, 2], 1: [3], 2: [3], 3: [4, 5], 4: [5], 5: []}
G = (V, E)
s = 0
t = 5
B = {1, 2, 4}
result = max_vertices_in_shortest_path(G, s, t, B)
print(result)
Posts: 1,093
Threads: 143
Joined: Jul 2017
Explain some more, a picture says a thousand words!
Maybe some examples for the various variables would clarify matters somewhat!
Posts: 6
Threads: 3
Joined: Jan 2024
Jan-27-2024, 10:51 AM
(This post was last modified: Jan-27-2024, 10:51 AM by nkiki.)
(V, E) be a graph and two vertices s and t. B ⊆ V be some set of vertices. How many vertices of the set B can there be at maximum on a shortest path from s to t? there may be several such paths. finding answer using python
code doesn't handle scenarios for multiple shortest paths from s to t. only considering first path found and returns the count for that path. code increments the count for vertices in set B inside the loop for neighbors. counting should be done only when the neighbor is in B and has not been visited before
def max_vertices_in_shortest_path(G, s, t, B):
V, E = G
# Initialize the count array with all elements set to -1
count = [-1 for _ in range(len(V))]
# Initialize the queue with the starting vertex
queue = [s]
# Mark the starting vertex as visited
count[s] = 0
while queue:
current = queue.pop(0)
for neighbor in E[current]:
if count[neighbor] == -1:
count[neighbor] = count[current]
if neighbor in B:
count[neighbor] += 1
queue.append(neighbor)
return count[t] # Example usage:
V = [0, 1, 2, 3, 4, 5]
E = {0: [1, 2], 1: [3], 2: [3], 3: [4, 5], 4: [5], 5: []}
G = (V, E)
s = 0
t = 5
B = {1, 2, 4}
result = max_vertices_in_shortest_path(G, s, t, B)
print(result)
Posts: 6,785
Threads: 20
Joined: Feb 2020
You need to find all possible paths, get the shortest path, report all paths that are that length. I think recursion would be a good choice for this problem. A recursive solution would start at t, pick a neighboring node, add the node to the path and call itself using the neighboring node as the start. When the search function picks a neighbor that is t, add the path to the list of paths, unwind to the previous recursion and pick the next neighbor. Your function should only allow moving to neighboring nodes that are not in the current path. You might also want to keep track of the shortest path. If a path exceeds the shortest path, there is no reason continuing along that path.
Posts: 4,786
Threads: 76
Joined: Jan 2018
I think you could also find the shortest path from s to t in a graph where the edges are weighted. If you give the weight 1 to edge a -> b when b is not in B and weight 1 - x if b is in B, where x = 1 / (1 + len(B)) .
I think a shortest path in this modified problem is a shortest path of the initial problem containing a maximal number of elements of B.
« We can solve any problem by introducing an extra level of indirection »
Posts: 6,785
Threads: 20
Joined: Feb 2020
I find this confusing.
Quote:I think a shortest path in this modified problem is a shortest path of the initial problem containing a maximal number of elements of B.
I also find the initial description confusing.
So compiled a list of paths from 0 to 5
0 1 3 4 5
0 1 3 5
0 2 3 4 5
0 2 3 5
Paths with the maximum number of nodes in B {1, 2, 4} are 0, 1, 3, 4, 5 and 0, 2, 3, 4, 5 which both include 2 nodes from B.
Shortest paths are 0, 1, 3, 5 and 0, 2, 3, 5, but they each only include 1 node from B.
So what is more important, minimum length or maximum inclusion?
Posts: 4,786
Threads: 76
Joined: Jan 2018
Jan-28-2024, 08:50 AM
(This post was last modified: Jan-28-2024, 08:53 AM by Gribouillis.)
(Jan-27-2024, 11:51 PM)deanhystad Wrote: I find this confusing.
I think a shortest path in this modified problem is a shortest path of the initial problem containing a maximal number of elements of B. I mean that a path from s to t with minimal sum of weights in the modified problem is also
- A shortest path from s to t in the initial graph
- Among these shortest paths, a path that contains a maximal number of elements of B.
« We can solve any problem by introducing an extra level of indirection »
Posts: 1,093
Threads: 143
Joined: Jul 2017
I'm confused about what you wish to achieve. Maybe you could be clearer.
I don't know why you want all those variables, you have enough with E: E.keys() = V, G is redundant, as are s and t
E = {0: [1, 2], 1: [3], 2: [3], 3: [4, 5], 4: [5], 5: []}
Starting with count = [0, -1, -1, -1, -1, -1] and queue = [0]
queue = [0]
for key in E.keys(): # E.keys() = V
# current = key
print(f'key is {key}')
for neighbour in E[key]: # starts as [1, 2]
print(f'neighbour is {neighbour}')
# count was defined as [0, -1, -1, -1, -1, -1] so first key = 0 will be skipped
if count[neighbour] == -1: # all count[key] begin life as -1, count[s] later defined as 0
print(f'count[neighbour] is {count[neighbour]}')
count[neighbour] = count[key] # count[current] = 0, count[s] = 0 # s defined as 0
print(f'count[neighbour] now is {count[neighbour]}')
if neighbour in B: # B = {1, 2, 4} 1, 2 and 4 are in B
print(f'neighbour = {neighbour} and {neighbour} is in {B}')
count[neighbour] += 1
print(f'count[neighbour] = {count[neighbour]}')
queue.append(neighbour)
print(f'queue now is {queue}') Output: count
[0, 1, 1, 1, 2, 1]
I am not sure what you want the while loop to do!
Posts: 6,785
Threads: 20
Joined: Feb 2020
Generating a list of all paths is easy using recursion.
def walk(nodes, target, path, all_paths):
"""Walk nodes looking for target. When found, add path to list of all paths""".
if path[-1] == target:
all_paths.append(path.copy())
else:
for node in nodes.get(path[-1], []):
if node not in path:
path.append(node)
walk(nodes, target, path, all_paths)
path.pop(-1)
Posts: 4,786
Threads: 76
Joined: Jan 2018
Jan-28-2024, 05:58 PM
(This post was last modified: Jan-28-2024, 05:59 PM by Gribouillis.)
I once posted an implementation of Dijkstra algorithm that solves the problem.
« We can solve any problem by introducing an extra level of indirection »
|