/// <summary> /// constructor /// </summary> /// <param name="graph"></param> /// <param name="weight"></param> /// <param name="root">the node we start building the tree</param> internal MinimumSpanningTreeByPrim(BasicGraph <IEdge> graph, Func <IEdge, double> weight, int root) { this.graph = graph; this.weight = weight; this.root = root; q = new BinaryHeapPriorityQueue(graph.NodeCount); }
static internal IEnumerable <IEnumerable <int> > GetComponents(BasicGraph <TEdge> graph) { bool[] enqueueed = new bool[graph.NodeCount]; #if SHARPKIT //http://code.google.com/p/sharpkit/issues/detail?id=367 bool arrays are not default initialised for (var i = 0; i < graph.NodeCount; i++) { enqueueed[i] = false; } #endif Queue <int> queue = new Queue <int>(); for (int i = 0; i < graph.NodeCount; i++) { if (!enqueueed[i]) { List <int> nodes = new List <int>(); Enqueue(i, queue, enqueueed); while (queue.Count > 0) { int s = queue.Dequeue(); nodes.Add(s); foreach (int neighbor in Neighbors(graph, s)) { Enqueue(neighbor, queue, enqueueed); } } yield return(nodes); } } }
/// <summary> /// We build a spanning tree by following the DFS, the tree induces an order on vertices /// measured by the distance from the tree root. The feedback set will consist of edges /// directed against this order. /// </summary> /// <param name="graph"></param> /// <returns></returns> static internal IEnumerable <IEdge> GetFeedbackSet(BasicGraph <TEdge> graph) { if (graph != null && graph.NodeCount > 0 && graph.Edges.Count > 0) { Set <IEdge> feedbackSet = new Set <IEdge>(); VertStatus[] status = new VertStatus[graph.NodeCount]; //will be Unvisited at the beginning #if SHARPKIT //http://code.google.com/p/sharpkit/issues/detail?id=367 arrays are not default initialised for (int i = 0; i < status.Length; i++) { status[i] = VertStatus.NotVisited; } #endif for (int vertex = 0; vertex < graph.NodeCount; vertex++) { if (status[vertex] == VertStatus.Visited) { continue; } System.Diagnostics.Debug.Assert(status[vertex] != VertStatus.InStack); Stack <IEnumerator <TEdge> > enumStack = new Stack <IEnumerator <TEdge> >(); //avoiding the recursion Stack <int> vertexStack = new Stack <int>(); //avoiding the recursion IEnumerator <TEdge> outEnum = graph.OutEdges(vertex).GetEnumerator(); Push(enumStack, vertexStack, status, vertex, outEnum); while (enumStack.Count > 0) { Pop(enumStack, vertexStack, status, out vertex, out outEnum); while (outEnum.MoveNext()) { TEdge e = outEnum.Current; if (e.Source == e.Target) { continue; } VertStatus targetStatus = status[e.Target]; if (targetStatus == VertStatus.InStack) { feedbackSet.Insert(e); } else if (targetStatus == VertStatus.NotVisited) //have to go deeper { Push(enumStack, vertexStack, status, vertex, outEnum); vertex = e.Target; status[e.Target] = VertStatus.Visited; outEnum = graph.OutEdges(vertex).GetEnumerator(); } } } } return(feedbackSet as IEnumerable <IEdge>); } else { return(new Set <IEdge>()); } }
/// <summary> /// Returning a list of edges reversing which makes the graph into a DAG /// </summary> /// <param name="graph"></param> /// <param name="constraints"></param> /// <returns></returns> static internal IEnumerable <IEdge> GetFeedbackSetWithConstraints(BasicGraph <TEdge> graph, Set <IntPair> constraints) { if (constraints == null || constraints.Count == 0) { return(GetFeedbackSet(graph)); } else { return(GetFeedbackSetWithConstraintsLocal(graph, constraints)); } }
/// <summary> /// The function returns an array arr such that /// arr is a permutation of the graph vertices, /// and for any edge e in graph if e.Source=arr[i] /// e.Target=arr[j], then i is less than j /// </summary> /// <param name="graph"></param> /// <returns></returns> internal static int[] GetOrder <TEdge>(BasicGraph <TEdge> graph) where TEdge : IEdge { var visited = new bool[graph.NodeCount]; //no recursion! So we have to organize a stack var sv = new Stack <int>(); var se = new Stack <IEnumerator <int> >(); var order = new List <int>(); IEnumerator <int> en; for (int u = 0; u < graph.NodeCount; u++) { if (visited[u]) { continue; } int cu = u; visited[cu] = true; en = graph.OutEdges(u).Select(e => e.Target).GetEnumerator(); do { while (en.MoveNext()) { int v = en.Current; if (!visited[v]) { visited[v] = true; sv.Push(cu); se.Push(en); cu = v; en = graph.OutEdges(cu).Select(e => e.Target).GetEnumerator(); } } order.Add(cu); if (sv.Count > 0) { en = se.Pop(); cu = sv.Pop(); } else { break; } } while (true); } order.Reverse(); return(order.ToArray()); }
static IEnumerable <int> Neighbors(BasicGraph <TEdge> graph, int s) { foreach (TEdge e in graph.OutEdges(s)) { yield return(e.Target); } foreach (TEdge e in graph.InEdges(s)) { yield return(e.Source); } }
/// <summary> /// Returning a list of edges reversing which makes the graph into a DAG /// </summary> /// <param name="graph"></param> /// <param name="constraints"></param> /// <returns></returns> static internal IEnumerable <IEdge> GetFeedbackSetWithConstraints(BasicGraph <TEdge> graph, Set <IntPair> constraints) { if (constraints == null || constraints.Count == 0) { return(GetFeedbackSet(graph)); /* * var reg = GetFeedbackSetFromGraph(graph); * var con= GetFeedbackSetWithConstraints(graph, new HashSet<Tuple<int, int>>()); * int i = 0; * foreach (var z in reg) * i++; * foreach (var z in con) * i--; * Console.WriteLine("Eades {0} by {1}", i>0?"wins":"loses", i); * return con; */ } else { return(GetFeedbackSetWithConstraintsLocal(graph, constraints)); } }
static IEnumerable <IEdge> GetFeedbackSetWithConstraintsLocal(BasicGraph <TEdge> graph, Set <IntPair> constraints) { var v = new CycleRemovalWithConstraints <TEdge>(graph, constraints); return(v.GetFeedbackSet()); }
internal CycleRemovalWithConstraints(BasicGraph <TEdge> graph, Set <IntPair> constraints) { this.graph = graph; constrainedEdges = constraints; graphOfConstraints = new BasicGraph <IntPair>(constrainedEdges, graph.NodeCount); }
public static int[] GetOrder(int numberOfVertices, IEnumerable <System.Tuple <int, int> > edges) { var dag = new BasicGraph <IntPair>(from e in edges select new IntPair(e.Item1, e.Item2), numberOfVertices); return(GetOrder(dag)); }