public WeightedSimpleGraph(int vertexCount) { var vertices = new Vertex[vertexCount]; for (int id = 0; id < vertexCount; ++id) { vertices[id] = new Vertex(this, id); } Vertices = vertices; }
public bool TryGetValue(Vertex key, out int value) { int keyIndex; if (_keyIndices.TryGetValue(key, out keyIndex)) { value = _keyValuePairs[keyIndex].Value; return(true); } value = default(int); return(false); }
public BinaryHeap(WeightedSimpleGraph graph, Vertex topKey, int topValue = 0) { _keyValuePairs.Add(new KeyValuePair <Vertex, int>(topKey, topValue)); _keyIndices.Add(topKey, 0); foreach (var vertex in graph.Vertices) { if (vertex.Equals(topKey)) { continue; } _keyValuePairs.Add(new KeyValuePair <Vertex, int>(vertex, int.MaxValue)); _keyIndices.Add(vertex, _keyValuePairs.Count - 1); } }
// This uses Dijkstra's algorithm: https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm. // We return immediately upon visiting the destination city, and we don't initialize the // heap with all cities. We only add cities to the heap when reaching one of their neighbor // cities. Without a pre-filled heap to rely on, we track what cities have been visited // using an array of bools. public static int?Solve(WeightedSimpleGraph cityGraph, Vertex startCity, Vertex endCity) { var pathCosts = new BinaryHeap(startCity); bool[] visitedCities = new bool[cityGraph.VertexCount]; while (!pathCosts.IsEmpty) { var cheapestPath = pathCosts.Extract(); var city = cheapestPath.Key; int pathCostToCity = cheapestPath.Value; if (city == endCity) { return(pathCostToCity); } foreach (var neighbor in city.Neighbors.Where(n => !visitedCities[n.ID])) { int pathCostToNeighborThroughCity = pathCostToCity + city.GetEdgeWeight(neighbor); int currentPathCostToNeighbor; // We know the neighboring city hasn't been visited yet, so we need to maintain its // path cost in the heap. If it's already in the heap, see if a cheaper path exists // to it through the city we're visiting. If it isn't in the heap yet, add it. if (pathCosts.TryGetValue(neighbor, out currentPathCostToNeighbor)) { if (pathCostToNeighborThroughCity < currentPathCostToNeighbor) { pathCosts.Update(neighbor, pathCostToNeighborThroughCity); } } else { pathCosts.Add(neighbor, pathCostToNeighborThroughCity); } } visitedCities[city.ID] = true; } return(null); }
public void AddEdge(Vertex firstVertex, Vertex secondVertex, int weight) { firstVertex.AddNeighbor(secondVertex, weight); secondVertex.AddNeighbor(firstVertex, weight); }
public int Update(Vertex key, int value) => Update(new KeyValuePair <Vertex, int>(key, value));
public int GetValue(Vertex key) => _keyValuePairs[_keyIndices[key]].Value;
public bool Contains(Vertex key) => _keyIndices.ContainsKey(key);
public void Add(Vertex key, int value) => Add(new KeyValuePair <Vertex, int>(key, value));
public BinaryHeap(Vertex topKey, int topValue = 0) { _keyValuePairs.Add(new KeyValuePair <Vertex, int>(topKey, topValue)); _keyIndices.Add(topKey, 0); }
public double Update(Vertex key, double value) => Update(new KeyValuePair <Vertex, double>(key, value));
public void Add(Vertex key, double value) => Add(new KeyValuePair <Vertex, double>(key, value));