コード例 #1
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);
        }
コード例 #2
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);
        }
コード例 #3
0
        public void Should_GetAllNodes_Empty()
        {
            //arrange
            var graph = new MyGraphAdj <int>(6);

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

            //assert
            result.Count.ShouldBeEquivalentTo(0);
        }
コード例 #4
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);
            }
        }
コード例 #5
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]);
            }
        }
コード例 #6
0
        private Dictionary <T, int> GetShortestPathsFromSource(T source, MyGraphAdj <T> graph,
                                                               int[] weights)
        {
            var vertexes = graph.GetAllVertexes().ToList();
            var edges    = graph.GetAllEdges().ToList();

            var parent = ComputePaths(source, graph).
                         OrderByDescending(x => x.Key).ToDictionary(x => x.Key, x => x.Value);

            Dictionary <T, int> result = new Dictionary <T, int>();

            foreach (var item in parent)
            {
                if (item.Value == null)
                {
                    result.Add(item.Key, 0);
                    continue;
                }
                int distance = 0;
                var u        = vertexes.First(x => x.Key.CompareTo(item.Value.Value) == 0);
                var v        = vertexes.Find(x => x.Key.CompareTo(item.Key) == 0);

                while (true)
                {
                    distance += weights[v.Value] - weights[u.Value] + edges.First(x => x[0] == u.Value && x[1] == v.Value)[2];

                    if (parent[u.Key] == null)
                    {
                        break;
                    }

                    var temp = parent[u.Key].Value;
                    var prev = vertexes.First(x => x.Key.CompareTo(temp) == 0);
                    v = u;
                    u = prev;
                }
                result.Add(item.Key, distance);
            }
            return(result);
        }
コード例 #7
0
        private MyGraphAdj <T> ExtendGraph(MyGraphAdj <T> graph)
        {
            var result = new MyGraphAdj <T>(graph.Count + 1, true);

            var vertexes = graph.GetAllVertexes().ToList();

            for (int i = 0; i < graph.Count; i++)
            {
                result.AddVertex(i, vertexes[i].Key);
            }
            foreach (var item in graph.GetAllEdges().ToList())
            {
                result.AddEdge(item[0], item[1], item[2]);
            }

            result.AddVertex(graph.Count, (T)((dynamic)vertexes.Max(x => x.Key) + 1));
            foreach (var item in vertexes)
            {
                result.AddEdge(graph.Count, item.Value, 0);
            }

            return(result);
        }
コード例 #8
0
        private IEnumerable <int> ReveightEdges(MyGraphAdj <T> tempGraph)
        {
            var vertexes = tempGraph.GetAllVertexes().ToList();
            var edges    = tempGraph.GetAllEdges().ToList();

            var distances = new Dictionary <int, int>();

            foreach (var item in vertexes)
            {
                distances[item.Value] = Int32.MaxValue;
            }
            distances[tempGraph.Count - 1] = 0;

            for (int i = 0; i < vertexes.Count; i++)
            {
                for (int j = 0; j < edges.Count; j++)
                {
                    var u      = edges[j][0];
                    var v      = edges[j][1];
                    var weight = edges[j][2] == Int32.MinValue ? 0 : edges[j][2];

                    if (distances[u] != Int32.MaxValue &&
                        distances[v] > distances[u] + weight)
                    {
                        if (i == vertexes.Count - 1)
                        {
                            throw new ArgumentException("Negative cycle detected");
                        }

                        distances[v] = distances[u] + weight;
                    }
                }
            }

            return(distances.Select(x => x.Value).Take(tempGraph.Count - 1));
        }