Example #1
0
        public bool Split(out Task <TVertex, TEdge> taskTake, out Task <TVertex, TEdge> taskDrop)
        {
            if (!CanSplit())
            {
                taskTake = null;
                taskDrop = null;
                return(false);
            }

            TEdge   edgeForSplit = ChooseEdgeForSplit();
            TVertex v1           = edgeForSplit.Source;
            TVertex v2           = edgeForSplit.Target;

            BidirectionalGraph <TVertex, TEdge> graphTake = _graph.Clone();
            var weightsTake = new Dictionary <EquatableEdge <TVertex>, double>(_weight);
            var reverseEdge = new EquatableEdge <TVertex>(edgeForSplit.Target, edgeForSplit.Source);

            weightsTake.Remove(reverseEdge);
            graphTake.RemoveEdgeIf(edge => edge.Equals(reverseEdge));

            foreach (TEdge outEdge in graphTake.OutEdges(v1))
            {
                weightsTake.Remove(outEdge);
            }

            foreach (TEdge inEdge in graphTake.InEdges(v2))
            {
                weightsTake.Remove(inEdge);
            }

            graphTake.ClearOutEdges(v1);
            graphTake.ClearInEdges(v2);
            var pathTake = new BidirectionalGraph <TVertex, TEdge>(Path);

            pathTake.AddEdge(edgeForSplit);
            taskTake = new Task <TVertex, TEdge>(graphTake, weightsTake, pathTake, MinCost, $"Take{edgeForSplit}");

            BidirectionalGraph <TVertex, TEdge> graphDrop = _graph.Clone();
            var weightsDrop = new Dictionary <EquatableEdge <TVertex>, double>(_weight);

            weightsDrop.Remove(edgeForSplit);
            graphDrop.RemoveEdge(edgeForSplit);
            taskDrop = new Task <TVertex, TEdge>(graphDrop, weightsDrop, new BidirectionalGraph <TVertex, TEdge>(Path), MinCost, $"Drop{edgeForSplit}");

            return(true);
        }
        public void ClearOutEdges()
        {
            int edgesRemoved = 0;

            var graph = new BidirectionalGraph <int, Edge <int> >();

            graph.EdgeRemoved += e =>
            {
                Assert.IsNotNull(e);
                // ReSharper disable once AccessToModifiedClosure
                ++edgesRemoved;
            };

            AssertEmptyGraph(graph);

            // Clear 1 => not in graph
            graph.ClearOutEdges(1);
            AssertEmptyGraph(graph);

            // Clear 1 => In graph but no out edges
            graph.AddVertex(1);
            graph.ClearOutEdges(1);
            AssertHasVertices(graph, new[] { 1 });
            AssertNoEdge(graph);
            CheckCounter(0);

            var edge12 = new Edge <int>(1, 2);
            var edge23 = new Edge <int>(2, 3);

            graph.AddVerticesAndEdgeRange(new[] { edge12, edge23 });

            // Clear out 1
            graph.ClearOutEdges(1);

            AssertHasEdges(graph, new[] { edge23 });
            CheckCounter(1);

            var edge13 = new Edge <int>(1, 3);
            var edge31 = new Edge <int>(3, 1);
            var edge32 = new Edge <int>(3, 2);

            graph.AddVerticesAndEdgeRange(new[] { edge12, edge13, edge31, edge32 });

            // Clear out 3
            graph.ClearOutEdges(3);

            AssertHasEdges(graph, new[] { edge12, edge13, edge23 });
            CheckCounter(2);

            // Clear out 1
            graph.ClearOutEdges(1);

            AssertHasEdges(graph, new[] { edge23 });
            CheckCounter(2);

            // Clear out 2 = Clear
            graph.ClearOutEdges(2);

            AssertNoEdge(graph);
            CheckCounter(1);

            #region Local function

            void CheckCounter(int expectedRemovedEdges)
            {
                Assert.AreEqual(expectedRemovedEdges, edgesRemoved);
                edgesRemoved = 0;
            }

            #endregion
        }