To Detect A Cycle Why Do I need a Visited List and A stack? - depth-first-search

Why would just not having a visited set like this work to detect a cycle?

Related

Fastest Continual Cycle Detection

I'm trying to build a directed graph implementation that I can add and delete nodes/edges from, and I can query whether any node participates in a cycle. By participate I mean that there exists a path from that node back to itself. Right now, whenever I query a single node, I have to run DFS on that node, and if I can reach the node again, then I return. However, I want to expand my query function by allowing for the user to query multiple nodes at once, so I want to use something more sophisticated than simply running DFS multiple times. Does anybody have any suggestions?
To anybody out there, I ended up using Tarjan's Strongly Connected Component algorithm. I kept track of which nodes were visited during each run through of the algorithm, and if I queried a node that was already visited, I would skip that node. Eventually, for a single query, I visited each node in the graph at most once.

Graph traversal using every edge

I have a state diagram where each state has a list of other states it can visit. My goal is to generate as many paths as necessary from state Open to state Closed such that every state transition is used.
I'm currently thinking of converting my state table into a graph, then using a graph traversal algorithm to generate my paths.
Problem is, I don't know if an algorithm exists to fit my exact scenario. I was looking at Eulerian paths, which hit every edge only once if possible. This is not ideal because there are multiple nodes that only have a way in and no way out.
Then, I was thinking of using Bellman Ford to generate paths to these closed nodes, and removing edges used in these paths and running it again.
Hopefully I described the problem well enough, let me know if there's something I can do. Thanks.

Breadth first search with fixed stopping distance

I'm looking at a graph problem where I'm given a source node and need to find all other nodes up to a fixed distance away, where each edge between nodes has a uniform cost. So I've implemented a breadth first search using the standard FIFO queue technique, but stopping the BFS at a fixed distance is causing me problems.
If I were using DFS, I could pass in the current depth with each recursive call, but I can't do that here. I cannot modify the nodes of the graph to keep an extra parameter (distance) either. Any suggestions or references?
Just use two queues and bounce back and forth between them. Every time you switch from one to the other, increment your depth count by one.
To elaborate...
Maintain an "active" queue and an "inactive" queue.
Pop a node from the active queue. Add its neighbors to the inactive queue. Repeat until the active queue is empty. Then swap the queues.
This maintains the invariant that if the distance to all nodes in the active queue is d, the distance to all nodes in the inactive queue is d+1. Easy enough to keep track of and stop when you want.
You can pass the depth to the value you put in the queue. You can also keep a separate array to store the depth you reached each node.
Encapsulate the vertices you pass together with their distance from the source of the BFS.
Another possibility would be to just mark the vertices in the queue; usually frameworks for graphs allow you to assign weights to elements of the graph, which is a mechanism you could use for your purpose.
One last possibility would be to insert a marking vertex that isn't actually in the graph into the queue after the frontier of one level of the BFS has been completely processed so you know when a new level of BFS depth starts. That would make your queue look something like v u w x y MARKER s t j l k with all of these being vertices of the graph, except for MARKER.

calculate the degree of separation between two nodes in a connected graph

I am working on a graph library that requires to determine whether two nodes are connected or not and if connected what is the degree of separation between them
i.e number of nodes needed to travel to reach the target node from the source node.
Since its an non-weighted graph, a bfs gives the shortest path. But how to keep the track of number of nodes discovered before reaching the target node.
A simple counter which increments on discovering a new node will give a wrong answer as it may include nodes which are not even in the path.
Another way would be to treat this as a weighted graph of uniform weighted edges and using Djkastra's shortest path algorithm.
But I want to manage it with bfs only.
How to do it ?
During the BFS, have each node store a pointer to its predecessor node (the node in the graph along whose edge the node was first discovered). Then, once you've run BFS, you can repeatedly follow this pointer from the destination node to the source node. If you count up how many steps this takes, you will have the distance from the destination to the source node.
Alternatively, if you need to repeatedly determine the distances between nodes, you might want to use the Floyd-Warshall all-pairs shortest paths algorithm, which if precomputed would let you immediately read off the distances between any pair of nodes.
Hope this helps!
I don't see why a simple counter wouldn't work. In this case, breadth-first search would definitely give you the shortest path. So what you want to do is attach a property to every node called 'count'. Now when you encounter a node that you have not visited yet, you populate the 'count' property with whatever the current count is and move on.
If later on, you come back to the node, you should know by the populated count property that it has already been visited.
EDIT: To expand a bit on my answer here, you'll have to maintain a variable that'll track the degree of separation from your starting node as you navigate the graph. For every new set of children that you load into the queue, make sure that you increment the value in that variable.
If all you want to know is the distance (possibly to cut off the search if the distance is too large), and all edges have the same weight (i.e. 1):
Pseudocode:
Let Token := a new node object which is different from every node in the graph.
Let Distance := 0
Let Queue := an empty queue of nodes
Push Start node and Token onto Queue
(Breadth-first-search):
While Queue is not empty:
If the head of Queue is Target node:
return Distance
If the head of Queue is Token:
Increment Distance
Push Token onto back of the Queue
If the head of Queue has not yet been seen:
Mark the head of the Queue as seen
Push all neighbours of the head of the Queue onto the back of Queue
Pop the head of Queue
(Did not find target)

Find connected-blocks with certain value in a grid

I'm having trouble finding an algorithm for my problem.
I have a grid of 8x8 blocks, each block has a value ranging from 0 to 9. And I want to find collections of connected blocks that match a total value of for example 15. My first approach was to start of at the border, that worked fine. But when starting in the middle of the grid my algorithm gets lost.
Would anyone know a simple algorithm to use or can you point me in the right direction?
Thanks!
As far as I know, no simple algorithm exists for this. As for pointing you in the right direction, an 8x8 grid is really just a special case of a graph, so I'd start with graph traversal algorithms. I find that in cases like this, it sometimes helps to think how you would solve the problem for a smaller grid (say, 3x3 or 4x4) and then see if your algorithm scales up to "full size."
EDIT :
My proposed algorithm is a modified depth-first traversal. To use it, you'll have to convert your grid into a graph. The graph should be undirected, since connected blocks are connected equally in both directions.
Each graph node represents a single block, containing the block's value and a visited variable. Edge weights represent their edges' resistance to being followed. Set them by summing the values of the nodes they connect. Depending on the sum you're looking for, you may be able to optimize this by removing edges that are guaranteed to fail. For example, if you're looking for 15, you can delete all edges with weight of 16 or greater.
The rest of the algorithm will be performed as many times as there are blocks, with each block serving as the starting block once. Traverse the graph by following the lowest-weighted edge from the current node, unless that takes you to a visited node. Push each visited node onto a stack and set its visited variable to true. Keep a running sum for every path followed.
Whenever the desired sum is reached, save the current path as one of your answers. Do not stop traversal, because the current node could be connected to a zero.
Whenever the total exceeds the desired sum, backtrack by setting visited to false and popping the current node off the stack.
Whenever all edges for a given node have been explored, backtrack.
After every possible path from a given starting node is analyzed, every answer that includes that node has been found. So, remove all edges touching the starting node and choose a new starting node.
I haven't fully analyzed the efficiency/running time of this algorithm yet, but... it's not good. (Consider the number of paths to be searched in a graph containing all zeroes.) That said, it's far better than pure brute force.

Resources