コード例 #1
0
        public void Should_Check_Graph_No_Edges()
        {
            //arrange
            var graph = new MyGraphAdj <char>(3, true);

            graph.AddVertex(0, 'A');
            graph.AddVertex(1, 'B');
            graph.AddVertex(2, 'C');

            var distances = new int[, ]
            {
                { 0, Int32.MaxValue, Int32.MaxValue },
                { Int32.MaxValue, 0, Int32.MaxValue },
                { Int32.MaxValue, Int32.MaxValue, 0 }
            };

            //act
            var result = _jonson.Compute(graph);

            //assert
            result.GetLength(0).ShouldBeEquivalentTo(distances.GetLength(0));
            result.GetLength(1).ShouldBeEquivalentTo(distances.GetLength(1));

            for (int i = 0; i < result.GetLength(0); i++)
            {
                for (int j = 0; j < result.GetLength(1); j++)
                {
                    result[i, j].ShouldBeEquivalentTo(distances[i, j]);
                }
            }
        }
コード例 #2
0
        public void Should_Check_Remove_Count()
        {
            //arrange
            var graph = new MyGraphAdj <int>(4);

            graph.AddVertex(0, 0);
            graph.AddVertex(1, 1);
            graph.AddVertex(2, 2);
            graph.AddVertex(3, 3);

            graph.AddEdge(0, 2);
            graph.AddEdge(1, 2);
            graph.AddEdge(2, 0);
            graph.AddEdge(2, 1);
            graph.AddEdge(2, 3);
            graph.AddEdge(3, 2);

            //act
            graph.Remove(2);
            graph.Remove(7);

            //assert
            graph.Capacity.ShouldBeEquivalentTo(4);
            graph.Count.ShouldBeEquivalentTo(3);
        }
コード例 #3
0
        public void Should_Check_Negative_Cycle_Complex()
        {
            //arrange
            var graph = new MyGraphAdj <char>(6, true);

            graph.AddVertex(0, 'A');
            graph.AddVertex(1, 'B');
            graph.AddVertex(2, 'C');
            graph.AddVertex(3, 'D');
            graph.AddVertex(4, 'E');
            graph.AddVertex(5, 'F');

            graph.AddEdge(0, 1, -7);
            graph.AddEdge(0, 3, 7);
            graph.AddEdge(0, 4, 5);
            graph.AddEdge(1, 0, 8);
            graph.AddEdge(1, 2, 1);
            graph.AddEdge(2, 1, 2);
            graph.AddEdge(2, 3, 3);
            graph.AddEdge(3, 2, -3);
            graph.AddEdge(3, 0, 5);
            graph.AddEdge(3, 5, -6);
            graph.AddEdge(5, 3, 4);
            graph.AddEdge(5, 4, 1);
            graph.AddEdge(4, 0, -3);
            graph.AddEdge(4, 5, -1);

            //act
            Action act = () => _jonson.Compute(graph);

            //assert
            act.ShouldThrow <ArgumentException>();
        }
コード例 #4
0
        public int[,] Compute(MyGraphAdj <T> graph)
        {
            if (graph == null)
            {
                throw new ArgumentNullException();
            }
            if (!graph.IsWeighted)
            {
                throw new InvalidOperationException();
            }
            if (graph.Count == 0)
            {
                return(new int[0, 0]);
            }

            MyGraphAdj <T> tempGraph  = ExtendGraph(graph);
            var            newWeights = ReveightEdges(tempGraph).ToArray();

            UpdateWeights(tempGraph, newWeights);

            var result = ComputeAllPairs(graph, tempGraph, newWeights);

            for (int i = 0; i < result.GetLength(0); i++)
            {
                for (int j = 0; j < result.GetLength(1); j++)
                {
                    result[i, j] = result[i, j] == Int32.MinValue ? Int32.MaxValue : result[i, j];
                }
            }

            return(result);
        }
コード例 #5
0
        private int[,] ComputeAllPairs(MyGraphAdj <T> graph, MyGraphAdj <T> tempGraph,
                                       int[] newWeights)
        {
            int[,] result = new int[graph.Count, graph.Count];
            var vertexes = graph.GetAllVertexes().ToDictionary(x => x.Key, x => x.Value);

            for (int i = 0; i < vertexes.Count; i++)
            {
                var path = GetShortestPathsFromSource(vertexes.Keys.ElementAt(i),
                                                      tempGraph, newWeights);

                for (int j = 0; j < result.GetLength(1); j++)
                {
                    result[i, j] = Int32.MinValue;
                }

                foreach (var pair in path)
                {
                    int index = vertexes[pair.Key];
                    result[i, index] = pair.Key.CompareTo(vertexes.ElementAt(i).Key) == 0 ?
                                       0 : pair.Value;
                }
            }

            return(result);
        }
コード例 #6
0
        public void Should_BidirectionalSearch_False()
        {
            //arrange
            var graph = new MyGraphAdj <int>(15);

            graph.AddVertex(0, 0);
            graph.AddVertex(1, 1);
            graph.AddVertex(2, 2);
            graph.AddVertex(3, 3);
            graph.AddVertex(4, 4);
            graph.AddVertex(5, 5);
            graph.AddVertex(6, 6);

            graph.AddVertex(8, 8);
            graph.AddVertex(9, 9);
            graph.AddVertex(10, 10);
            graph.AddVertex(11, 11);
            graph.AddVertex(12, 12);
            graph.AddVertex(13, 13);
            graph.AddVertex(14, 14);

            graph.AddEdge(0, 4);
            graph.AddEdge(1, 4);
            graph.AddEdge(2, 5);
            graph.AddEdge(3, 5);
            graph.AddEdge(4, 0);
            graph.AddEdge(4, 1);
            graph.AddEdge(4, 6);
            graph.AddEdge(5, 2);
            graph.AddEdge(5, 3);
            graph.AddEdge(5, 6);
            graph.AddEdge(6, 4);
            graph.AddEdge(6, 5);
            graph.AddEdge(8, 9);
            graph.AddEdge(8, 10);
            graph.AddEdge(9, 8);
            graph.AddEdge(9, 11);
            graph.AddEdge(9, 12);
            graph.AddEdge(10, 8);
            graph.AddEdge(10, 13);
            graph.AddEdge(10, 14);
            graph.AddEdge(11, 9);
            graph.AddEdge(12, 9);
            graph.AddEdge(13, 10);
            graph.AddEdge(14, 10);

            //act
            var result = graph.BidirectionalSearch(1, 14);

            //assert
            result.ShouldBeEquivalentTo(null);

            graph.Capacity.ShouldBeEquivalentTo(15);
            graph.Count.ShouldBeEquivalentTo(14);
        }
コード例 #7
0
        public void Should_Throw_Update_Edge_If_vertexes_Does_Not_Exists()
        {
            //arrange
            var graph = new MyGraphAdj <int>(6);

            //act
            Action act = () => graph.UpdateWeight(0, 1, 2);

            //assert
            act.ShouldThrow <InvalidOperationException>();
        }
コード例 #8
0
        public void Should_GetAllNodes_Empty()
        {
            //arrange
            var graph = new MyGraphAdj <int>(6);

            //act
            var result = graph.GetAllVertexes().ToList();

            //assert
            result.Count.ShouldBeEquivalentTo(0);
        }
コード例 #9
0
        public void Should_Throw_Add_Edge_If_No_vertexes()
        {
            //arrange
            var graph = new MyGraphAdj <int>(6);

            //act
            Action act = () => graph.AddEdge(0, 1);

            //assert
            act.ShouldThrow <InvalidOperationException>();
        }
コード例 #10
0
        private Dictionary <T, T?> ComputePaths(T source, MyGraphAdj <T> graph)
        {
            var vertexes = graph.GetAllVertexes().ToList();
            var edges    = graph.GetAllEdges().ToList();

            Dictionary <T, int> distances        = new Dictionary <T, int>();
            Dictionary <T, T?>  parent           = new Dictionary <T, T?>();
            Dictionary <T, int> heapMinDistances = new Dictionary <T, int>();

            var heap = new MyBinaryHeap <MyBinaryHeapKeyNode <T, int> >(MyBinaryHeapType.MinHeap);

            foreach (var vertex in vertexes)
            {
                heap.Insert(new MyBinaryHeapKeyNode <T, int>(vertex.Key, vertex.Key.CompareTo(source) == 0 ? 0 : Int32.MaxValue));
                heapMinDistances.Add(vertex.Key, Int32.MaxValue);
            }
            parent[source]    = null;
            distances[source] = 0;

            while (heap.Count > 0)
            {
                var current = heap.ExtractTop();
                var nodes   = edges.Where(x => x[0].Equals(
                                              vertexes.First(y => y.Key.CompareTo(current.Key) == 0).Value)).ToList();
                if (nodes.Count == 0)
                {
                    break;
                }
                var parentNode = vertexes.First(x => x.Key.CompareTo(current.Key) == 0);
                foreach (var node in nodes)
                {
                    var vertex = vertexes.First(x => x.Value == node[1]);
                    if (!heap.Contains(new MyBinaryHeapKeyNode <T, int>(vertex.Key, vertex.Value)))
                    {
                        continue;
                    }

                    var currentDistance = edges.First(x =>
                                                      x[0] == parentNode.Value && x[1] == vertex.Value)[2];
                    distances[vertex.Key] = distances[current.Key] + currentDistance;

                    if (heapMinDistances[vertex.Key] >= distances[vertex.Key])
                    {
                        parent[vertex.Key] = current.Key;

                        heap.Decrease(new MyBinaryHeapKeyNode <T, int>(vertex.Key, Int32.MaxValue),
                                      new MyBinaryHeapKeyNode <T, int>(vertex.Key, currentDistance));
                        heapMinDistances[vertex.Key] = currentDistance;
                    }
                }
            }

            return(parent);
        }
コード例 #11
0
        public void Should_Throw_If_Null()
        {
            //arrange
            MyGraphAdj <char> graph = null;

            //act
            Action act = () => _jonson.Compute(graph);

            //assert
            act.ShouldThrow <ArgumentNullException>();
        }
コード例 #12
0
        public void Should_Create_Default_With_Capacity()
        {
            //arrange

            //act
            var result = new MyGraphAdj <int>(5);

            //assert
            result.Count.ShouldBeEquivalentTo(0);
            result.Capacity.ShouldBeEquivalentTo(5);
        }
コード例 #13
0
        public void Should_Check_Empty_Graph()
        {
            //arrange
            var graph = new MyGraphAdj <char>(6, true);

            //act
            var result = _jonson.Compute(graph);

            //assert
            result.GetLength(0).ShouldBeEquivalentTo(0);
            result.GetLength(1).ShouldBeEquivalentTo(0);
        }
コード例 #14
0
        public void Should_Check_Dijkstra_Negative_Edges()
        {
            //arrange
            var graph = new MyGraphAdj <char>(6, true);

            graph.AddVertex(0, 'A');
            graph.AddVertex(1, 'B');
            graph.AddVertex(2, 'C');
            graph.AddVertex(3, 'D');
            graph.AddVertex(4, 'E');
            graph.AddVertex(5, 'F');

            graph.AddEdge(0, 1, -7);
            graph.AddEdge(0, 3, 7);
            graph.AddEdge(0, 4, 5);
            graph.AddEdge(1, 0, 8);
            graph.AddEdge(1, 2, 1);
            graph.AddEdge(2, 1, 2);
            graph.AddEdge(2, 3, 3);
            graph.AddEdge(3, 2, -3);
            graph.AddEdge(3, 0, 5);
            graph.AddEdge(3, 5, 6);
            graph.AddEdge(5, 3, 4);
            graph.AddEdge(5, 4, 8);
            graph.AddEdge(4, 0, -3);
            graph.AddEdge(4, 5, -1);

            var distances = new int[, ]
            {
                { 0, -7, -6, -3, 5, 3 },
                { 8, 0, 1, 4, 13, 10 },
                { 8, 1, 0, 3, 13, 9 },
                { 5, -2, -3, 0, 10, 6 },
                { -3, -10, -9, -6, 0, -1 },
                { 5, -2, -1, 2, 8, 0 }
            };

            //act
            var result = _jonson.Compute(graph);

            //assert
            result.GetLength(0).ShouldBeEquivalentTo(distances.GetLength(0));
            result.GetLength(1).ShouldBeEquivalentTo(distances.GetLength(1));

            for (int i = 0; i < result.GetLength(0); i++)
            {
                for (int j = 0; j < result.GetLength(1); j++)
                {
                    result[i, j].ShouldBeEquivalentTo(distances[i, j]);
                }
            }
        }
コード例 #15
0
        public void Should_AddVertex_Check_Index()
        {
            //arrange
            var graph = new MyGraphAdj <int>(4);

            //act
            Action actLower  = () => graph.AddVertex(-1, 1);
            Action actHigher = () => graph.AddVertex(6, 1);

            //assert
            actLower.ShouldThrow <ArgumentOutOfRangeException>();
            actHigher.ShouldThrow <ArgumentOutOfRangeException>();
        }
コード例 #16
0
        public void Should_BreadthFirstSearch_Throw_If_Node_Is_Null()
        {
            //arrange
            var graph = new MyGraphAdj <int>(5);

            //act
            Action act = () => graph.BreadthFirstSearch(1).ToArray();

            //assert
            act.ShouldThrow <ArgumentException>();

            graph.Capacity.ShouldBeEquivalentTo(5);
            graph.Count.ShouldBeEquivalentTo(0);
        }
コード例 #17
0
        public void Should_Throw_Update_Edge_If_It_Was_Not_Added()
        {
            //arrange
            var graph = new MyGraphAdj <int>(6, true);

            graph.AddVertex(0, 0);
            graph.AddVertex(1, 1);

            //act
            Action act = () => graph.UpdateWeight(0, 1, 2);

            //assert
            act.ShouldThrow <ArgumentException>();
        }
コード例 #18
0
        public void Should_Throw_Add_Edge_With_Weight_If_It_Already_Exists()
        {
            //arrange
            var graph = new MyGraphAdj <int>(6, true);

            graph.AddVertex(0, 0);
            graph.AddVertex(1, 1);
            graph.AddEdge(0, 1, 1);

            //act
            Action act = () => graph.AddEdge(0, 1, 2);

            //assert
            act.ShouldThrow <ArgumentException>();
        }
コード例 #19
0
        public void Should_Throw_If_Not_Weighted()
        {
            //arrange
            var graph = new MyGraphAdj <char>(5);

            graph.AddVertex(0, '0');
            graph.AddVertex(1, '1');
            graph.AddVertex(0, '1');

            //act
            Action act = () => _jonson.Compute(graph);

            //assert
            act.ShouldThrow <InvalidOperationException>();
        }
コード例 #20
0
        public void Should_Throw_Add_Edge_With_Weight_If_Node_From_Equals_Node_To()
        {
            //arrange
            var graph = new MyGraphAdj <int>(6);

            graph.AddVertex(0, 0);
            graph.AddVertex(1, 1);


            //act
            Action act = () => graph.AddEdge(0, 0, 5);

            //assert
            act.ShouldThrow <ArgumentOutOfRangeException>();
        }
コード例 #21
0
        public void Should_Throw_Update_Edge_With_Weight_If_Not_Weighted_Graph()
        {
            //arrange
            var graph = new MyGraphAdj <int>(6);

            graph.AddVertex(0, 0);
            graph.AddVertex(1, 1);


            //act
            Action act = () => graph.UpdateWeight(0, 1, 5);

            //assert
            act.ShouldThrow <InvalidOperationException>();
        }
コード例 #22
0
        public void Should_BreadthFirstSearch_Throw_Check_Index()
        {
            //arrange
            var graph = new MyGraphAdj <int>(5);

            //act
            Action actLower  = () => graph.BreadthFirstSearch(-1).ToArray();
            Action actHigher = () => graph.BreadthFirstSearch(6).ToArray();

            //assert
            actLower.ShouldThrow <ArgumentOutOfRangeException>();
            actHigher.ShouldThrow <ArgumentOutOfRangeException>();

            graph.Capacity.ShouldBeEquivalentTo(5);
            graph.Count.ShouldBeEquivalentTo(0);
        }
コード例 #23
0
        public void Should_GetAllEdges_Weighted()
        {
            //arrange
            var graph = new MyGraphAdj <int>(6, true);

            graph.AddVertex(0, 0);
            graph.AddVertex(1, 1);
            graph.AddVertex(2, 2);
            graph.AddVertex(3, 3);
            graph.AddVertex(4, 4);
            graph.AddVertex(5, 5);

            graph.AddEdge(0, 5, 0);
            graph.AddEdge(0, 1, 1);
            graph.AddEdge(0, 4, 2);
            graph.AddEdge(1, 3, 3);
            graph.AddEdge(1, 4, 4);
            graph.AddEdge(2, 1, 5);
            graph.AddEdge(3, 2, 6);
            graph.AddEdge(3, 4, 7);

            var edges = new List <int[]>
            {
                new int[] { 0, 1, 1 },
                new int[] { 0, 4, 2 },
                new int[] { 0, 5, 0 },
                new int[] { 1, 3, 3 },
                new int[] { 1, 4, 4 },
                new int[] { 2, 1, 5 },
                new int[] { 3, 2, 6 },
                new int[] { 3, 4, 7 }
            };

            //act
            var result = graph.GetAllEdges().ToList();

            //assert
            result.Count.ShouldBeEquivalentTo(edges.Count);

            for (int i = 0; i < edges.Count; i++)
            {
                edges[i].Length.ShouldBeEquivalentTo(result[i].Length);
                edges[i][0].ShouldBeEquivalentTo(result[i][0]);
                edges[i][1].ShouldBeEquivalentTo(result[i][1]);
                edges[i][2].ShouldBeEquivalentTo(result[i][2]);
            }
        }
コード例 #24
0
        public void Should_DepthFirstSearch_Length_One()
        {
            //arrange
            var graph = new MyGraphAdj <int>(6);

            graph.AddVertex(0, 0);

            //act
            var result = graph.DepthFirstSearch(0).ToArray();

            //assert
            result.Length.ShouldBeEquivalentTo(1);
            result[0].ShouldBeEquivalentTo(0);

            graph.Capacity.ShouldBeEquivalentTo(6);
            graph.Count.ShouldBeEquivalentTo(1);
        }
コード例 #25
0
        public void Should_Check_Negative_Cycle_Simple()
        {
            //arrange
            var graph = new MyGraphAdj <char>(2, true);

            graph.AddVertex(0, 'A');
            graph.AddVertex(1, 'B');

            graph.AddEdge(0, 1, -3);
            graph.AddEdge(1, 0, -5);

            //act
            Action act = () => _jonson.Compute(graph);

            //assert
            act.ShouldThrow <ArgumentException>();
        }
コード例 #26
0
        public void Should_BidirectionalSearch_Throw_If_Node_Is_Null()
        {
            //arrange
            var graph = new MyGraphAdj <int>(5);

            graph.AddVertex(0, 0);

            //act
            Action actFrom = () => graph.BidirectionalSearch(1, 0).ToArray();
            Action actTo   = () => graph.BidirectionalSearch(0, 1).ToArray();

            //assert
            actFrom.ShouldThrow <ArgumentException>();
            actTo.ShouldThrow <ArgumentException>();

            graph.Capacity.ShouldBeEquivalentTo(5);
            graph.Count.ShouldBeEquivalentTo(1);
        }
コード例 #27
0
        public void Should_GetAllEdges_Empty()
        {
            //arrange
            var graph = new MyGraphAdj <int>(6);

            graph.AddVertex(0, 0);
            graph.AddVertex(1, 1);
            graph.AddVertex(2, 2);
            graph.AddVertex(3, 3);
            graph.AddVertex(4, 4);
            graph.AddVertex(5, 5);

            //act
            var result = graph.GetAllEdges().ToList();

            //assert
            result.Count.ShouldBeEquivalentTo(0);
        }
コード例 #28
0
        public void Should_Update_Edge_Weight()
        {
            //arrange
            var graph = new MyGraphAdj <int>(6, true);

            graph.AddVertex(0, 0);
            graph.AddVertex(1, 1);
            graph.AddEdge(0, 1, 5);

            //act
            graph.UpdateWeight(0, 1, 7);
            var result = graph.GetAllEdges().ToList();

            //assert
            result.Count.ShouldBeEquivalentTo(1);
            result[0][0].ShouldBeEquivalentTo(0);
            result[0][1].ShouldBeEquivalentTo(1);
            result[0][2].ShouldBeEquivalentTo(7);
        }
コード例 #29
0
        private void UpdateWeights(MyGraphAdj <T> tempGraph, IEnumerable <int> newWeights)
        {
            List <int[]> edgesToDelete = tempGraph.GetAllEdges().Where(x => x[2] == 0).ToList();

            foreach (var edge in edgesToDelete)
            {
                tempGraph.RemoveEdge(edge[0], edge[1]);
            }

            tempGraph.Remove((tempGraph.GetAllVertexes().Last().Key));

            var restEdges = tempGraph.GetAllEdges();

            foreach (var edge in restEdges)
            {
                int newWeight = edge[2] + newWeights.ElementAt(edge[0]) - newWeights.ElementAt(edge[1]);
                tempGraph.UpdateWeight(edge[0], edge[1], newWeight);
            }
        }
コード例 #30
0
        public void Should_GetAllNodes()
        {
            //arrange
            var graph = new MyGraphAdj <int>(6);

            graph.AddVertex(0, 0);
            graph.AddVertex(1, 1);
            graph.AddVertex(2, 2);
            graph.AddVertex(3, 3);
            graph.AddVertex(4, 4);
            graph.AddVertex(5, 5);

            graph.AddEdge(0, 5);
            graph.AddEdge(0, 1);
            graph.AddEdge(0, 4);
            graph.AddEdge(1, 3);
            graph.AddEdge(1, 4);
            graph.AddEdge(2, 1);
            graph.AddEdge(3, 2);
            graph.AddEdge(3, 4);

            var nodes = new List <int[]>
            {
                new [] { 0, 0 },
                new [] { 1, 1 },
                new [] { 2, 2 },
                new [] { 3, 3 },
                new [] { 4, 4 },
                new [] { 5, 5 },
            };

            //act
            var result = graph.GetAllVertexes().ToList();

            //assert
            result.Count.ShouldBeEquivalentTo(nodes.Count);

            for (int i = 0; i < result.Count; i++)
            {
                result[i].Key.ShouldBeEquivalentTo(nodes[i][0]);
                result[i].Value.ShouldBeEquivalentTo(nodes[i][1]);
            }
        }