So, I do understand depth-first-search is not appropriate for this problem and something like UCS or Astar would be a lot better, just attempting to see if it is possible with a DFS approach.
I need to find a path within a cost budget, my approach using dfs is to keep the cost to get to the next node in the stack as they get pushed, and if going to the next node exceeds, it ignores does not push.
The problem I am facing is that when the budget is exceeded, I am struggling to find a way to set the nodes that have led to this path to be set back as unvisited so newer paths can consider them. I feel it has something to do with setting visited/unvisited properly and have tested a couple but in a bigger graph input, it always fails to find a path within constraint (Have confirmed that it exist using other methods)
def DFS(start, end, budget, adj_list, dist_list, cost_list):
# TODO Depth-First Search
print(f"DFS path from {start} to {end} with budget of {budget}...")
# Set all initial to not visited
visited = [False] * (len(adj_list) + 1)
parent = [None] * (len(adj_list) + 1)
stack = deque()
# Push starting node into the stack
stack.append((start, 0))
parent[start] = -1
path = deque()
pathFound = False
while (len(stack)):
next_node_tup = stack.pop()
next_node = int(next_node_tup[0])
energy_used = next_node_tup[1]
# Found target, proceed to print path
if (next_node == end):
pathFound = True
break
# Set to visited if not yet
# if (not visited[next_node]):
# visited[next_node] = True
# Add all connecting nodes to top of stack
edgeNodes = adj_list[str(next_node)]
#print(f"There are {len(edgeNodes)} nodes connecting to {next_node}")
for node in edgeNodes:
node = int(node)
#print(f"Node {node} connecting to node {next_node}")
if (not visited[node]):
# If taking this node exceeds budget, we dont want it
minipath = str(next_node) + "," + str(node)
print(f"Cost to go from {next_node} to {node} is {cost_list[minipath]}")
energy_if_take = energy_used + cost_list[minipath]
print(f"Energy used if path taken is {energy_if_take}")
if (energy_if_take <= budget):
parent[node] = next_node
stack.append((node, energy_if_take))
visited[node] = True
else:
print(f"Budget exceeded")
# ! Need to set backtracked nodes to not visited
# ! Problem is here!
visited[node] = False
print(stack)
if pathFound:
curr = end
path = []
distance = 0
energy = 0
print("Printing path")
while(curr != -1):
path.append(curr)
if (parent[curr] != -1):
miniPath = str(parent[curr]) + "," + str(curr)
distance += dist_list[miniPath]
energy += cost_list[miniPath]
curr = parent[curr]
# Reverse and print path
path.reverse()
print(*path, sep = " -> ")
print(f"Number of jumps is {len(path)}")
print(f"Distance from {start} to {end} is {distance}")
print(f"Cost from {start} to {end} is {energy}")
else:
print("No path that satisfies budget")
Any hints are suggestions would be appreciated, been stuck here for quite a few days :(