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); } }
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); }
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]); } }
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); }
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); }
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); }
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); }
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)); }