/// <summary> /// Returns the number of reachable nodes from the given vertex inside the given graph. /// </summary> /// <param name="g"></param> /// <param name="from"></param> /// <returns></returns> public static int CountReachableNodes(Graph g, Vertex from) { //Initialize Dictionary <Vertex, int> distances = new Dictionary <Vertex, int>(); Dictionary <Vertex, Vertex> predecessor = new Dictionary <Vertex, Vertex>(); int count = 1; distances.Add(from, 0); predecessor.Add(from, from); foreach (Vertex v in g.Vertices) { if (!v.Equals(from)) { distances.Add(v, Int32.MaxValue); predecessor.Add(v, null); } } PriorityQueue <Vertex> q = new PriorityQueue <Vertex>(); q.Insert(from, 0); //Algorithm while (q.Count != 0) { //Get next Vertex Vertex u = q.PopLowest(); //Find all neighbors of u Vertex[] neighbors = GraphHelper.FindAdjacentVertices(g, u); //Analyse the neighbors and update their distances and predecessors accordingly foreach (Vertex v in neighbors) { if (predecessor[v] != null) { //update distance if (distances[u] + 1 < distances[v]) { distances[v] = distances[u] + 1; predecessor[v] = u; q.InsertOverride(v, distances[u] + 1); } } else { distances[v] = distances[u] + 1; predecessor[v] = u; q.InsertOverride(v, distances[u] + 1); count++; } } } return(count); }
/// <summary> /// Returns true when the given Graph is bipartite. /// </summary> /// <param name="graph"></param> /// <returns></returns> public static bool IsGraphBipartite(Graph g) { //Create two sets of Vertices Dictionary <Vertex, bool> U = new Dictionary <Vertex, bool>(); Dictionary <Vertex, bool> V = new Dictionary <Vertex, bool>(); //Define Source Vertex Vertex src = g.Vertices[0]; //Create a Queue that holds all vertices to analyse and starts with the source Vertex Queue <Vertex> q = new Queue <Vertex>(); q.Enqueue(src); //Add Source Vertex to Set U U.Add(src, true); //while there is an Element in the Queue while (!(q.Count == 0)) { //get the next Vertex Vertex v = q.Dequeue(); //find all neighbors Vertex[] neighbors = GraphHelper.FindAdjacentVertices(g, v); foreach (Vertex vn in neighbors) { //if neighbor is in no set yet add it to the alternate set of v if (!U.ContainsKey(vn) && !V.ContainsKey(vn)) { if (U.ContainsKey(v)) { V.Add(vn, true); } else { U.Add(vn, true); } //Add the neighbor to the Queue q.Enqueue(vn); } //if the neighbor already is inside a set and it is the same set as v, the graph is not bipartite else if ((U.ContainsKey(v) && U.ContainsKey(vn)) || (V.ContainsKey(v) && V.ContainsKey(vn))) { return(false); } } } //if until now the graph was not determined non-bipartite, it can only be bipartite return(true); }
/// <summary> /// Returns true when the given Graph is Complete. /// </summary> /// <param name="graph"></param> /// <returns></returns> public static bool IsGraphComplete(Graph g) { Vertex[] vertices = g.Vertices; foreach (Vertex v in vertices) { List <Vertex> neighbors = GraphHelper.FindAdjacentVertices(g, v).ToList <Vertex>(); neighbors.Add(v); if (!vertices.All((x) => { return(neighbors.Contains(x)); })) { return(false); } } return(true); }
/// <summary> /// Uses the Dijkstra Search Algorithm to find from one Vertex to another in the given Graph. /// </summary> /// <param name="graph"></param> /// <param name="from"></param> /// <param name="to"></param> /// <returns></returns> public static Vertex[] Search(Graph g, Vertex from, Vertex to) { //Initialize Dictionary <Vertex, int> distances = new Dictionary <Vertex, int>(); Dictionary <Vertex, Vertex> predecessor = new Dictionary <Vertex, Vertex>(); bool found = false; distances.Add(from, 0); predecessor.Add(from, from); foreach (Vertex v in g.Vertices) { if (!v.Equals(from)) { distances.Add(v, Int32.MaxValue); predecessor.Add(v, null); } } PriorityQueue <Vertex> q = new PriorityQueue <Vertex>(); q.Insert(from, 0); //Algorithm while (q.Count != 0) { Vertex u = q.PopLowest(); //Goal Vertex found if (u.Equals(to)) { found = true; break; } //Find all neighbors of u Vertex[] neighbors = GraphHelper.FindAdjacentVertices(g, u); //Analyse the neighbors and update their distances and predecessors accordingly foreach (Vertex v in neighbors) { if (predecessor[v] != null) { //update distance if (distances[u] + 1 < distances[v]) { distances[v] = distances[u] + 1; predecessor[v] = u; q.InsertOverride(v, distances[u] + 1); } } else { distances[v] = distances[u] + 1; predecessor[v] = u; q.InsertOverride(v, distances[u] + 1); } } } if (found) { return(GetPath(predecessor, to)); } else { return(null); } }