Ejemplo n.º 1
0
        public void MultiThreadedSyncedGraphAccessTest()
        {
            // set up our session.
            Guid sessionId = Guid.NewGuid();

            CQManager.ActivateCommandQueueStack(sessionId);

            var toTest = new DirectedGraph <int, DirectedEdge <int> >((a, b) => new DirectedEdge <int>(a, b), isCommandified: true, isSynchronized: true);

            for (int i = 0; i < 30; i++)
            {
                toTest.Add(new DirectedEdge <int>(i, i + 1));
                toTest.Add(new DirectedEdge <int>(i + 3, i));
            }

            var       waitHandles     = new WaitHandle[] { new AutoResetEvent(false), new AutoResetEvent(false) };
            Exception caughtException = null;

            Console.WriteLine("Starting threads...");
            var threadA = new Thread(() => MultiThreadedSyncedGraphAccessTest_ThreadA(toTest, waitHandles[0], (e) => caughtException = e));
            var threadB = new Thread(() => MultiThreadedSyncedGraphAccessTest_ThreadB(toTest, waitHandles[1], (e) => caughtException = e));

            threadA.Start();
            threadB.Start();
            Console.WriteLine("Threads started... waiting for handles");
            WaitHandle.WaitAll(waitHandles);
            if (caughtException != null)
            {
                throw caughtException;
            }
            Console.WriteLine("All completed.");
        }
Ejemplo n.º 2
0
        internal static DirectedGraph <Project, ProjectDependency> Parse(string solutionFilePath)
        {
            Dictionary <Project, IEnumerable <string> > projectsWithReferences = new Dictionary <Project, IEnumerable <string> >();

            foreach (string projectFilePath in Directory.EnumerateFiles(Path.GetDirectoryName(solutionFilePath), "*.csproj", SearchOption.AllDirectories))
            {
                projectsWithReferences.Add(new Project(GetProjectId(projectFilePath), GetProjectName(projectFilePath), projectFilePath), ProjectReader.GetProjectReferences(projectFilePath));
            }

            var graph = new DirectedGraph <Project, ProjectDependency>();

            Dictionary <string, Project> projects = projectsWithReferences.Keys.ToDictionary(p => p.Id, p => p);

            foreach (KeyValuePair <Project, IEnumerable <string> > projectsWithReference in projectsWithReferences)
            {
                graph.Add(projectsWithReference.Key);

                foreach (string projectReference in projectsWithReference.Value)
                {
                    graph.Add(new ProjectDependency(projectsWithReference.Key, projects[GetProjectId(projectReference)]));
                }
            }

            return(graph);
        }
Ejemplo n.º 3
0
        public static DirectedGraph <Entity> ColapseIdentifiables(DirectedGraph <Modifiable> modifiables)
        {
            DirectedGraph <Entity> result = new DirectedGraph <Entity>(modifiables.Comparer);

            foreach (var item in modifiables.OfType <Entity>())
            {
                var toColapse        = modifiables.IndirectlyRelatedTo(item, i => !(i is Entity));
                var toColapseFriends = toColapse.SelectMany(i => modifiables.RelatedTo(i).OfType <Entity>());
                result.Add(item, toColapseFriends);
                result.Add(item, modifiables.RelatedTo(item).OfType <Entity>());
            }
            return(result);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Creates and returns the dependency graph. The result will be cached.
        /// </summary>
        /// <param name="forceRecompute">Whether to force the recomputation of the dependency graph. If false, the cached graph will be used, if it has been previously computed.</param>
        public DirectedGraph <Type, DirectedEdge <Type> > CreateGraph(bool forceRecompute = false)
        {
            if (!forceRecompute && cachedGraph != null)
            {
                return(cachedGraph);
            }

            var graphNodes = container.Kernel.GraphNodes;
            var graph      = new DirectedGraph <Type, DirectedEdge <Type> >();

            //Build the nodes
            foreach (var graphNode in graphNodes)
            {
                if (graphNode is ComponentModel componentModel)
                {
                    foreach (var service in componentModel.Services)
                    {
                        if (!graph.Contains(service))
                        {
                            graph.Add(service);
                        }
                    }

                    if (!graph.Contains(componentModel.Implementation))
                    {
                        graph.Add(componentModel.Implementation);
                    }
                }
            }

            //Build the edges
            foreach (var graphNode in graphNodes)
            {
                if (graphNode is ComponentModel componentModel)
                {
                    foreach (var dep in componentModel.Dependencies)
                    {
                        foreach (var service in componentModel.Services)
                        {
                            graph.Add(new DirectedEdge <Type>(service, dep.TargetItemType));
                        }

                        graph.Add(new DirectedEdge <Type>(componentModel.Implementation, dep.TargetItemType));
                    }
                }
            }

            cachedGraph = graph;
            return(graph);
        }
Ejemplo n.º 5
0
    public DirectedGraph <T> Inverse()
    {
        DirectedGraph <T> result = new DirectedGraph <T>(Comparer);

        foreach (var item in Nodes)
        {
            result.Add(item);
            foreach (var related in RelatedTo(item))
            {
                result.Add(related, item);
            }
        }
        return(result);
    }
Ejemplo n.º 6
0
        public void IsConnected2Test()
        {
            DirectedGraph <string, DirectedEdge <string> > graph = new DirectedGraph <string, DirectedEdge <string> >();

            graph.Add(new DirectedEdge <string>("A", "B")); // A->B
            graph.Add("C");                                 // lonely, non-connected vertex

            Assert.IsFalse(graph.IsConnected());

            // Add a connected edge.
            DirectedEdge <string> toAdd = new DirectedEdge <string>("C", "B");

            graph.Add(toAdd);

            Assert.IsTrue(graph.IsConnected());
        }
Ejemplo n.º 7
0
        public void GraphTestMethod4()
        {
            var g = new DirectedGraph <int>();

            for (var i = 0; i < 10; i++)
            {
                g.Add(i);
            }
            Assert.IsTrue(g.Add(1, 5));
            Assert.IsTrue(g.Add(1, 30));
            Assert.IsTrue(g.Vertices.Contains(30));
            Assert.IsFalse(g.Add(1, 30));
            g.Add(1, 20, true);
            Assert.AreEqual(11, g.VerticesCount);
            Assert.AreEqual(3, g.EdgesCount);
        }
Ejemplo n.º 8
0
        static void TryCacheSubTables(Type type, SchemaBuilder sb)
        {
            List <Type> relatedTypes = sb.Schema.Table(type).DependentTables()
                                       .Where(a => !a.Value.IsEnum)
                                       .Select(t => t.Key.Type).ToList();

            dependencies.Add(type);
            inverseDependencies.Add(type);

            foreach (var rType in relatedTypes)
            {
                TryCacheTable(sb, rType);

                dependencies.Add(type, rType);
                inverseDependencies.Add(rType, type);
            }
        }
Ejemplo n.º 9
0
        public void TopologicalSorterOnDirectedAcyclicGraphWhereDirectionMeansOrder()
        {
            DirectedGraph <string, DirectedEdge <string> > graph = new DirectedGraph <string, DirectedEdge <string> >();

            graph.Add(new DirectedEdge <string>("A", "B"));             // A->B
            graph.Add(new DirectedEdge <string>("A", "C"));             // A->C
            graph.Add(new DirectedEdge <string>("B", "D"));             // B->D
            graph.Add(new DirectedEdge <string>("C", "D"));             // C->D
            graph.Add(new DirectedEdge <string>("D", "E"));             // D->E
            graph.Add(new DirectedEdge <string>("H", "G"));             // H->G
            graph.Add(new DirectedEdge <string>("G", "F"));             // G->F

            TopologicalSorter <string, DirectedEdge <string> > sorter = new TopologicalSorter <string, DirectedEdge <string> >(graph, true);

            sorter.Sort();
            List <string> expectedResults = new List <string>()
            {
                "H", "G", "F", "A", "C", "B", "D", "E"
            };

            for (int i = 0; i < sorter.SortResults.Count; i++)
            {
                Assert.AreEqual(expectedResults[i], sorter.SortResults[i]);
            }
        }
Ejemplo n.º 10
0
        public void IsConnectedTest()
        {
            DirectedGraph <string, DirectedEdge <string> > graph = new DirectedGraph <string, DirectedEdge <string> >();

            graph.Add(new DirectedEdge <string>("A", "B"));             // A->B
            graph.Add(new DirectedEdge <string>("A", "C"));             // A->C
            graph.Add(new DirectedEdge <string>("B", "D"));             // B->D
            graph.Add(new DirectedEdge <string>("C", "D"));             // C->D
            graph.Add(new DirectedEdge <string>("D", "E"));             // D->E

            Assert.IsTrue(graph.IsConnected());

            // Add an un-connected edge.
            DirectedEdge <string> toAdd = new DirectedEdge <string>("G", "F");

            graph.Add(toAdd);

            Assert.IsFalse(graph.IsConnected());

            // Add a directed edge from F to A.
            toAdd = new DirectedEdge <string>("F", "A");
            graph.Add(toAdd);

            Assert.IsTrue(graph.IsConnected());
        }
Ejemplo n.º 11
0
 public TestGraph(int count)
 {
     nodes = new Dictionary <char, Node <string, int> >(count);
     graph = new DirectedGraph <string, int>();
     for (int i = 0; i < count; i++)
     {
         var key = (char)('A' + i);
         nodes.Add(key, graph.Add(key.ToString()));
     }
 }
Ejemplo n.º 12
0
    public DirectedGraph <T> WhereEdges(Func <Edge <T>, bool> condition)
    {
        DirectedGraph <T> result = new DirectedGraph <T>(Comparer);

        foreach (var item in Nodes)
        {
            result.Add(item, RelatedTo(item).Where(to => condition(new Edge <T>(item, to))));
        }
        return(result);
    }
Ejemplo n.º 13
0
        /// <summary>
        /// Generates a random integer graph of maxSize size. Size here denotes the amount of edges, nodes may be up to
        /// twice that amount.
        /// </summary>
        /// <param name="maxSize">The maximum amount of edges the graph contains.</param>
        /// <returns>The randomly generated graph.</returns>
        private DirectedGraph <int, DirectedEdge <int> > GenerateRandomIntegerDirectedGraph(int maxSize)
        {
            int size = _random.Next(maxSize);
            // create an integer graph and set the edge producer func
            DirectedGraph <int, DirectedEdge <int> > graph = new DirectedGraph <int, DirectedEdge <int> >((a, b) => new DirectedEdge <int>(a, b));

            for (int i = 0; i < size;)
            {
                int startNode = _random.Next(maxSize);
                int endNode   = _random.Next(maxSize);
                if (!graph.ContainsEdge(startNode, endNode))
                {
                    graph.Add(startNode);
                    graph.Add(endNode);
                    graph.Add(new DirectedEdge <int>(startNode, endNode));
                    i++;
                }
            }
            return(graph);
        }
Ejemplo n.º 14
0
        public void AsNonDirectedGraphTest()
        {
            DirectedGraph <string, DirectedEdge <string> > graph = new DirectedGraph <string, DirectedEdge <string> >();

            graph.Add(new DirectedEdge <string>("A", "B"));             // A->B
            graph.Add(new DirectedEdge <string>("A", "C"));             // A->C
            graph.Add(new DirectedEdge <string>("B", "D"));             // B->D
            graph.Add(new DirectedEdge <string>("C", "D"));             // C->D
            graph.Add(new DirectedEdge <string>("D", "E"));             // D->E

            Assert.IsTrue(graph.IsDirected);
            Assert.IsTrue(graph.EdgeCount == 5);

            NonDirectedGraph <string, NonDirectedEdge <string> > nonDirectedGraph = (NonDirectedGraph <string, NonDirectedEdge <string> >)graph.GetAsNonDirectedCopy();

            Assert.IsFalse(nonDirectedGraph.IsDirected);

            Assert.IsTrue(nonDirectedGraph.ContainsEdge("A", "B"));
            Assert.IsTrue(nonDirectedGraph.ContainsEdge("B", "A"));

            Assert.IsTrue(nonDirectedGraph.ContainsEdge("A", "C"));
            Assert.IsTrue(nonDirectedGraph.ContainsEdge("C", "A"));

            Assert.IsTrue(nonDirectedGraph.ContainsEdge("B", "D"));
            Assert.IsTrue(nonDirectedGraph.ContainsEdge("D", "B"));

            Assert.IsTrue(nonDirectedGraph.ContainsEdge("C", "D"));
            Assert.IsTrue(nonDirectedGraph.ContainsEdge("D", "C"));

            Assert.IsTrue(nonDirectedGraph.ContainsEdge("D", "E"));
            Assert.IsTrue(nonDirectedGraph.ContainsEdge("E", "D"));

            foreach (Edge <string> edge in nonDirectedGraph.Edges)
            {
                Console.Write("\n\nEdge Start index: " + edge.StartVertex + "\tEdge End index:" + edge.EndVertex + "\n\t");

                Assert.IsFalse(edge.IsDirected);
            }

            //Assert.IsTrue(nonDirectedGraph.EdgeCount == 10);
        }
Ejemplo n.º 15
0
        public void TransitiveClosureCyclicTest()
        {
            var g = new DirectedGraph <int, DirectedEdge <int> >((a, b) => new DirectedEdge <int>(a, b), isCommandified: false, isSynchronized: true);

            g.Add(new DirectedEdge <int>(1, 2));
            g.Add(new DirectedEdge <int>(2, 3));
            g.Add(new DirectedEdge <int>(3, 1));
            DirectedGraph <int, DirectedEdge <int> > h = g.TransitiveClosure();

            Assert.AreEqual(3, h.VertexCount);
            Assert.AreEqual(9, h.EdgeCount);
            Assert.IsTrue(h.ContainsEdge(1, 2));
            Assert.IsTrue(h.ContainsEdge(2, 3));
            Assert.IsTrue(h.ContainsEdge(3, 1));
            Assert.IsTrue(h.ContainsEdge(1, 3));
            Assert.IsTrue(h.ContainsEdge(1, 1));
            Assert.IsTrue(h.ContainsEdge(2, 1));
            Assert.IsTrue(h.ContainsEdge(2, 2));
            Assert.IsTrue(h.ContainsEdge(3, 2));
            Assert.IsTrue(h.ContainsEdge(3, 3));
        }
Ejemplo n.º 16
0
        public void TransitiveClosureBasicTest()
        {
            // create an integer graph and set the edge producer func
            DirectedGraph <int, DirectedEdge <int> > g = new DirectedGraph <int, DirectedEdge <int> >((a, b) => new DirectedEdge <int>(a, b));
            DirectedEdge <int> toAdd = new DirectedEdge <int>(1, 2);

            g.Add(toAdd);
            Assert.IsTrue(g.Contains(toAdd));
            g.Add(new DirectedEdge <int>(2, 3));
            g.Add(new DirectedEdge <int>(3, 4));
            DirectedGraph <int, DirectedEdge <int> > h = g.TransitiveClosure();

            Assert.IsTrue(h.VertexCount == 4);
            Assert.IsTrue(h.EdgeCount == 6);
            Assert.IsTrue(h.ContainsEdge(1, 2));
            Assert.IsTrue(h.ContainsEdge(2, 3));
            Assert.IsTrue(h.ContainsEdge(3, 4));
            Assert.IsTrue(h.ContainsEdge(1, 3));
            Assert.IsTrue(h.ContainsEdge(1, 4));
            Assert.IsTrue(h.ContainsEdge(2, 4));
        }
Ejemplo n.º 17
0
        public void TransitiveClosureCyclicTest()
        {
            DirectedGraph <int, DirectedEdge <int> > g = new DirectedGraph <int, DirectedEdge <int> >((a, b) => new DirectedEdge <int>(a, b));

            g.Add(new DirectedEdge <int>(1, 2));
            g.Add(new DirectedEdge <int>(2, 3));
            g.Add(new DirectedEdge <int>(3, 1));
            DirectedGraph <int, DirectedEdge <int> > h = g.TransitiveClosure();

            Assert.AreEqual(3, h.VertexCount);
            Assert.AreEqual(9, h.EdgeCount);
            Assert.IsTrue(h.ContainsEdge(1, 2));
            Assert.IsTrue(h.ContainsEdge(2, 3));
            Assert.IsTrue(h.ContainsEdge(3, 1));
            Assert.IsTrue(h.ContainsEdge(1, 3));
            Assert.IsTrue(h.ContainsEdge(1, 1));
            Assert.IsTrue(h.ContainsEdge(2, 1));
            Assert.IsTrue(h.ContainsEdge(2, 2));
            Assert.IsTrue(h.ContainsEdge(3, 2));
            Assert.IsTrue(h.ContainsEdge(3, 3));
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Merges the ancestors of all nodes (recursively) if any node has multiple ancestors (i.e. multiple incoming edges). The input graph will not be mutated.
        /// If any nodes which are to be merged have edges between them, the merging will create loops, unless <paramref name="eliminateLoopsFromMergedNodes"/> is true.
        /// </summary>
        /// <typeparam name="TVertex">The type of the vertices.</typeparam>
        /// <param name="g">The graph.</param>
        /// <param name="eliminateLoopsFromMergedNodes">If true, any loop that would be created for a merged node due to the nodes to be merged having edges among them is removed.</param>
        /// <returns>The mutated input graph if there were no cycles in the original graph, and <see cref="Maybe.Nothing{T}"/> otherwise.</returns>
        public static Maybe <DirectedGraph <IFuncSet <TVertex>, DirectedEdge <IFuncSet <TVertex> > > > MergeAncestors <TVertex>(
            this DirectedGraph <TVertex, DirectedEdge <TVertex> > g,
            bool eliminateLoopsFromMergedNodes = false)
            where TVertex : IEquatable <TVertex>
        {
            var copy = new DirectedGraph <IFuncSet <TVertex>, DirectedEdge <IFuncSet <TVertex> > >();

            g.Vertices.ForEach(v => copy.Add(new FuncSet <TVertex> {
                v
            }));
            g.Edges.ForEach(e => copy.Add(new DirectedEdge <IFuncSet <TVertex> >(new FuncSet <TVertex> {
                e.StartVertex
            }, new FuncSet <TVertex> {
                e.EndVertex
            })));

            var ret = copy.MergeAncestors <DirectedGraph <IFuncSet <TVertex>, DirectedEdge <IFuncSet <TVertex> > >, IFuncSet <TVertex> >(
                vs => new FuncSet <TVertex>(vs.Concat()),
                (s, e) => new DirectedEdge <IFuncSet <TVertex> >(s, e),
                (xs, ys) => xs.IsSupersetOf(ys), eliminateLoopsFromMergedNodes);

            return(ret);
        }
Ejemplo n.º 19
0
        public void TopologicalSorterOnDirectedGraphWithCycle()
        {
            DirectedGraph <string, DirectedEdge <string> > graph = new DirectedGraph <string, DirectedEdge <string> >();

            graph.Add(new DirectedEdge <string>("A", "B"));             // A->B
            graph.Add(new DirectedEdge <string>("A", "C"));             // A->C
            graph.Add(new DirectedEdge <string>("B", "D"));             // B->D
            graph.Add(new DirectedEdge <string>("C", "D"));             // C->D
            graph.Add(new DirectedEdge <string>("D", "E"));             // D->E
            graph.Add(new DirectedEdge <string>("E", "A"));             // E->A, creates cycle A, B/C, D, E, A
            graph.Add(new DirectedEdge <string>("H", "G"));             // H->G
            graph.Add(new DirectedEdge <string>("G", "F"));             // G->F

            TopologicalSorter <string, DirectedEdge <string> > sorter = new TopologicalSorter <string, DirectedEdge <string> >(graph);

            sorter.Sort();
        }
Ejemplo n.º 20
0
        public void TestClone()
        {
            var original = new DirectedGraph <string, string>()
            {
                "a",
                "b",
                { "a", "b", "a-b" },
            };

            var cloned = original.Clone() as DirectedGraph <string, string>;

            original.Add("c");

            Assert.False(cloned.Contains("c"));
        }
Ejemplo n.º 21
0
        public void TopologicalSorterOnDirectedGraphWithCycle()
        {
            DirectedGraph <string, DirectedEdge <string> > graph = new DirectedGraph <string, DirectedEdge <string> >();

            graph.Add(new DirectedEdge <string>("A", "B"));             // A->B
            graph.Add(new DirectedEdge <string>("A", "C"));             // A->C
            graph.Add(new DirectedEdge <string>("B", "D"));             // B->D
            graph.Add(new DirectedEdge <string>("C", "D"));             // C->D
            graph.Add(new DirectedEdge <string>("D", "E"));             // D->E
            graph.Add(new DirectedEdge <string>("E", "A"));             // E->A, creates cycle A, B/C, D, E, A
            graph.Add(new DirectedEdge <string>("H", "G"));             // H->G
            graph.Add(new DirectedEdge <string>("G", "F"));             // G->F

            TopologicalSorter <string, DirectedEdge <string> > sorter = new TopologicalSorter <string, DirectedEdge <string> >(graph);

            Assert.That(() => sorter.Sort(), Throws.TypeOf <InvalidOperationException>());
        }
Ejemplo n.º 22
0
        static void AssertOrder(TestGraph graph, string expected)
        {
            var order = graph.TopologicalSort();

            AssertOrder(order, expected);

            var orderedGraph = new DirectedGraph <string, int>();

            foreach (var node in order)
            {
                orderedGraph.Add(node);
            }
            var secondOrder = orderedGraph.TopologicalSort();

            AssertOrder(secondOrder, expected);
        }
Ejemplo n.º 23
0
        public void DikastraMinDistanceTest()
        {
            var graph = new DirectedGraph <string>();

            graph.Add(new DirectedEdge <string>("B", "A", 2));
            graph.Add(new DirectedEdge <string>("A", "C", 5));
            graph.Add(new DirectedEdge <string>("C", "B", 15));
            graph.Add(new DirectedEdge <string>("A", "D", 30));
            graph.Add(new DirectedEdge <string>("B", "E", 8));
            graph.Add(new DirectedEdge <string>("E", "D", 4));
            graph.Add(new DirectedEdge <string>("C", "F", 7));
            graph.Add(new DirectedEdge <string>("F", "E", 18));
            graph.Add(new DirectedEdge <string>("F", "D", 10));
            var dikastra = graph.DikastraMinDistance("A");

            Assert.AreEqual(20, dikastra["B"].Distance);
            Assert.AreEqual(1, dikastra["B"].RouteVertexs.Count);
            Assert.AreEqual("C", dikastra["B"].RouteVertexs[0]);

            Assert.AreEqual(5, dikastra["C"].Distance);
            Assert.AreEqual(0, dikastra["C"].RouteVertexs.Count);

            Assert.AreEqual(22, dikastra["D"].Distance);
            Assert.AreEqual(2, dikastra["D"].RouteVertexs.Count);
            Assert.AreEqual("C", dikastra["D"].RouteVertexs[0]);
            Assert.AreEqual("F", dikastra["D"].RouteVertexs[1]);

            Assert.AreEqual(28, dikastra["E"].Distance);
            Assert.AreEqual(2, dikastra["E"].RouteVertexs.Count);
            Assert.AreEqual("C", dikastra["E"].RouteVertexs[0]);
            Assert.AreEqual("B", dikastra["E"].RouteVertexs[1]);

            Assert.AreEqual(12, dikastra["F"].Distance);
            Assert.AreEqual(1, dikastra["F"].RouteVertexs.Count);
            Assert.AreEqual("C", dikastra["F"].RouteVertexs[0]);
        }
Ejemplo n.º 24
0
        public void TopologicalSortTest()
        {
            var graph = new DirectedGraph <string>();

            graph.Add(new DirectedEdge <string>("c1", "c2"));
            graph.Add(new DirectedEdge <string>("c2", "c6"));
            graph.Add(new DirectedEdge <string>("c1", "c3"));
            graph.Add(new DirectedEdge <string>("c3", "c6"));
            graph.Add(new DirectedEdge <string>("c4", "c3"));
            graph.Add(new DirectedEdge <string>("c4", "c5"));
            graph.Add(new DirectedEdge <string>("c5", "c6"));

            List <string> topological;
            var           has_loop = graph.TopologicalSort(out topological);

            Assert.IsFalse(has_loop);
        }
Ejemplo n.º 25
0
        public void OrphanedVerticesRetrievalTest()
        {
            DirectedGraph <string, DirectedEdge <string> > graph = new DirectedGraph <string, DirectedEdge <string> >();

            graph.Add(new DirectedEdge <string>("A", "B"));             // A->B
            graph.Add(new DirectedEdge <string>("A", "C"));             // A->C
            graph.Add(new DirectedEdge <string>("B", "D"));             // B->D
            graph.Add(new DirectedEdge <string>("C", "D"));             // C->D
            graph.Add(new DirectedEdge <string>("D", "E"));             // D->E
            graph.Add(new DirectedEdge <string>("H", "G"));             // H->G
            DirectedEdge <string> toAdd = new DirectedEdge <string>("G", "F");

            graph.Add(toAdd);                   // G->F
            graph.Remove(toAdd);
            HashSet <string> orphanedVertices = graph.GetOrphanedVertices();

            Assert.AreEqual(1, orphanedVertices.Count);
            Assert.IsTrue(orphanedVertices.Contains("F"));
        }
Ejemplo n.º 26
0
        public void GraphTestMethod1()
        {
            var g = new DirectedGraph <int>();

            for (var i = 0; i < 10; i++)
            {
                g.Add(i);
            }
            Assert.IsTrue(g.Add(1, 2));
            Assert.IsTrue(g.Add(2, 3));
            Assert.IsFalse(g.Add(2, 3));
            Assert.IsTrue(g.Add(9, 3));
            Assert.IsTrue(g.Add(7, 8));
            Assert.AreEqual(10, g.VerticesCount);
            Assert.AreEqual(4, g.EdgesCount);
        }
Ejemplo n.º 27
0
        public void RemoveOrphanedVerticesWhenEdgeIsRemovedTest()
        {
            DirectedGraph <string, DirectedEdge <string> > graph = new DirectedGraph <string, DirectedEdge <string> >();

            graph.Add(new DirectedEdge <string>("A", "B"));             // A->B
            graph.Add(new DirectedEdge <string>("A", "C"));             // A->C
            graph.Add(new DirectedEdge <string>("B", "D"));             // B->D
            graph.Add(new DirectedEdge <string>("C", "D"));             // C->D
            graph.Add(new DirectedEdge <string>("D", "E"));             // D->E
            graph.Add(new DirectedEdge <string>("H", "G"));             // H->G
            DirectedEdge <string> toAdd = new DirectedEdge <string>("G", "F");

            graph.Add(toAdd);                   // G->F
            graph.RemoveOrphanedVerticesOnEdgeRemoval = true;
            graph.Remove(toAdd);
            HashSet <string> orphanedVertices = graph.GetOrphanedVertices();

            Assert.AreEqual(0, orphanedVertices.Count);
            Assert.IsFalse(graph.Contains("F"));
        }
Ejemplo n.º 28
0
        public void CommandifiedGraphAddRemoveVertexWithUndoTest()
        {
            Guid sessionId = Guid.NewGuid();

            CQManager.ActivateCommandQueueStack(sessionId);

            DirectedGraph <int, DirectedEdge <int> > graph = new DirectedGraph <int, DirectedEdge <int> >(true);

            graph.Add(42);
            Assert.IsTrue(graph.Contains(42));
            CQManager.UndoLastCommand();
            Assert.IsFalse(graph.Contains(42));
            Assert.AreEqual(0, graph.VertexCount);

            graph.Add(42);
            graph.Add(13);
            graph.Add(10);
            Assert.IsTrue(graph.Contains(42));
            Assert.IsTrue(graph.Contains(13));
            Assert.IsTrue(graph.Contains(10));

            graph.Add(new DirectedEdge <int>(42, 13));                  // 42 -> 13
            graph.Add(new DirectedEdge <int>(42, 10));                  // 42 -> 10
            Assert.AreEqual(2, graph.EdgeCount);
            Assert.IsTrue(graph.ContainsEdge(42, 13));
            Assert.IsTrue(graph.ContainsEdge(42, 10));

            graph.Remove(42);
            Assert.IsFalse(graph.Contains(42));
            Assert.AreEqual(0, graph.EdgeCount);
            Assert.AreEqual(2, graph.VertexCount);

            // undo removal of 42. This should re-add 42, but also re-add the edges
            CQManager.UndoLastCommand();
            Assert.AreEqual(2, graph.EdgeCount);
            Assert.IsTrue(graph.ContainsEdge(42, 13));
            Assert.IsTrue(graph.ContainsEdge(42, 10));
            Assert.IsTrue(graph.Contains(42));

            CQManager.ActivateCommandQueueStack(Guid.Empty);
        }
Ejemplo n.º 29
0
        public void CommandifiedGraphAddRemoveVertexWithUndoTest()
        {
            Guid sessionId = Guid.NewGuid();
            CQManager.ActivateCommandQueueStack(sessionId);

            DirectedGraph<int, DirectedEdge<int>> graph = new DirectedGraph<int, DirectedEdge<int>>(true);
            graph.Add(42);
            Assert.IsTrue(graph.Contains(42));
            CQManager.UndoLastCommand();
            Assert.IsFalse(graph.Contains(42));
            Assert.AreEqual(0, graph.VertexCount);

            graph.Add(42);
            graph.Add(13);
            graph.Add(10);
            Assert.IsTrue(graph.Contains(42));
            Assert.IsTrue(graph.Contains(13));
            Assert.IsTrue(graph.Contains(10));

            graph.Add(new DirectedEdge<int>(42, 13));	// 42 -> 13
            graph.Add(new DirectedEdge<int>(42, 10));	// 42 -> 10
            Assert.AreEqual(2, graph.EdgeCount);
            Assert.IsTrue(graph.ContainsEdge(42, 13));
            Assert.IsTrue(graph.ContainsEdge(42, 10));

            graph.Remove(42);
            Assert.IsFalse(graph.Contains(42));
            Assert.AreEqual(0, graph.EdgeCount);
            Assert.AreEqual(2, graph.VertexCount);

            // undo removal of 42. This should re-add 42, but also re-add the edges
            CQManager.UndoLastCommand();
            Assert.AreEqual(2, graph.EdgeCount);
            Assert.IsTrue(graph.ContainsEdge(42, 13));
            Assert.IsTrue(graph.ContainsEdge(42, 10));
            Assert.IsTrue(graph.Contains(42));

            CQManager.ActivateCommandQueueStack(Guid.Empty);
        }
Ejemplo n.º 30
0
        public void CommandifiedGraphAddRemoveGraphAndEdgesWithUndoTest()
        {
            Guid sessionId = Guid.NewGuid();

            CQManager.ActivateCommandQueueStack(sessionId);

            DirectedGraph <int, DirectedEdge <int> > graph = new DirectedGraph <int, DirectedEdge <int> >(true);

            graph.Add(42);
            graph.Add(13);
            graph.Add(10);
            graph.Add(new DirectedEdge <int>(42, 13));                  // 42 -> 13
            graph.Add(new DirectedEdge <int>(42, 10));                  // 42 -> 10
            Assert.IsTrue(graph.Contains(42));
            Assert.IsTrue(graph.Contains(13));
            Assert.IsTrue(graph.Contains(10));
            Assert.AreEqual(2, graph.EdgeCount);
            Assert.IsTrue(graph.ContainsEdge(42, 13));
            Assert.IsTrue(graph.ContainsEdge(42, 10));

            // create graph to add to this graph. Doesn't have to be a commandified graph, as we're not rolling back the actions on that graph.
            DirectedGraph <int, DirectedEdge <int> > graphToAdd = new DirectedGraph <int, DirectedEdge <int> >();

            graphToAdd.Add(1);
            graphToAdd.Add(2);
            graphToAdd.Add(3);
            graphToAdd.Add(new DirectedEdge <int>(1, 2));               // 1 -> 2
            graphToAdd.Add(new DirectedEdge <int>(1, 3));               // 1 -> 3
            graphToAdd.Add(new DirectedEdge <int>(2, 3));               // 2 -> 3
            Assert.AreEqual(3, graphToAdd.VertexCount);
            Assert.AreEqual(3, graphToAdd.EdgeCount);

            // add this graph to the main graph. This is an undoable action.
            graph.Add(graphToAdd);
            Assert.AreEqual(6, graph.VertexCount);
            Assert.AreEqual(5, graph.EdgeCount);
            Assert.IsTrue(graph.Contains(1));
            Assert.IsTrue(graph.Contains(2));
            Assert.IsTrue(graph.Contains(3));
            Assert.IsTrue(graph.ContainsEdge(1, 2));
            Assert.IsTrue(graph.ContainsEdge(1, 3));
            Assert.IsTrue(graph.ContainsEdge(2, 3));

            // undo add
            CQManager.UndoLastCommand();
            Assert.AreEqual(3, graph.VertexCount);
            Assert.AreEqual(2, graph.EdgeCount);
            Assert.IsFalse(graph.Contains(1));
            Assert.IsFalse(graph.Contains(2));
            Assert.IsFalse(graph.Contains(3));
            Assert.IsFalse(graph.ContainsEdge(1, 2));
            Assert.IsFalse(graph.ContainsEdge(1, 3));
            Assert.IsFalse(graph.ContainsEdge(2, 3));

            // redo
            CQManager.RedoLastCommand();
            Assert.AreEqual(6, graph.VertexCount);
            Assert.AreEqual(5, graph.EdgeCount);
            Assert.IsTrue(graph.Contains(1));
            Assert.IsTrue(graph.Contains(2));
            Assert.IsTrue(graph.Contains(3));
            Assert.IsTrue(graph.ContainsEdge(1, 2));
            Assert.IsTrue(graph.ContainsEdge(1, 3));
            Assert.IsTrue(graph.ContainsEdge(2, 3));

            // remove the graph we added
            graph.Remove(graphToAdd);
            Assert.AreEqual(3, graph.VertexCount);
            Assert.AreEqual(2, graph.EdgeCount);
            Assert.IsFalse(graph.Contains(1));
            Assert.IsFalse(graph.Contains(2));
            Assert.IsFalse(graph.Contains(3));
            Assert.IsFalse(graph.ContainsEdge(1, 2));
            Assert.IsFalse(graph.ContainsEdge(1, 3));
            Assert.IsFalse(graph.ContainsEdge(2, 3));

            CQManager.UndoLastCommand();
            Assert.AreEqual(6, graph.VertexCount);
            Assert.AreEqual(5, graph.EdgeCount);
            Assert.IsTrue(graph.Contains(1));
            Assert.IsTrue(graph.Contains(2));
            Assert.IsTrue(graph.Contains(3));
            Assert.IsTrue(graph.ContainsEdge(1, 2));
            Assert.IsTrue(graph.ContainsEdge(1, 3));
            Assert.IsTrue(graph.ContainsEdge(2, 3));

            DirectedEdge <int> newEdge = new DirectedEdge <int>(42, 1);                         // 42 -> 1

            graph.Add(newEdge);
            Assert.AreEqual(6, graph.EdgeCount);
            Assert.IsTrue(graph.ContainsEdge(42, 1));
            Assert.IsFalse(graph.ContainsEdge(1, 42));

            CQManager.UndoLastCommand();
            Assert.AreEqual(5, graph.EdgeCount);
            Assert.IsFalse(graph.ContainsEdge(42, 1));

            CQManager.RedoLastCommand();
            Assert.AreEqual(6, graph.EdgeCount);
            Assert.IsTrue(graph.ContainsEdge(42, 1));

            graph.Remove(newEdge);
            Assert.AreEqual(5, graph.EdgeCount);
            Assert.IsFalse(graph.ContainsEdge(42, 1));

            CQManager.UndoLastCommand();
            Assert.AreEqual(6, graph.EdgeCount);
            Assert.IsTrue(graph.ContainsEdge(42, 1));

            graph.Disconnect(42, 1, false);
            Assert.AreEqual(5, graph.EdgeCount);
            Assert.IsFalse(graph.ContainsEdge(42, 1));

            CQManager.UndoLastCommand();
            Assert.AreEqual(6, graph.EdgeCount);
            Assert.IsTrue(graph.ContainsEdge(42, 1));

            CQManager.ActivateCommandQueueStack(Guid.Empty);
        }
Ejemplo n.º 31
0
    /// <summary>
    /// A simple but effective linear-time heuristic constructs a vertex ordering,
    /// just as in the topological sort heuristic above, and deletes any arc going from right to left.
    ///
    /// This heuristic builds up the ordering from the outside in based on the in- and out-degrees of each vertex.
    /// - Any vertex of in-degree 0 is a source and can be placed first in the ordering.
    /// - Any vertex of out-degree 0 is a sink and can be placed last in the ordering, again without violating any constraints.
    /// - If not, we find the vertex with the maximum difference between in- and out-degree,
    /// and place it on the side of the permutation that will salvage the greatest number of constraints.
    /// Delete any vertex from the DAG after positioning it and repeat until the graph is empty.
    /// </summary>
    /// <returns></returns>

    public DirectedGraph <T> FeedbackEdgeSet()
    {
        DirectedGraph <T> result = new DirectedGraph <T>(Comparer);

        DirectedGraph <T> clone = this.Clone();
        DirectedGraph <T> inv   = this.Inverse();

        HashSet <T> head = new HashSet <T>();  // for sources
        HashSet <T> tail = new HashSet <T>();  // for sinks

        while (clone.Count > 0)
        {
            var sinks = clone.Sinks();
            if (sinks.Count() != 0)
            {
                foreach (var sink in sinks)
                {
                    DirectedGraph <T> .RemoveFullNodeSymetric(clone, inv, sink);

                    tail.Add(sink);
                }
                continue;
            }

            var sources = inv.Sinks();
            if (sources.Count() != 0)
            {
                foreach (var source in sources)
                {
                    DirectedGraph <T> .RemoveFullNodeSymetric(clone, inv, source);

                    head.Add(source);
                }
                continue;
            }

            int fanInOut(T n) => clone.RelatedTo(n).Count() - inv.RelatedTo(n).Count();

            MinMax <T> mm = clone.MinMaxBy(fanInOut);

            if (fanInOut(mm.Max) > -fanInOut(mm.Min))
            {
                T node = mm.Max;
                foreach (var n in inv.RelatedTo(node))
                {
                    result.Add(node, n);
                }
                DirectedGraph <T> .RemoveFullNodeSymetric(clone, inv, node);

                head.Add(node);
            }
            else
            {
                T node = mm.Min;
                foreach (var n in clone.RelatedTo(node))
                {
                    result.Add(node, n);
                }
                DirectedGraph <T> .RemoveFullNodeSymetric(clone, inv, node);

                head.Add(node);
            }
        }

        return(result);
    }
Ejemplo n.º 32
0
        public void CommandifiedGraphAddRemoveGraphAndEdgesWithUndoTest()
        {
            Guid sessionId = Guid.NewGuid();
            CQManager.ActivateCommandQueueStack(sessionId);

            DirectedGraph<int, DirectedEdge<int>> graph = new DirectedGraph<int, DirectedEdge<int>>(true);
            graph.Add(42);
            graph.Add(13);
            graph.Add(10);
            graph.Add(new DirectedEdge<int>(42, 13));	// 42 -> 13
            graph.Add(new DirectedEdge<int>(42, 10));	// 42 -> 10
            Assert.IsTrue(graph.Contains(42));
            Assert.IsTrue(graph.Contains(13));
            Assert.IsTrue(graph.Contains(10));
            Assert.AreEqual(2, graph.EdgeCount);
            Assert.IsTrue(graph.ContainsEdge(42, 13));
            Assert.IsTrue(graph.ContainsEdge(42, 10));

            // create graph to add to this graph. Doesn't have to be a commandified graph, as we're not rolling back the actions on that graph.
            DirectedGraph<int, DirectedEdge<int>> graphToAdd = new DirectedGraph<int, DirectedEdge<int>>();
            graphToAdd.Add(1);
            graphToAdd.Add(2);
            graphToAdd.Add(3);
            graphToAdd.Add(new DirectedEdge<int>(1, 2));	// 1 -> 2
            graphToAdd.Add(new DirectedEdge<int>(1, 3));	// 1 -> 3
            graphToAdd.Add(new DirectedEdge<int>(2, 3));	// 2 -> 3
            Assert.AreEqual(3, graphToAdd.VertexCount);
            Assert.AreEqual(3, graphToAdd.EdgeCount);

            // add this graph to the main graph. This is an undoable action.
            graph.Add(graphToAdd);
            Assert.AreEqual(6, graph.VertexCount);
            Assert.AreEqual(5, graph.EdgeCount);
            Assert.IsTrue(graph.Contains(1));
            Assert.IsTrue(graph.Contains(2));
            Assert.IsTrue(graph.Contains(3));
            Assert.IsTrue(graph.ContainsEdge(1, 2));
            Assert.IsTrue(graph.ContainsEdge(1, 3));
            Assert.IsTrue(graph.ContainsEdge(2, 3));

            // undo add
            CQManager.UndoLastCommand();
            Assert.AreEqual(3, graph.VertexCount);
            Assert.AreEqual(2, graph.EdgeCount);
            Assert.IsFalse(graph.Contains(1));
            Assert.IsFalse(graph.Contains(2));
            Assert.IsFalse(graph.Contains(3));
            Assert.IsFalse(graph.ContainsEdge(1, 2));
            Assert.IsFalse(graph.ContainsEdge(1, 3));
            Assert.IsFalse(graph.ContainsEdge(2, 3));

            // redo
            CQManager.RedoLastCommand();
            Assert.AreEqual(6, graph.VertexCount);
            Assert.AreEqual(5, graph.EdgeCount);
            Assert.IsTrue(graph.Contains(1));
            Assert.IsTrue(graph.Contains(2));
            Assert.IsTrue(graph.Contains(3));
            Assert.IsTrue(graph.ContainsEdge(1, 2));
            Assert.IsTrue(graph.ContainsEdge(1, 3));
            Assert.IsTrue(graph.ContainsEdge(2, 3));

            // remove the graph we added
            graph.Remove(graphToAdd);
            Assert.AreEqual(3, graph.VertexCount);
            Assert.AreEqual(2, graph.EdgeCount);
            Assert.IsFalse(graph.Contains(1));
            Assert.IsFalse(graph.Contains(2));
            Assert.IsFalse(graph.Contains(3));
            Assert.IsFalse(graph.ContainsEdge(1, 2));
            Assert.IsFalse(graph.ContainsEdge(1, 3));
            Assert.IsFalse(graph.ContainsEdge(2, 3));

            CQManager.UndoLastCommand();
            Assert.AreEqual(6, graph.VertexCount);
            Assert.AreEqual(5, graph.EdgeCount);
            Assert.IsTrue(graph.Contains(1));
            Assert.IsTrue(graph.Contains(2));
            Assert.IsTrue(graph.Contains(3));
            Assert.IsTrue(graph.ContainsEdge(1, 2));
            Assert.IsTrue(graph.ContainsEdge(1, 3));
            Assert.IsTrue(graph.ContainsEdge(2, 3));

            DirectedEdge<int> newEdge = new DirectedEdge<int>(42, 1);		// 42 -> 1
            graph.Add(newEdge);
            Assert.AreEqual(6, graph.EdgeCount);
            Assert.IsTrue(graph.ContainsEdge(42, 1));
            Assert.IsFalse(graph.ContainsEdge(1, 42));

            CQManager.UndoLastCommand();
            Assert.AreEqual(5, graph.EdgeCount);
            Assert.IsFalse(graph.ContainsEdge(42, 1));

            CQManager.RedoLastCommand();
            Assert.AreEqual(6, graph.EdgeCount);
            Assert.IsTrue(graph.ContainsEdge(42, 1));

            graph.Remove(newEdge);
            Assert.AreEqual(5, graph.EdgeCount);
            Assert.IsFalse(graph.ContainsEdge(42, 1));

            CQManager.UndoLastCommand();
            Assert.AreEqual(6, graph.EdgeCount);
            Assert.IsTrue(graph.ContainsEdge(42, 1));

            graph.Disconnect(42, 1, false);
            Assert.AreEqual(5, graph.EdgeCount);
            Assert.IsFalse(graph.ContainsEdge(42, 1));

            CQManager.UndoLastCommand();
            Assert.AreEqual(6, graph.EdgeCount);
            Assert.IsTrue(graph.ContainsEdge(42, 1));

            CQManager.ActivateCommandQueueStack(Guid.Empty);
        }