/// <summary> /// Отрисовка ориентированного графа с выделенным маршрутом /// </summary> /// <param name="graph">орг. граф</param> /// <param name="path">маршрут</param> /// <returns>битовое изображение</returns> public static Bitmap Drawing(Digraph graph, Digraph.Path path) { if (graph == null || graph.CountVertex() == 0) throw new Exception("Невозможно отрисовать граф. Граф пуст."); if (path == null || !path.IsExists()) return Drawing(graph); string script = "digraph G { nrankdir=LR node [style=\"filled\", fillcolor=\"skyblue\"]"; for (int i = 0; i < graph.CountVertex(); i++) script += (i + 1) + " "; for (int i = 0; i < graph.CountVertex(); i++) for (int j = 0; j < graph.CountVertex(); j++) if (!float.IsInfinity(graph[i, j])) { script += (i + 1) + " -> " + (j + 1) + " [label=\"" + graph[i, j] + "\""; if (path.IsContain(new Digraph.Edge(i, j, graph[i, j]))) script += ", fontcolor=\"firebrick\", color=\"firebrick2\", penwidth=3, weight=1"; script += "] "; } script += "}"; return RenderingOnGraphviz(script); }
/// <summary> /// Создание пошагового метода ветвей и границ /// </summary> /// <param name="graph">орг. граф</param> public BranchAndBound(Digraph graph) { // метод ветвей и границ для указанного графа Graph = graph; // переход в следующее состояние next = IterationState.Start; // создание пустого маршрута коммивояжера TsPath = new Digraph.Path(Graph); if (Graph.CountVertex() == 0) { // пустой маршрут // окончание метода next = IterationState.Stop; } else if (Graph.CountVertex() == 1) { // маршрут из одной вершины TsPath.Append(new Digraph.Edge(0, 0, 0)); // окончание метода next = IterationState.Stop; } else if (Graph.CountVertex() == 2) { // маршрут из двух вершин TsPath.Append(new Digraph.Edge(0, 1, Graph[0, 1])); TsPath.Append(new Digraph.Edge(1, 0, Graph[1, 0])); // окончание метода next = IterationState.Stop; } }
public static Digraph<char> Build(string s) { string[] edges = s.Split(','); Digraph<char> ret = new Digraph<char>(); foreach (var e in edges) { var trimed_e = e.Trim(); ret.AddEdge(trimed_e[0], trimed_e[1], double.Parse(trimed_e.Substring(2))); } return ret; }
/// <summary> /// does the id[] array contain the strongly connected components? /// </summary> /// <param name="g"></param> /// <returns></returns> public bool Check(Digraph g) { var tc = new TransitiveClosure(g); for (var v = 0; v < g.V; v++) { for (var w = 0; w < g.V; w++) { if (StronglyConnected(v, w) != (tc.Reachable(v, w) && tc.Reachable(w, v))) return false; } } return true; }
// установка значений всех виджетов и полей значениями по-умолчанию public void Default() { imageTsPath = imageGraph = null; iterator = null; tspImg.Source = null; graph = new Digraph(); tsPath = new Digraph.Path(graph); tspPathTxtBox.Text = ""; ExitTraceTsp(); traceTspBttn.IsEnabled = false; }
public KosarajuCC(Digraph G) { mark = new bool[G.v()]; id = new int[G.v()]; DepthFirstOrder order = new DepthFirstOrder(G.reverse()); foreach (int s in order.getReversePost()) { if (!mark[s]) { dfs(G, s); count++; } } }
/** * Returns a random simple digraph containing {@code V} vertices and {@code E} edges. * @param V the number of vertices * @param E the number of vertices * @return a random simple digraph on {@code V} vertices, containing a total * of {@code E} edges * @throws IllegalArgumentException if no such simple digraph exists */ public static Digraph simple(int V, int E) { if (E > (long) V*(V-1)) throw new IllegalArgumentException("Too many edges"); if (E < 0) throw new IllegalArgumentException("Too few edges"); Digraph G = new Digraph(V); SET<Edge> set = new SET<Edge>(); while (G.E() < E) { int v = StdRandom.uniform(V); int w = StdRandom.uniform(V); Edge e = new Edge(v, w); if ((v != w) && !set.contains(e)) { set.add(e); G.addEdge(v, w); } } return G; }
/// <summary> /// does the id[] array contain the strongly connected components? /// </summary> /// <param name="g"></param> /// <returns></returns> public bool Check(Digraph g) { var tc = new TransitiveClosure(g); for (var v = 0; v < g.V; v++) { for (var w = 0; w < g.V; w++) { if (StronglyConnected(v, w) != (tc.Reachable(v, w) && tc.Reachable(w, v))) { return(false); } } } return(true); }
public void Digraph_RemoveEdge() { var digraph = new Digraph(); digraph.AddVertex(0); digraph.AddVertex(1); digraph.AddVertex(2); digraph.AddEdge(0, 1); digraph.AddEdge(0, 2); digraph.RemoveEdge(0, 1); Assert.That(digraph.V, Is.EqualTo(3)); Assert.That(digraph.E, Is.EqualTo(1)); Assert.That(digraph.GetAdjList(0).Count(), Is.EqualTo(1)); }
private bool check(Digraph G) { TransitiveClosure tc = new TransitiveClosure(G); for (int v = 0; v < G.V(); v++) { for (int w = 0; w < G.V(); w++) { if (stronglyConnected(v, w) != (tc.reachable(v, w) && tc.reachable(w, v))) { return(false); } } } return(true); }
/** * Computes the strong components of the digraph {@code G}. * @param G the digraph */ public GabowSCC(Digraph G) { marked = new boolean[G.V()]; stack1 = new Stack<Integer>(); stack2 = new Stack<Integer>(); id = new int[G.V()]; preorder = new int[G.V()]; for (int v = 0; v < G.V(); v++) id[v] = -1; for (int v = 0; v < G.V(); v++) { if (!marked[v]) dfs(G, v); } // check that id[] gives strong components assert check(G); }
private void DFS(Digraph g, int v) { marked[v] = true; ListBag <int> list = g.Adj(v); BagNode <int> node = list.first; while (node != null) { if (!marked[node.t]) { DFS(g, node.t); } node = node.next; } }
private int[] rank; // rank[v] = position of vertex v in topological order public Topological(Digraph G) { DirectedCycle finder = new DirectedCycle(G); if (!finder.hasCycle()) { DepthFirstOrder dfs = new DepthFirstOrder(G); order = dfs.reversePost(); rank = new int[G.V()]; int i = 0; foreach (int v in order) { rank[v] = i++; } } }
public Widget GetWidget(AssemblyDefinition assembly) { this.assembly = assembly; Digraph digraph = GetDotData(assembly); image = new Image(DotHelper.BuildDotImage(digraph)); AddinScrolledWindow sw = new AddinScrolledWindow(); sw.AddWithViewport(image); sw.ShowAll(); sw.OnRefresh += delegate { Refresh(); }; return(sw); }
public CircleNodeScene() { this.mGraph = new Digraph <CircleNode, ArrowEdge>(); this.mLayoutTimer = new Timer(); this.mLayoutTimer.Interval = 1000 / 25; this.mLayoutTimer.Tick += new EventHandler(OnLayoutTimerTick); this.mLayout = null; this.mMouseUpHistory = new int[3]; for (int i = 0; i < this.mMouseUpHistory.Length; i++) { this.mMouseUpHistory[i] = -1; } }
public void UpdateEdges() { Digraph <StateNode, StateEdge> .GEdge edge; Digraph <StateNode, StateEdge> graph = this.mScene.StateGraph; int index = graph.IndexOfNode(this); for (int i = graph.EdgeCount - 1; i >= 0; i--) { edge = graph.InternalEdgeAt(i); if (edge.SrcNode.Index == index || edge.DstNode.Index == index) { edge.Data.Update(); } } }
/** * Initializes a new digraph that is a deep copy of the specified digraph. * * @param G the digraph to copy */ public Digraph(Digraph G) { this(G.V()); this.E = G.E(); for (int v = 0; v < V; v++) this.indegree[v] = G.indegree(v); for (int v = 0; v < G.V(); v++) { // reverse so that adjacency list is in same order as original Stack<Integer> reverse = new Stack<Integer>(); for (int w : G.adj[v]) { reverse.push(w); } for (int w : reverse) { adj[v].add(w); } } }
private void Dfs(Digraph G, int vertex) { _marked.Add(vertex); foreach (var neighborVertex in G.GetNeighbors(vertex)) { if (_marked.Contains(neighborVertex)) { continue; } Dfs(G, neighborVertex); } _reversePost.Push(vertex); }
public KosarajuSCC(Digraph G) : base(G) { _marked = new bool[G.V()]; _id = new int[G.V()]; DepthFirstOrder order = new DepthFirstOrder(G.Reverse()); foreach (var v in order.ReversePost()) { if (!_marked[v]) { Dfs(G, v); _count++; } } }
/// <summary> /// Checks desktop /// </summary> /// <param name="desktop"></param> static public void Check(this IDesktop desktop) { IDesktop d = desktop.Root; CheckObject ch = new CheckObject(checkLink); List <IObjectLabel> objects; List <IArrowLabel> arrows; PureDesktopPeer.GetFullList(d, out objects, out arrows); Digraph graph = PureDesktop.CreateDigraph(objects, arrows, null, ch); List <DigraphLoop> loops = graph.Loops; foreach (DigraphLoop loop in loops) { Check(loop); } }
public KosarajuSCC(Digraph digraph) { marked = new bool[digraph.Vertices]; id = new int[digraph.Vertices]; var order = new DepthFirstOrder(digraph.Reverse()); foreach (var s in order.ReversePost()) { if (!marked[s]) { Dfs(digraph, s); count++; } } }
private bool check(Digraph digraph) { TransitiveClosure transitiveClosure = new TransitiveClosure(digraph); for (int i = 0; i < digraph.V(); i++) { for (int j = 0; j < digraph.V(); j++) { if (this.stronglyConnected(i, j) != ((!transitiveClosure.reachable(i, j) || !transitiveClosure.reachable(j, i)) ? false : true)) { return(false); } } } return(true); }
static string Add_Edge_ThrowsExceptionWhenEitherVertexNotInGraph() { var expectedMessage1 = "Vertex Id 1 is not an element within V"; var expectedMessage2 = "Vertex Id 2 is not an element within V"; // Arrange preconditions var graph = new Digraph<int, int, int>(); var vertex1 = new Vertex<int, int>(1); var vertex2 = new Vertex<int, int>(2); // Act bool result; try { graph.AddEdge(vertex1, vertex2, 1); return Fail; } catch (Exception ex) { result = expectedMessage1 == ex.Message; } try { var graphPrime = graph.AddVertex(vertex2, vertex2.Identifier); graphPrime.AddEdge(vertex1, vertex2, 1); return Fail; } catch (Exception ex) { result = expectedMessage1 == ex.Message; } try { var graphPrime = graph.AddVertex(vertex1, vertex1.Identifier); graphPrime.AddEdge(vertex1, vertex2, 1); return Fail; } catch (Exception ex) { result = expectedMessage2 == ex.Message; } return result ? Pass : Fail; }
private Digraph graph; // the underlying digraph public SymbolDigraph(TextAsset txt, char sparator) //jobs.txt { st = new ST <string, int>(); // First pass builds the index by reading strings to associate // distinct strings with an index string[] lines = txt.text.Split(new char[1] { '\n' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < lines.Length; i++) { string[] lineStrs = lines[i].Split(new char[1] { sparator }, StringSplitOptions.RemoveEmptyEntries); foreach (string str in lineStrs) { if (!st.contains(str)) { st.put(str, st.size()); } } } keys = new string[st.size()]; foreach (string name in st.keys()) { keys[st.GetValue(name)] = name; } // second pass builds the digraph by connecting first vertex on each // line to all others graph = new Digraph(st.size()); foreach (string line in lines) { string[] lineStrs = line.Split(new char[1] { sparator }, StringSplitOptions.RemoveEmptyEntries); int v = st.GetValue(lineStrs[0]); for (int i = 1; i < lineStrs.Length; i++) { int w = st.GetValue(lineStrs[i]); graph.AddEdge(v, w); } } }
/** * Unit tests the {@code DirectedEulerianCycle} data type. * * @param args the command-line arguments */ public static void main(String[] args) { int V = Integer.parseInt(args[0]); int E = Integer.parseInt(args[1]); // Eulerian cycle Digraph G1 = DigraphGenerator.eulerianCycle(V, E); unitTest(G1, "Eulerian cycle"); // Eulerian path Digraph G2 = DigraphGenerator.eulerianPath(V, E); unitTest(G2, "Eulerian path"); // empty digraph Digraph G3 = new Digraph(V); unitTest(G3, "empty digraph"); // self loop Digraph G4 = new Digraph(V); int v4 = StdRandom.uniform(V); G4.addEdge(v4, v4); unitTest(G4, "single self loop"); // union of two disjoint cycles Digraph H1 = DigraphGenerator.eulerianCycle(V/2, E/2); Digraph H2 = DigraphGenerator.eulerianCycle(V - V/2, E - E/2); int[] perm = new int[V]; for (int i = 0; i < V; i++) perm[i] = i; StdRandom.shuffle(perm); Digraph G5 = new Digraph(V); for (int v = 0; v < H1.V(); v++) for (int w : H1.adj(v)) G5.addEdge(perm[v], perm[w]); for (int v = 0; v < H2.V(); v++) for (int w : H2.adj(v)) G5.addEdge(perm[V/2 + v], perm[V/2 + w]); unitTest(G5, "Union of two disjoint cycles"); // random digraph Digraph G6 = DigraphGenerator.simple(V, E); unitTest(G6, "simple digraph"); // 4-vertex digraph Digraph G7 = new Digraph(new In("eulerianD.txt")); unitTest(G7, "4-vertex Eulerian digraph"); }
// BFS from single source private void bfs(Digraph G, int s) { Queue<Integer> q = new Queue<Integer>(); marked[s] = true; distTo[s] = 0; q.enqueue(s); while (!q.isEmpty()) { int v = q.dequeue(); for (int w : G.adj(v)) { if (!marked[w]) { edgeTo[w] = v; distTo[w] = distTo[v] + 1; marked[w] = true; q.enqueue(w); } } } }
private int count; // number of strongly-connected components public KosarajuSharirSCC(Digraph G) { // compute reverse postorder of reverse graph DepthFirstOrder dfs = new DepthFirstOrder(G.Reverse()); // run DFS on G, using reverse postorder to guide calculation marked = new bool[G.V()]; id = new int[G.V()]; foreach (int v in dfs.reversePost()) { if (!marked[v]) { DFS(G, v); count++; } } }
private Digraph <ParsingResults> ConstructGraph(IEnumerable <ParsingResults> to_do) { Digraph <ParsingResults> g = new Digraph <ParsingResults>(); HashSet <ParsingResults> done = new HashSet <ParsingResults>(); Stack <ParsingResults> stack = new Stack <ParsingResults>(); foreach (ParsingResults f in to_do) { stack.Push(f); } while (stack.Count > 0) { ParsingResults f = stack.Pop(); var workspace = f.Item.Workspace; g.AddVertex(f); done.Add(f); foreach (string d in f.PropagateChangesTo) { Document d_doc = workspace.FindDocument(d); ParsingResults d_pd = ParsingResultsFactory.Create(d_doc); if (done.Contains(d_pd)) { continue; } stack.Push(d_pd); } } foreach (ParsingResults v in g.Vertices) { HashSet <string> deps = v.PropagateChangesTo; var workspace = v.Item.Workspace; Document doc = workspace.FindDocument(v.FullFileName); ParsingResults pd = ParsingResultsFactory.Create(doc); foreach (string d in deps) { Document d_doc = workspace.FindDocument(d); ParsingResults d_pd = ParsingResultsFactory.Create(d_doc); g.AddEdge(new DirectedEdge <ParsingResults>(pd, d_pd)); } } return(g); }
private readonly int height; //Drawing surface height (maximum height) /// <summary> /// Initializes a new instance of TriangularLatticeForm /// </summary> /// <param name="width">Drawing surface width (maximum width)</param> /// <param name="height">Drawing surface height (maximum height)</param> /// <exception cref="ArgumentOutOfRangeException"/> public TriangularLatticeForm(int width, int height) { if (width <= 0) { throw new ArgumentOutOfRangeException(nameof(width)); } if (height <= 0) { throw new ArgumentOutOfRangeException(nameof(height)); } InitializeComponent(); TriangularLatticeDigraph = null; this.width = width; this.height = height; }
private Stack<Integer> path = null; // Eulerian path; null if no suh path /** * Computes an Eulerian path in the specified digraph, if one exists. * * @param G the digraph */ public DirectedEulerianPath(Digraph G) { // find vertex from which to start potential Eulerian path: // a vertex v with outdegree(v) > indegree(v) if it exits; // otherwise a vertex with outdegree(v) > 0 int deficit = 0; int s = nonIsolatedVertex(G); for (int v = 0; v < G.V(); v++) { if (G.outdegree(v) > G.indegree(v)) { deficit += (G.outdegree(v) - G.indegree(v)); s = v; } } // digraph can't have an Eulerian path // (this condition is needed) if (deficit > 1) return; // special case for digraph with zero edges (has a degenerate Eulerian path) if (s == -1) s = 0; // create local view of adjacency lists, to iterate one vertex at a time Iterator<Integer>[] adj = (Iterator<Integer>[]) new Iterator[G.V()]; for (int v = 0; v < G.V(); v++) adj[v] = G.adj(v).iterator(); // greedily add to cycle, depth-first search style Stack<Integer> stack = new Stack<Integer>(); stack.push(s); path = new Stack<Integer>(); while (!stack.isEmpty()) { int v = stack.pop(); while (adj[v].hasNext()) { stack.push(v); v = adj[v].next(); } // push vertex with no more available edges to path path.push(v); } // check if all edges have been used if (path.size() != G.E() + 1) path = null; assert check(G); }
private readonly int height; //Drawing surface height (maximum height) /// <summary> /// Initializes a new instance of RandomDigraphGeneratorForm /// </summary> /// <param name="width">Drawing surface width (maximum width)</param> /// <param name="height">Drawing surface height (maximum height)</param> /// <exception cref="ArgumentOutOfRangeException"/> public RandomDigraphGeneratorForm(int width, int height) { if (width <= 0) { throw new ArgumentOutOfRangeException(nameof(width)); } if (height <= 0) { throw new ArgumentOutOfRangeException(nameof(height)); } InitializeComponent(); Digraph = null; this.width = width; this.height = height; }
public override bool Execute() { int i, j; DGEdge edge; List <DGEdge> edges; Digraph <DGNode, DGEdge> dg = this.mNode.mState.DecisionGraph; StateNode fState = this.mNode.mScene.FocusedState; if (fState != null && fState.Equals(this.mNode.mState)) { for (i = this.mSelectedEdges.Count - 1; i >= 0; i--) { edge = this.mSelectedEdges[i]; this.mNode.mScene.SelectDGEdge(edge, false); } } for (i = this.mAPs.Length - 1; i >= 0; i--) { edges = this.mAPs[i].Edges; for (j = edges.Count - 1; j >= 0; j--) { edge = edges[j]; dg.RemoveEdge(edge.SrcNode, edge.DstNode); edge.SetParent(null); } } foreach (IEdgeAction action in this.mActions) { action.Redo(); } this.mNode.mState.AddRootDGEdges(); this.mSliceList.Clear(); Array.Clear(this.mNode.mSliceAnchors, 0, this.mNode.mSliceCount); this.mNode.mSliceCount = 0; for (i = this.mAPs.Length - 1; i >= 0; i--) { this.mAPs[i].SetParent(null); } this.mNode.UpdateVisualization(); return(true); }
public override void Undo() { int i, j; DGEdge edge; List <DGEdge> edges; Digraph <DGNode, DGEdge> dg = this.mNode.mState.DecisionGraph; this.mSliceList.AddRange(this.mSlices); Array.Copy(this.mAPs, 0, this.mNode.mSliceAnchors, 0, this.mAPs.Length); this.mNode.mSliceCount = this.mAPs.Length; for (i = this.mAPs.Length - 1; i >= 0; i--) { this.mAPs[i].SetParent(this.mNode); } this.mNode.UpdateVisualization(); foreach (IEdgeAction action in this.mActions) { action.Undo(); } for (i = this.mAPs.Length - 1; i >= 0; i--) { edges = this.mAPs[i].Edges; for (j = edges.Count - 1; j >= 0; j--) { edge = edges[j]; edge.SetParent(this.mNode.mState); dg.AddEdge(edge); } } this.mNode.mState.RemoveRootDGEdges(); StateNode fState = this.mNode.mScene.FocusedState; if (fState != null && fState.Equals(this.mNode.mState)) { for (i = this.mSelectedEdges.Count - 1; i >= 0; i--) { edge = this.mSelectedEdges[i]; this.mNode.mScene.SelectDGEdge(edge, false); } } }
public void TestDigraph_AddEdge_FailsWithMissingNodes() { var g = new Digraph <int, Edge <int> >(); var sourceInside = 1; var targetInside = 2; g.AddNode(sourceInside); g.AddNode(targetInside); var sourceOutside = 3; var targetOutside = 4; foreach (var source in new[] { sourceInside, sourceOutside }) { foreach (var target in new[] { targetInside, targetOutside }) { var signature = "source=" + source + "; target=" + target; var edge = new Edge <int>(source, target); Assert.IsNotNull(edge); var isValid = (source < 3) && (target < 3); // The edge is valid, if both nodes are in the graph. try { Assert.AreEqual(isValid, g.AddEdge(edge), "Should be able to add edge only if edge is valid. @signature=" + signature); if (!isValid) { Assert.Fail("Expect an exception if edge is invalid. @signature=" + signature); } } catch (KeyNotFoundException) { Assert.IsTrue(!isValid, "Expect this exception only if edge is invalid. @signature=" + signature); } catch (Exception ex) { Assert.Fail("Unexpected type '" + ex.GetType().ToString() + "' of exception. @signature=" + signature); } } } }
protected override void OnFinishNode( Digraph <Node, Edge> .GNode n, uint depth) { int index = n.Index; if (this.mDatas[index].LowLink == this.mDatas[index].Depth) { /*this.mRoots.Add(n.Data); * int count = 0; * Node[] comp = new Node[this.mStackCount]; * int i = -1; * while (i != index) * { * i = this.mStack[--this.mStackCount];//this.mStack.Pop(); * comp[count++] = this.mDatas[i].Data; * } * Node[] newComp = new Node[count]; * Array.Copy(comp, 0, newComp, 0, count); * this.mComponents.Add(newComp);/* */ if (this.mCompCount == this.mRoots.Length) { Digraph <Node, Edge> .GNode[] roots; if (this.mCompCount == 0) { roots = new Digraph <Node, Edge> .GNode[4]; } else { roots = new Digraph <Node, Edge> .GNode[2 * this.mCompCount]; Array.Copy(this.mRoots, 0, roots, 0, this.mCompCount); } this.mRoots = roots; } this.mRoots[this.mCompCount] = n; int i = -1; while (i != index) { i = this.mStack[--this.mStackCount]; this.mCompIds[i] = this.mCompCount; } this.mCompCount++; } }
/**/ public static void main(string[] strarr) { string str = strarr[0]; string str2 = strarr[1]; SymbolDigraph symbolDigraph = new SymbolDigraph(str, str2); Digraph digraph = symbolDigraph.G(); while (!StdIn.IsEmpty) { string str3 = StdIn.readLine(); Iterator iterator = digraph.adj(symbolDigraph.index(str3)).iterator(); while (iterator.hasNext()) { int i = ((Integer)iterator.next()).intValue(); StdOut.println(new StringBuilder().append(" ").append(symbolDigraph.name(i)).toString()); } } }
static string Add_Edge_InsertsEdgeFromV1ToV2AndReturnsGPrime() { // Arrange preconditions var graph = new Digraph<int, int, int>(); var vertex1 = new Vertex<int, int>(1); var vertex2 = new Vertex<int, int>(2); var graphPrime = graph.AddVertex(vertex1, vertex1.Identifier); var graphDoublePrime = graphPrime.AddVertex(vertex2, vertex2.Identifier); var edgeLabel = 1; // Act var graphTriplePrime = graphDoublePrime.AddEdge(vertex1, vertex2, edgeLabel); // Assert postconditions if (graphTriplePrime == graphDoublePrime) return Fail; if (!graphTriplePrime.FromEdges(vertex1).Any()) return Fail; if (graphTriplePrime.FromEdges(vertex2).Any()) return Fail; return graphTriplePrime.GetEdge(vertex1, vertex2) == edgeLabel ? Pass : Fail; }
/// <summary> /// Отрисовка ориентированного графа /// </summary> /// <param name="graph">орг. граф</param> /// <returns>битовое изображение</returns> public static Bitmap Drawing(Digraph graph) { if (graph == null || graph.CountVertex() == 0) throw new Exception("Невозможно отрисовать граф. Граф не задан."); string script = "digraph G { nrankdir=LR node [style=\"filled\", fillcolor=\"skyblue\"]"; for (int i = 0; i < graph.CountVertex(); i++) script += (i + 1) + " "; for (int i = 0; i < graph.CountVertex(); i++) for (int j = 0; j < graph.CountVertex(); j++) if (!float.IsInfinity(graph[i, j])) script += (i + 1) + " -> " + (j + 1) + " [label=\"" + graph[i, j] + "\"] "; script += "}"; return RenderingOnGraphviz(script); }
private readonly bool[] _marked; // marked[v] = has vertex v been visited? #endregion Fields #region Constructors /// <summary> /// Computes the strong components of the digraph <tt>G</tt>. /// </summary> /// <param name="g">g the digraph</param> public KosarajuSharirSCC(Digraph g) { // compute reverse postorder of reverse graph var dfs = new DepthFirstOrder(g.Reverse()); // run DFS on G, using reverse postorder to guide calculation _marked = new bool[g.V]; _id = new int[g.V]; foreach (int v in dfs.ReversePost()) { if (!_marked[v]) { Dfs(g, v); _count++; } } // check that id[] gives strong components //assert check(G); }
/// <summary> /// DFS on graph G /// </summary> /// <param name="g"></param> /// <param name="v"></param> private void Dfs(Digraph g, int v) { _marked[v] = true; _id[v] = _count; foreach (int w in g.Adj(v)) { if (!_marked[w]) Dfs(g, w); } }
static string Update_Vertex_ThowsExceptionWhenVertexIsNotInGraph() { var expectedMessage = "Vertex Id Id1 is not an element within V"; // Arrange preconditions var graph = new Digraph<string, string, string>(); var vertex = new Vertex<string, string>("Id1"); var label = "Label1"; // Act bool result; try { graph.UpdateVertex(vertex, label); return Fail; } catch (Exception ex) { result = expectedMessage == ex.Message; } return result ? Pass : Fail; }
static string Add_Vertex_InsertsVertexWithLabelAndReturnsGPrime() { var expectedLabel = "Foo"; // Arrange Preconditions var graph = new Digraph<decimal, string, int>(); var vertex = new Vertex<decimal, string>(1000m); // Act var graphPrime = graph.AddVertex(vertex, expectedLabel); // Assert Postconditions if (graphPrime == graph) return Fail; if (graphPrime.IsEmpty) return Fail; if (!graph.IsEmpty) return Fail; if (!graphPrime.HasVertex(vertex)) return Fail; return graphPrime.GetVertex(vertex).Equals(expectedLabel) ? Pass:Fail; }
/// <summary> /// Исключение подмаршрутов в графе /// </summary> /// <param name="matrix">редуцированная матрица</param> /// <param name="dsu">непересекающиеся множества вершин</param> /// <param name="edges">ребро ветвления, которое уже находяться в маршруте или не входит в него</param> private static void ExcludeSubRoute(ReductionMatrix matrix, Dsu dsu, Digraph.Edge edge) { // если ребро не входит в ветвление if (edge.Begin < 0 || edge.End < 0) // исключение данного ребра из матрицы matrix[Math.Abs(edge.Begin), Math.Abs(edge.End)] = float.PositiveInfinity; // ребро входит в ветвление else { // исключение строки и столбца из матрицы, соответсвующие началу и концу ребра matrix.DeleteRowColumn(edge.Begin, edge.End); // исключение оставщихся подмаршрутов for (int i = 0; i < matrix.Size; i++) for (int j = 0; j < matrix.Size; j++) if (dsu.Find(edge.Begin) == dsu.Find(i) && dsu.Find(edge.End) == dsu.Find(j)) matrix[j, i] = float.PositiveInfinity; // объединение двух вершин графа в одно множество dsu.Union(edge.Begin, edge.End); } }
private EquationDecomposition(EquationSystem eqsys) { /** This algorithm decomposes a given equation system into smaller equation blocks * which can be solved subsequently. The algorithm is sometimes referred to as * Tarjan's sorting or Dulmage-Mendelson decomposition. * * The algorithm consists of several steps. The description below will use the * following notions: * Var: The set of variables of the whole equation system * Eqn: The set of equations of the whole equation system * Var u Eqn: The set unification of Var and Eqn * * Step (1): Maximum matching * Define an undirected graph G = (V, E) with V = Var u Eqn. * Whenever an equation eqn \in Eqn references a variable var \in Var * add the edge (eqn, var) to E. * Compute a maximum matching M between variables and equations. * M will now contain a set of equation/variable pairs. * * Step (2): Finding strongly connected components * Define a directed graph Gd = (V, Ed) with V = Var u Eqn. * Whenever an equation eqn \in Eqn references a variable var \in Var * add the edge (eqn, var) to Ed. * For each equation/variable pair (eqn, var) in M add furthermore * the edge (var, eqn) to Ed. * Note: Matched equation/variable pairs will result in bi-directional edges in Ed. * Compute the strongly connected components SCC of Gd. * SCC is a set of subsets of V such that each subset represents one component. * * Step (3): Building the tree of equation blocks * Defined a directed graph Dt = (SCC, Et). * For each equation eqn \in Eqn which is assigned to component c1 and * references a variable var \in Var which is assigned to component c2 * add an edge (c1, c2) to Et of c1 and c2 are different. * * The resulting graph will have a tree/forest sutrcture. Each node * represents an equation block. An edge b1 -> b2 represents a dependency in the * that b2 must be solved prior to b1. A schedule can be found by topological * sorting the tree. * */ if (eqsys == null || eqsys.Equations == null || eqsys.Variables == null) throw new ArgumentException("null reference in equation system argument"); if (eqsys.Equations.Count != eqsys.Variables.Count) throw new ArgumentException("equation system is not well-constrained!"); /** Assign each equation and each variable an index which will be a unique node * ID within the graphs. Indices are assigned as follows: * - Equations get indices from 0...count(equations)-1 * - Variables get indices from count(equations)...count(equations)+count(variables) * Note: Assuming a well-constrained equation system, count(equations) = count(variables) **/ int curidx = 0; foreach (Expression eq in eqsys.Equations) { eq.Cookie = curidx++; } Dictionary<object, int> idx = new Dictionary<object, int>(); foreach (Variable v in eqsys.Variables) { idx[v] = curidx++; } // Steps 1 and 2: Construct G and Gd Graph g = new Graph(curidx); Digraph dg = new Digraph(curidx); for (int i = 0; i < eqsys.Equations.Count; i++) { Expression eq = eqsys.Equations[i]; LiteralReference[] lrs = eq.ExtractLiteralReferences(); foreach (LiteralReference lr in lrs) { int j; if (idx.TryGetValue(lr.ReferencedObject, out j)) { g.AddEdge(i, j); dg.AddEdge(i, j); } } } // Step 1: Maximum matching GraphAlgorithms.Matching m = g.GetMaximumMatching(); bool success = m.IsMaximumCardinality; for (int i = 0; i < eqsys.Equations.Count; i++) { int k = m[i]; if (k >= 0) dg.AddEdge(k, i); } // Step 2: Strongly connected components StrongComponents sc = dg.GetStrongComponents(); int numc = sc.NumComponents; EquationBlock[] blocks = new EquationBlock[numc]; for (int i = 0; i < numc; i++) { blocks[i] = new EquationBlock(); } // Step 3: Construct the tree Digraph dg2 = new Digraph(numc); for (int i = 0; i < eqsys.Equations.Count; i++) { int c = sc[i]; blocks[c].EqSys.Equations.Add(eqsys.Equations[i]); int vi = m[i]; Variable v = eqsys.Variables[vi - eqsys.Equations.Count]; blocks[c].EqSys.Variables.Add(v); List<int> outset = dg.GetOutSet(i); foreach (int ovi in outset) { int oc = sc[ovi]; if (c != oc) dg2.AddEdge(c, oc); } } List<int> rootSet = new List<int>(); List<int> sinkSet = new List<int>(); for (int c = 0; c < numc; c++) { if (dg2.GetOutDegree(c) == 0) rootSet.Add(c); if (dg2.GetInDegree(c) == 0) sinkSet.Add(c); List<int> outset = dg2.GetOutSet(c); foreach (int oc in outset) blocks[c].Predecessors.Add(blocks[oc]); List<int> inset = dg2.GetInSet(c); foreach (int ic in inset) blocks[c].Successors.Add(blocks[ic]); } RootSet = (from int c in rootSet select blocks[c]).ToArray(); SinkSet = (from int c in sinkSet select blocks[c]).ToArray(); AllBlocks = blocks; }
private readonly DirectedDFS[] _tc; // tc[v] = reachable from v #endregion Fields #region Constructors /// <summary> /// Computes the transitive closure of the digraph <tt>G</tt>. /// </summary> /// <param name="g">g the digraph</param> public TransitiveClosure(Digraph g) { _tc = new DirectedDFS[g.V]; for (var v = 0; v < g.V; v++) _tc[v] = new DirectedDFS(g, v); }
/// <summary> /// Создание матрицы на основе матрциы смежности /// </summary> /// <param name="matrix">матрца смежности</param> public ReductionMatrix(Digraph.AdjacencyMatrix matrix) : base(matrix) { RealSize = Size; }
public void Init() { g = DigraphBuilder.Build(g_s); srn = new SimpleRouteNavigator<char>(g); finder = new BellmanFordShotestPathFinder<char>(g); }
public void Method() { Digraph<HV, HE>.Arc arc = new Digraph<HV, HE>.Arc(start, succ.First, succ.Second); }
/// <summary> /// Создания ветвления /// </summary> /// <param name="lowerBound">нижняя граница ветвления</param> /// <param name="branchingEdge">ребро ветвления</param> public Branch(float lowerBound, Digraph.Edge branchingEdge) { LowerBound = lowerBound; BranchingEdge = branchingEdge; }
/// <summary> /// Нахождение маршрута коммивояжера /// </summary> /// <param name="graph">ограф. граф</param> /// <returns>маршрут коммивояжера</returns> public static Digraph.Path Tsp(Digraph graph) { // маршрут коммивояжера var TsPath = new Digraph.Path(graph); // если граф пуст if (graph.CountVertex() == 0) { // пустой маршрут return TsPath; } // если граф имеет одну вершину else if (graph.CountVertex() == 1) { TsPath.Append(new Digraph.Edge(0, 0, 0)); // маршрут для одной вершины return TsPath; } // если граф имеет две вершины else if (graph.CountVertex() == 2) { TsPath.Append(new Digraph.Edge(0, 1, graph[0, 1])); TsPath.Append(new Digraph.Edge(1, 0, graph[1, 0])); // маршрут для двух вершин return TsPath; } /// Создания неперекающихся множеств вершин в графе, /// для определения и исключения подмаршрутов графа var dsu = new Dsu(graph.CountVertex()); // минимальное ветвление var minBranch = new Branch(float.PositiveInfinity, null); /// Получение исходной матрицы смежности данного графа var matrix = new ReductionMatrix(graph.Adjacency); /// Создание корня и дерева ветвления var parentBranch = new Branch(matrix.Reduce(), null); var tree = new TreeBranch(graph, parentBranch); for (; ; ) { // ребра с нулевой стоимостью var zeroEdges = new List<Digraph.Edge>(); // Получение всех ребер и соответсвующих штрафов for (int i = 0; i < matrix.Size; i++) for (int j = 0; j < matrix.Size; j++) if (matrix[i, j] == 0) zeroEdges.Add(new Digraph.Edge(i, j, matrix.MinInRow(i, j) + matrix.MinInColumn(j, i))); // если нет ребер ветвления - нет маршрута коммивояжера if (zeroEdges.Count == 0) return new Digraph.Path(graph); /// Определение ребра ветвления - ребра с максимальным штрафом var branchingEdge = zeroEdges.OrderByDescending(e => e.Cost).ToList().First(); /// Процесс ветления - не включая данное ребро var leftBranch = new Branch(parentBranch.LowerBound + branchingEdge.Cost, new Digraph.Edge(-branchingEdge.Begin, -branchingEdge.End, float.PositiveInfinity)); // добавление ветвления в дерево tree.Add(parentBranch, Branch.Direction.Left, leftBranch); /// Процесс ветления - включая данное ребро ExcludeSubRoute(matrix, dsu, branchingEdge); var rightBranch = new Branch(parentBranch.LowerBound + matrix.Reduce(), new Digraph.Edge(branchingEdge.Begin, branchingEdge.End, graph[branchingEdge.Begin, branchingEdge.End])); // добавление ветвления в дерево tree.Add(parentBranch, Branch.Direction.Right, rightBranch); /// Проверка на достаточность размера матрцицы if (matrix.RealSize == 2) { // новый родитель parentBranch = rightBranch; /// Добавление оставщихся ребер в дерево ветвлений for (int i = 0; i < matrix.Size; i++) for (int j = 0; j < matrix.Size; j++) if (matrix[i, j] == 0) { // новый потомок rightBranch = new Branch(parentBranch.LowerBound, new Digraph.Edge(i, j, graph[i, j])); tree.Add(parentBranch, Branch.Direction.Right, rightBranch); // потомок теперь родитель parentBranch = rightBranch; } /// Определение нового минимального ветвления if (parentBranch.LowerBound < minBranch.LowerBound) minBranch = parentBranch; } /// Выбор новой родительской вершины из еще не подвергшихся ветвлению parentBranch = tree.GetNotGoBranches().OrderBy(b => b.LowerBound).ToList().First(); /// Проверка на нахождения минимального ветвления и остановки if (minBranch.LowerBound <= parentBranch.LowerBound) break; /// Корректировка матрицы для данного ветвления и редуцирование if (parentBranch != rightBranch) { // новые непересекающиеся множества вершин dsu = new Dsu(graph.CountVertex()); // исходная редуцированная матрица matrix = new ReductionMatrix(graph.Adjacency); // получение текущих вершин для данного ветвления var currentPath = tree.GetEdgesBranching(parentBranch); // исключение всех подмаршрутов foreach (var e in currentPath) ExcludeSubRoute(matrix, dsu, e); // редуцирование матрицы matrix.Reduce(); } } // формирование маршрута коммивояжера TsPath = tree.CreatePathFromBranch(minBranch); return TsPath; }
static string Update_Edge_ThrowsExceptionWhenEdgeNotInGraph() { var expectedMessage = "Edge from vertex 1 to 2 is not an element within E"; // Arrange preconditions var graph = new Digraph<int, int, int>(); var vertex1 = new Vertex<int, int>(1); var vertex2 = new Vertex<int, int>(2); var graphPrime = graph.AddVertex(vertex1, vertex1.Identifier); var graphDoublePrime = graphPrime.AddVertex(vertex2, vertex2.Identifier); // Act bool result; try { graphDoublePrime.UpdateEdge(vertex1, vertex2, 5); return Fail; } catch (Exception ex) { result = expectedMessage == ex.Message; } return result ? Pass : Fail; }
static void OutputGraphStringRepresentation() { var graph = new Digraph<int, int, int>(); var vertex1 = new Vertex<int, int>(1); var vertex2 = new Vertex<int, int>(2); var graphPrime = graph.AddVertex(vertex1, vertex1.Identifier); var graphDoublePrime = graphPrime.AddVertex(vertex2, vertex2.Identifier); var edgeLabel = 1; var graphTriplePrime = graphDoublePrime.AddEdge(vertex1, vertex2, edgeLabel); var vertex3 = new Vertex<int, int>(3); var graphQuadruplePrime = graphTriplePrime.AddVertex(vertex3, vertex3.Identifier); var graphQuintuplePrime = graphQuadruplePrime.AddEdge(vertex1, vertex3, edgeLabel + 1); var graphSextuplePrime = graphQuintuplePrime.AddEdge(vertex3, vertex2, edgeLabel + 2); Console.WriteLine(graphSextuplePrime.ToString()); }
/// <summary> /// Создание дерева ветвления /// </summary> /// <param name="graph">орг. граф для которого строится дерево ветвлений</param> /// <param name="root">корень дерева</param> public TreeBranch(Digraph graph, Branch root) { Graph = graph; Root = root; }
private List<byte[]> GetPredecessorModelPositions( Bitmap image, int tileSize, Digraph<TileGenerationRecord>.Vertex v, byte[] partialPos, int nLeft, int nSkip, bool suppressSubpaths, bool suppressUngenerated) { List<byte[]> positions = new List<byte[]>(); if (nSkip != 0) { // skip this node and go to its predecessors if (v.Predecessors.Length == 0) { positions.Add(partialPos); } foreach (Digraph<TileGenerationRecord>.Vertex pred in v.Predecessors) { if (pred.Label.IsGenerated || !suppressUngenerated) { positions.AddRange(GetPredecessorModelPositions( image, tileSize, pred, partialPos, nLeft, nSkip - 1, suppressSubpaths, suppressUngenerated )); } else { Console.WriteLine("hit un-generated tile at {0}, {1}", pred.Label.Point.X, pred.Label.Point.Y); } } } else if (nLeft != 0) { // add this node's position to the partial and go to its predecessors if (!suppressSubpaths || v.Predecessors.Length == 0) { positions.Add(partialPos); } Color c = image.GetPixel(v.Label.Point.X, v.Label.Point.Y); byte[] thisPosition = new byte[] { c.R, c.G, c.B }; byte[] nextPartial = new byte[partialPos.Length + thisPosition.Length]; Array.Copy(partialPos, nextPartial, partialPos.Length); Array.Copy(thisPosition, 0, nextPartial, partialPos.Length, thisPosition.Length); foreach (Digraph<TileGenerationRecord>.Vertex pred in v.Predecessors) { if (pred.Label.IsGenerated || !suppressUngenerated) { positions.AddRange(GetPredecessorModelPositions( image, tileSize, pred, nextPartial, nLeft - 1, nSkip, suppressSubpaths, suppressUngenerated )); } else { Console.WriteLine("hit un-generated tile at {0}, {1}", pred.Label.Point.X, pred.Label.Point.Y); } } } else { // done positions.Add(partialPos); } return positions; }
static string Update_Vertex_ChangesLabelOnVertexAndReturnsGPrime() { // Arrange preconditions var graph = new Digraph<float, object, int>(); var f = .33333f; var vertex = new Vertex<float, object>(f); var object1 = new object(); var graphPrime = graph.AddVertex(vertex,object1); // Act var object2 = new object(); var graphDoublePrime = graphPrime.UpdateVertex(vertex, object2); // Assert postconditions if(graphDoublePrime == graphPrime) return Fail; if(graphDoublePrime.GetVertex(vertex) == object1) return Fail; return graphDoublePrime.GetVertex(vertex) == object2 ? Pass : Fail; }
private Digraph<TileGenerationRecord> MakeDependencyGraph(int w, int h) { Digraph<TileGenerationRecord> depGraph = new Digraph<TileGenerationRecord>(); int wTile = w, hTile = h; Digraph<TileGenerationRecord>.Vertex[,] vertices = new Digraph<TileGenerationRecord>.Vertex[wTile, hTile]; // build vertices for (int y = 0; y < hTile; y++) { for (int x = 0; x < wTile; x++) { vertices[x, y] = new Digraph<TileGenerationRecord>.Vertex(new TileGenerationRecord(new Point(x, y), false)); depGraph.Add(vertices[x, y]); } } // build edges for (int y = 0; y < hTile; y++) { for (int x = 0; x < wTile; x++) { if (x != 0) depGraph.DrawEdge(vertices[x - 1, y], vertices[x, y]); if (y != 0) depGraph.DrawEdge(vertices[x, y - 1], vertices[x, y]); } } return depGraph; }
static string Remove_Vertex_DeletesVertexAndReturnsGPrime() { // Arrange Preconditions var date = DateTime.Now; var graph = new Digraph<DateTime, string, int>(); var vertex = new Vertex<DateTime, string>(date); var graphPrime = graph.AddVertex(vertex, "Foo"); // Act var graphDoublePrime = graphPrime.RemoveVertex(vertex); // Assert Postconditions if (graphDoublePrime == graphPrime) return Fail; if (!graphPrime.GetVertex(vertex).Equals("Foo")) return Fail; if (!graphDoublePrime.IsEmpty) return Fail; if (!graphPrime.HasVertex(vertex)) return Fail; return !graphDoublePrime.HasVertex(vertex) ? Pass:Fail; }
static string Remove_Vertex_ThrowsExceptionWhenVertexIsNotInGraph() { var expectedMessage = "Vertex Id 1 is not an element within V"; // Arrange Preconditions var graph = new Digraph<int, string, int>(); var vertex = new Vertex<int, string>(1); // Act var result = false; try { var graphPrime = graph.RemoveVertex(vertex); return Fail; } catch (ArgumentException ae) { result = ae.Message == expectedMessage; } return result ? Pass : Fail; }
static string Remove_Edge_DeletesEdgeFromGraphGAndReturnsGPrime() { // Arrange preconditons var graph = new Digraph<int, int, int>(); var vertex1 = new Vertex<int, int>(1); var vertex2 = new Vertex<int, int>(2); var graphPrime = graph.AddVertex(vertex1, vertex1.Identifier); var graphDoublePrime = graphPrime.AddVertex(vertex2, vertex2.Identifier); var edgeLabel = 1; var graphTriplePrime = graphDoublePrime.AddEdge(vertex1, vertex2, edgeLabel); // Act var graphQuadruplePrime = graphTriplePrime.RemoveEdge(vertex1, vertex2); // Assert postconditions if (graphQuadruplePrime == graphTriplePrime) return Fail; return !graphQuadruplePrime.HasEdge(vertex1,vertex2) ? Pass : Fail; }
static string Update_Edge_ChangesEdgeLabelAndReturnsGPrime() { // Arrange preconditons var graph = new Digraph<char, int, int>(); var vertex1 = new Vertex<char, int>('a'); var vertex2 = new Vertex<char, int>('b'); var graphPrime = graph.AddVertex(vertex1, vertex1.Identifier); var graphDoublePrime = graphPrime.AddVertex(vertex2, vertex2.Identifier); var edgeLabel = 1; var graphTriplePrime = graphDoublePrime.AddEdge(vertex1, vertex2, edgeLabel); // Act var updatedEdgeLabel = 2; var graphQuadruplePrime = graphTriplePrime.UpdateEdge(vertex1, vertex2, updatedEdgeLabel); // Assert if (graphQuadruplePrime == graphTriplePrime) return Fail; if (graphQuadruplePrime.GetEdge(vertex1, vertex2) == edgeLabel) return Fail; return graphQuadruplePrime.GetEdge(vertex1, vertex2) == updatedEdgeLabel ? Pass : Fail; }