Unvisited neigbours in graph path - algorithm

I am trying to find distance in an undirected graph, but when navigating to different path, the count cannot be calculated properly.
I am not sure what is the best approach for:
1) To count the path values excluding unnecessary paths.
2) To keep the path (I think to use LinkedList or ArrayList, etc. what is the best choices for this situation.
Any help would be appreciated.

Here is a code that solves this problem:
void Measure(Node node)
{
path.Add(node);
node.IsVisited = true;
if (node != destination)
{
foreach (var neighbor in node.Neighbors.Where(n=>!n.IsVisited))
{
Measure(neighbor);
}
path.RemoveAt(path.Count - 1);
}
}
You can use any dynamic length structure such as List or LinkedList for storing the path. List is recommended for simplicity.
usage:
var path = new List<Node>()
Measure(firstNode);
Print(path.Count);
this works if there is a path between the two nodes. otherwise the path is empty.
class Node
{
public string Name { get; set; }
public bool IsVisited { get; set; }
public List<Node> Neighbors { get; set; } = new List<Node>();
}

Related

Find inclusion graph from ordered set

Let's say I have a set of elements and an order relation (not total) between them.
To keep it simple, let's say its 1D segments with inclusion.
From the raw list of segments, how can I build a graph of direct inclusion (given it's possible from my set):
from the black segments, how can I rebuild the red graph?
I have a O(n^3) solution in C#, which is perfectly ugly, and I wonder if there is anything better [pseudo-code]:
interface INode
{
bool Includes(INode other);
List<INode> Childs { get; set; }
}
class Graph
{
public INode Root { get; set; }
}
class GraphBuilder
{
public static Graph Build(IList<INode> nodes)
{
Graph result = new Graph();
foreach (var segment in nodes) {
segment.Childs = new List<INode>();
bool isRoot = true;
foreach (var segment2 in nodes)
{
if (segment2.Includes(segment))
{
isRoot = false;
}
if (segment.Includes(segment2))
{
bool isDirectChild = true;
foreach (var segment3 in nodes)
{
if (segment.Includes(segment3) && segment3.Includes(segment2))
isDirectChild = false;
break;
}
if (isDirectChild)
segment.Childs.Add(segment2);
}
}
if (isRoot)
{
result.Root = segment;
}
}
return result;
}
}
First do a topological sort of the DAG using an efficient algorithm such as Kahn's algorithm in time O(V+E).
For each element, construct just the arrow from itself to the least (in the topological order) thing it is less than in the original DAG. Figuring these out also requires time O(V+E).
That's your red graph in time O(V+E).
Note that just reading the DAG takes time O(V+E) so this is, up to a constant, the best that you could possibly do.

Randomised Path on graph - set length, no crossing, no dead ends

I am working on a game with a 8 wide 5 high grid. I have a 'snake' feature which needs to enter the grid and "walk" around for a set distance (20 for example). There are certain restrictions for the movement of the snake:
It needs go over the predetermined amount of blocks (20)
It cannot go over itself or double back (no dead ends)
Currently I am using a Randomised Depth First search, however I have found that it occasionally goes back over itself (crosses its own path) and am not sure if this is the best way to go about it.
Options considered: I have looked at using A*, but am struggling to figure out a good way to do it without a predetermined goal and the conditions above. I have also considered adding a heuristic to favour blocks that are not on the outside of the grid - but am not sure either of these will solve the issue at hand.
Any help is appreciated and I can add more detail or code if necessary:
public List<GridNode> RandomizedDepthFirst(int distance, GridNode startNode)
{
Stack<GridNode> frontier = new Stack<GridNode>();
frontier.Push(startNode);
List<GridNode> visited = new List<GridNode>();
visited.Add(startNode);
while (frontier.Count > 0 && visited.Count < distance)
{
GridNode current = frontier.Pop();
if (current.nodeState != GridNode.NodeState.VISITED)
{
current.nodeState = GridNode.NodeState.VISITED;
GridNode[] vals = current.FindNeighbours().ToArray();
List<GridNode> neighbours = new List<GridNode>();
foreach (GridNode g in vals.OrderBy(x => XMLReader.NextInt(0,0)))
{
neighbours.Add(g);
}
foreach (GridNode g in neighbours)
{
frontier.Push(g);
}
if (!visited.Contains(current))
{
visited.Add(current);
}
}
}
return visited;
}
An easy way to account for back tracking is using a recursive dfs search.
Consider the following graph:
And a java implementation of a dfs search, removing nodes from the path when backtracking (note the comments. Run it online here) :
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Stack;
public class Graph {
//all graph nodes
private Node[] nodes;
public Graph(int numberOfNodes) {
nodes = new Node[numberOfNodes];
//construct nodes
for (int i = 0; i < numberOfNodes; i++) {
nodes[i] = new Node(i);
}
}
// add edge from a to b
public Graph addEdge(int from, int to) {
nodes[from].addNeighbor(nodes[to]);
//unless unidirectional: //if a is connected to b
//than b should be connected to a
nodes[to].addNeighbor(nodes[from]);
return this; //makes it convenient to add multiple edges
}
//returns a list of path size of pathLength.
//if path not found : returns an empty list
public List<Node> dfs(int pathLength, int startNode) {
List<Node> path = new ArrayList<>(); //a list to hold all nodes in path
Stack<Node> frontier = new Stack<>();
frontier.push(nodes[startNode]);
dfs(pathLength, frontier, path);
return path;
}
private boolean dfs(int pathLength, Stack<Node> frontier, List<Node> path) {
if(frontier.size() < 1) {
return false; //stack is empty, no path found
}
Node current = frontier.pop();
current.setVisited(true);
path.add(current);
if(path.size() == pathLength) {
return true; //path size of pathLength found
}
System.out.println("testing node "+ current); //for testing
Collections.shuffle(current.getNeighbors()); //shuffle list of neighbours
for(Node node : current.getNeighbors()) {
if(! node.isVisited()) {
frontier.push(node);
if(dfs(pathLength, frontier, path)) { //if solution found
return true; //return true. continue otherwise
}
}
}
//if all neighbours tested and no solution found, current node
//is not part of the path
path.remove(current); // remove it
current.setVisited(false); //this accounts for loops: you may get to this node
//from another edge
return false;
}
public static void main(String[] args){
Graph graph = new Graph(9); //make graph
graph.addEdge(0, 4) //add edges
.addEdge(0, 1)
.addEdge(1, 2)
.addEdge(1, 4)
.addEdge(4, 3)
.addEdge(2, 3)
.addEdge(2, 5)
.addEdge(3, 5)
.addEdge(1, 6)
.addEdge(6, 7)
.addEdge(7, 8);
//print path with length of 6, starting with node 1
System.out.println( graph.dfs(6,1));
}
}
class Node {
private int id;
private boolean isVisited;
private List<Node>neighbors;
Node(int id){
this.id = id;
isVisited = false;
neighbors = new ArrayList<>();
}
List<Node> getNeighbors(){
return neighbors;
}
void addNeighbor(Node node) {
neighbors.add(node);
}
boolean isVisited() {
return isVisited;
}
void setVisited(boolean isVisited) {
this.isVisited = isVisited;
}
#Override
public String toString() {return String.valueOf(id);} //convenience
}
Output:
testing node 1
testing node 6
testing node 7
testing node 8
testing node 2
testing node 5
testing node 3
testing node 4
[1, 2, 5, 3, 4, 0]
Note that nodes 6,7,8 which are dead-end, are tested, but not included in the final path.

How to get total count of children of a class containing Dictionary of same type?

I have a 'Node' class as follows:
public class Node
{
public readonly IDictionary<string, Node> _nodes =
new Dictionary<string, Node>();
public string Path { get; set; }
}
I want to get the total child count of _nodes of object of the above class. There can be any level of depths. Let us suppose i create an object as:
Node obj = new Node();
After iterating, i wish to get total no of Nodes at all levels of depth. I tried the following but it is not working:
foreach (var item in obj._nodes)
{
count += item.Value._nodes.SelectMany(list => list.Value._nodes).Distinct().Count();
}
A typical solution to this problem is to create a recursive method, like this:
public class Node
{
public readonly IDictionary<string, Node> _nodes
= new Dictionary<string, Node>();
public int GetTotalChildrenCount()
{
return _nodes.Values.Sum(n => n.GetTotalChildrenCount() + 1);
}
}
+ 1 part is used to count a node itself, apart from the number of its children.
I've omitted the call to the Distinct function. It will probably won't work, as your node doesn't have Equals and GetHashCode method overridden.
What you have there is a tree of nodes. You need to flatten this and then you could count the nodes easily. This is a very nice extension method I googled somewhere ages ago:
public static IEnumerable<T> Flatten<T>(
this IEnumerable<T> e,
Func<T, IEnumerable<T>> f)
{
return e.SelectMany(c => f(c).Flatten(f)).Concat(e);
}
When you have that, the rest is easy:
var count = new [] {obj}.Flatten(x => x._nodes.Values).Distinct().Count();
You may want to override Equals and GetHashCode on Node to make Distinct() work as expected.

Better version of Compare Extension for Linq

I need to get differences between two IEnumerable. I wrote extension method for it. But as you can see, it has performance penalties. Anyone can write better version of it?
EDIT
After first response, I understand that I could not explain well. I'm visiting both arrays three times. This is performance penalty. It must be a single shot.
PS: Both is optional :)
public static class LinqExtensions
{
public static ComparisonResult<T> Compare<T>(this IEnumerable<T> source, IEnumerable<T> target)
{
// Looping three times is performance penalty!
var res = new ComparisonResult<T>
{
OnlySource = source.Except(target),
OnlyTarget = target.Except(source),
Both = source.Intersect(target)
};
return res;
}
}
public class ComparisonResult<T>
{
public IEnumerable<T> OnlySource { get; set; }
public IEnumerable<T> OnlyTarget { get; set; }
public IEnumerable<T> Both { get; set; }
}
Dependig on the use-case, this might be more efficient:
public static ComparisonResult<T> Compare<T>(this IEnumerable<T> source, IEnumerable<T> target)
{
var both = source.Intersect(target).ToArray();
if (both.Any())
{
return new ComparisonResult<T>
{
OnlySource = source.Except(both),
OnlyTarget = target.Except(both),
Both = both
};
}
else
{
return new ComparisonResult<T>
{
OnlySource = source,
OnlyTarget = target,
Both = both
};
}
}
You're looking for an efficient full outer join.
Insert all items into a Dictionary<TKey, Tuple<TLeft, TRight>>. If a given key is not present, add it to the dictionary. If it is present, update the value. If the "left member" is set, this means that the item is present in the left source collection (you call it source). The opposite is true for the right member. You can do that using a single pass over both collections.
After that, you iterate over all values of this dictionary and output the respective items into one of three collections, or you just return it as an IEnumerable<Tuple<TLeft, TRight>> which saves the need for result collections.

How do I find all paths in a sequence of edges in a fast way?

Let E be a given directed edge set. Suppose it is known that the edges in E can form a directed tree T with all the nodes (except the root node) has only 1 in-degree. The problem is how to efficiently traverse the edge set E, in order to find all the paths in T?
For example, Given a directed edge set E={(1,2),(1,5),(5,6),(1,4),(2,3)}. We know that such a set E can generate a directed tree T with only 1 in-degree (except the root node). Is there any fast method to traverse the edge set E, in order to find all the paths as follows:
Path1 = {(1,2),(2,3)}
Path2 = {(1,4)}
Path3 = {(1,5),(5,6)}
By the way, suppose the number of edges in E is |E|, is there complexity bound to find all the paths?
I have not worked on this kind of problems earlier. So just tried out a simple solution. Check this out.
public class PathFinder
{
private static Dictionary<string, Path> pathsDictionary = new Dictionary<string, Path>();
private static List<Path> newPaths = new List<Path>();
public static Dictionary<string, Path> GetBestPaths(List<Edge> edgesInTree)
{
foreach (var e in edgesInTree)
{
SetNewPathsToAdd(e);
UpdatePaths();
}
return pathsDictionary;
}
private static void SetNewPathsToAdd(Edge currentEdge)
{
newPaths.Clear();
newPaths.Add(new Path(new List<Edge> { currentEdge }));
if (!pathsDictionary.ContainsKey(currentEdge.PathKey()))
{
var pathKeys = pathsDictionary.Keys.Where(c => c.Split(",".ToCharArray())[1] == currentEdge.StartPoint.ToString()).ToList();
pathKeys.ForEach(key => { var newPath = new Path(pathsDictionary[key].ConnectedEdges); newPath.ConnectedEdges.Add(currentEdge); newPaths.Add(newPath); });
pathKeys = pathsDictionary.Keys.Where(c => c.Split(",".ToCharArray())[0] == currentEdge.EndPoint.ToString()).ToList();
pathKeys.ForEach(key => { var newPath = new Path(pathsDictionary[key].ConnectedEdges); newPath.ConnectedEdges.Insert(0, currentEdge); newPaths.Add(newPath); });
}
}
private static void UpdatePaths()
{
Path oldPath = null;
foreach (Path newPath in newPaths)
{
if (!pathsDictionary.ContainsKey(newPath.PathKey()))
pathsDictionary.Add(newPath.PathKey(), newPath);
else
{
oldPath = pathsDictionary[newPath.PathKey()];
if (newPath.PathWeights < oldPath.PathWeights)
pathsDictionary[newPath.PathKey()] = newPath;
}
}
}
}
public static class Extensions
{
public static bool IsNullOrEmpty(this IEnumerable<object> collection) { return collection == null || collection.Count() > 0; }
public static string PathKey(this ILine line) { return string.Format("{0},{1}", line.StartPoint, line.EndPoint); }
}
public interface ILine
{
int StartPoint { get; }
int EndPoint { get; }
}
public class Edge :ILine
{
public int StartPoint { get; set; }
public int EndPoint { get; set; }
public Edge(int startPoint, int endPoint)
{
this.EndPoint = endPoint;
this.StartPoint = startPoint;
}
}
public class Path :ILine
{
private List<Edge> connectedEdges = new List<Edge>();
public Path(List<Edge> edges) { this.connectedEdges = edges; }
public int StartPoint { get { return this.IsValid ? this.connectedEdges.First().StartPoint : 0; } }
public int EndPoint { get { return this.IsValid ? this.connectedEdges.Last().EndPoint : 0; } }
public bool IsValid { get { return this.EdgeCount > 0; } }
public int EdgeCount { get { return this.connectedEdges.Count; } }
// For now as no weights logics are defined
public int PathWeights { get { return this.EdgeCount; } }
public List<Edge> ConnectedEdges { get { return this.connectedEdges; } }
}
I think DFS(Depth First Search) should suit your requirements. Have a look at it here - Depth First Search - Wikipedia. You can tailor it to print the paths in the format that you require. As regards the complexity, since every node in your tree has in-degree one , the number of edges for your tree is bounded as - |E| = O(|V|). Since DFS operates with a complexity of O(|V|+|E|), your overall complexity comes out to be O(|V|).
I did this question as a part of a my assignment. The gentleman above has correctly pointed out to use pathID. You must visit each edge atleast once hence the complexity bound is O(V+E) but for tree E=O(V) therefore the complexity is O(v). I will give you a glimpse since the details are bit involved -
you will label each path with a unique ID and the path are alloted IDs in the incremental values such as 0,1,2.... A pathID of a path is the sum of weights of the edges on the path. So using DFS allocate weights to the path. You may begin by using 0 for edges until you encounter your first path and then you keep adding 1 and so on. You will also have to argue the correctness and properly allocate the weights. DFS will do the trick.

Resources