private void Visit(EdgeWeightedGraph graph, int vertex) { marked[vertex] = true; foreach (var edge in graph.Adj(vertex)) { int otherVertex = edge.Other(vertex); if (marked[otherVertex]) { continue; } if (!(edge.Weight < distTo[otherVertex])) { continue; } edgeTo[otherVertex] = edge; distTo[otherVertex] = edge.Weight; if (prioryQueue.Contains(otherVertex)) { prioryQueue.ChangeKey(otherVertex, distTo[otherVertex]); } else { prioryQueue.Insert(otherVertex, distTo[otherVertex]); } } }
/// <summary> /// scan vertex v /// </summary> /// <param name="g"></param> /// <param name="v"></param> private void Scan(EdgeWeightedGraph g, int v) { _marked[v] = true; foreach (var e in g.Adj(v)) { var w = e.Other(v); if (_marked[w]) { continue; // v-w is obsolete edge } if (e.Weight < _distTo[w]) { _distTo[w] = e.Weight; _edgeTo[w] = e; if (_pq.Contains(w)) { _pq.DecreaseKey(w, _distTo[w]); } else { _pq.Insert(w, _distTo[w]); } } } }
private void scan(EdgeWeightedGraph g, int v) { marked[v] = true; foreach (Edge e in g.Adj(v)) { int w = e.Other(v); if (marked[w]) { continue;//v-w is obsolete edge } if (e.Weight() < distTo[w]) { distTo[w] = e.Weight(); edgeTo[w] = e; if (pq.Contains(w)) { pq.ChangeKey(w, distTo[w]); } else { pq.Insert(w, distTo[w]); } } } }
public void Visit(EdgeWeightedGraph g, int v) { marked[v] = true; foreach (var edge in g.Adj(v)) { int v2 = edge.Other(v); if (marked[v2]) { continue; } if (edge.Weight < distanceTo[v2]) { edgeTo[v2] = edge; distanceTo[v2] = edge.Weight; if (pq.Contains(v2)) { pq.Change(v2, distanceTo[v2]); } else { pq.Insert(v2, distanceTo[v2]); } } } }
private void Visit(IEdgeWeightGraph g, int v) { marked[v] = true; foreach (var e in g.Adj(v)) { int w = e.Other(v); if (marked[w]) { continue; } if (e.Weight < distTo[w]) //更新最佳的边 { edgeTo[w] = e; distTo[w] = e.Weight; if (pq.Contains(w)) { pq.ChangeKey(w, distTo[w]); } else { pq.Insert(w, distTo[w]); } } } }
private void Relax(EdgeWeightedDigraph g, int v) { foreach (var e in g.Adj(v)) { int w = e.To; if (_distTo[v] + e.Weight < _distTo[w]) { _edgeTo[w] = e; _distTo[w] = _distTo[v] + e.Weight; if (_pq.Contains(e.To)) { _pq.Change(e.To, _distTo[w]); } else { _pq.Insert(e.To, _distTo[w]); } } } }
public void IndexMinPQTest1() { const int MaxSize = 8; const double MinValue = 3.9; const double MaxValue = MinValue * MaxSize + 32; int index; // MinValue index == 3, MaxValue index == 4 double[] items = { MinValue * 2, MinValue * 3, MinValue * 4, MinValue, MaxValue, MinValue * 5, MinValue * 6, MinValue * 7 }; StdRandom.Seed = 101; IndexMinPQ <double> pq = new IndexMinPQ <double>(MaxSize); index = StdRandom.Uniform(items.Length); Assert.IsFalse(pq.Contains(index)); Assert.IsTrue(pq.IsEmpty); Assert.AreEqual(0, pq.Count); try { index = pq.DelMin(); Assert.Fail("Failed to catch exception"); } catch (InvalidOperationException) { } for (int i = 0; i < items.Length; i++) { pq.Insert(i, items[i]); } Assert.AreEqual(items.Length, pq.Count); Assert.AreEqual(MinValue, pq.MinKey); Assert.AreEqual(3, pq.MinIndex); Assert.AreEqual(MaxValue, pq.KeyOf(4)); index = StdRandom.Uniform(items.Length); Assert.AreEqual(items[index], pq.KeyOf(index)); pq.ChangeKey(1, pq.MinKey * 0.9); // make it the smallest item Assert.AreEqual(1, pq.MinIndex); pq.DecreaseKey(3, pq.MinKey * 0.87); Assert.AreEqual(3, pq.MinIndex); pq.Delete(3); Assert.AreNotEqual(3, pq.MinIndex); Assert.AreEqual(1, pq.DelMin()); }
/// <summary> /// relax edge e and update pq if changed /// </summary> /// <param name="e"></param> /// <param name="v"></param> private void Relax(EdgeW e, int v) { var w = e.Other(v); if (_distTo[w] > _distTo[v] + e.Weight) { _distTo[w] = _distTo[v] + e.Weight; _edgeTo[w] = e; if (_pq.Contains(w)) { _pq.DecreaseKey(w, _distTo[w]); } else { _pq.Insert(w, _distTo[w]); } } }
void Relax(EdgeWeightedDirectedGraph graph, int vertex) { foreach (var edge in graph.Adj(vertex)) { int v2 = edge.End; if (DistTo[v2] > DistTo[vertex] + edge.Weight) { DistTo[v2] = DistTo[vertex] + edge.Weight; EdgeTo[v2] = edge; if (pq.Contains(v2)) { pq.Change(v2, DistTo[v2]); } pq.Insert(v2, DistTo[v2]); } } }
/// <summary> /// relax edge e and update pq if changed /// </summary> /// <param name="e"></param> private void Relax(DirectedEdge e) { int v = e.From(), w = e.To(); if (_distTo[w] > _distTo[v] + e.Weight) { _distTo[w] = _distTo[v] + e.Weight; _edgeTo[w] = e; if (_pq.Contains(w)) { _pq.DecreaseKey(w, _distTo[w]); } else { _pq.Insert(w, _distTo[w]); } } }
private void Visit(WeightedGraph G, int v) { marked[v] = true; foreach (var e in G.adj(v)) { int w = e.other(v); if (!marked[w]) { if (!pq.Contains(w)) { pq.Insert(w, e); } else { pq.DecreaseKey(w, e); } } } }
private void Relax(WeightedDiGraph G, Edge e) { int v = e.from(); int w = e.to(); if (cost[w] > cost[v] + e.Weight) { cost[w] = cost[v] + e.Weight; edgeTo[w] = e; if (!pq.Contains(w)) { pq.Insert(w, cost[w]); } else { pq.DecreaseKey(w, cost[w]); } } }
/// <summary> /// relax edge e and update pq if changed /// relax defined as follows: to relax an edge v-->w means to test whether the best known way from s to w is to go from s to v, then take the edge from v to w.If so, update our data structures to indicate that /// </summary> /// <param name="e"></param> private void relax(DirectedEdge e) { int v = e.From(); int w = e.To(); if (distTo[w] > distTo[v] + e.Weight()) { distTo[w] = distTo[v] + e.Weight(); edgeTo[w] = e; if (pq.Contains(w)) { pq.DecreaseKey(w, distTo[w]); } else { pq.Insert(w, distTo[w]); } } }
private void Relax(IEdgeWeightedDIgraph g, int v) { foreach (var e in g.Adj(v)) { int w = e.To; if (distTo[w] > distTo[v] + e.Weight) { distTo[w] = distTo[v] + e.Weight; edgeTo[w] = e; if (pq.Contains(w)) { pq.ChangeKey(w, distTo[w]); } else { pq.Insert(w, distTo[w]); } } } }
protected void Relax(IndexMinPQ <double> pq, DirectedEdge e) { int v = e.From; int w = e.To; if (distTo[w] > distTo[v] + e.Weight) { distTo[w] = distTo[v] + e.Weight; edgeTo[w] = e; if (pq.Contains(w)) { pq.DecreaseKey(w, distTo[w]); } else { //this will never used pq.Insert(w, distTo[w]); } } }
private void Relax(EdgeWeightedDigraph graph, int vertex) { foreach (var edge in graph.Adj(vertex)) { int w = edge.DestinationVertex; if (distTo[w] > distTo[vertex] + edge.Weight) { distTo[w] = distTo[vertex] + edge.Weight; edgeTo[w] = edge; if (priorityQueue.Contains(w)) { priorityQueue.Change(w, distTo[w]); } else { priorityQueue.Insert(w, distTo[w]); } } } }
void Relax(EdgeWeightedDiagraph g, int v) { foreach (DirectedEdge e in g.AdjList(v)) { int w = e.To(); double weight = e.Weight(); if (distTo[w] > distTo[v] + weight) { //relax edgeTo[w] = e; distTo[w] = distTo[v] + weight; if (pq.Contains(w)) { pq.ChangeKey(w, distTo[w]); } else { pq.Insert(w, distTo[w]); } } } }
private void Relax(EdgeWeightedDiGraph g, int v) { foreach (var edge in g.Adj(v)) { //test if current weight of path to W is more than going through v; ie v 'relaxes' the path int w = edge.To(); double distViaV = _distTo[v] + edge.Weight(); //if current distTo w is greater than (distTo v + this.edge weight), then add/or replace on arrays and PQ if (distViaV < _distTo[w]) { _distTo[w] = distViaV; _edgeTo[w] = edge; if (_pq.Contains(w)) { _pq.Change(w, distViaV); } else { _pq.Insert(w, distViaV); } } } }
private void Relax(EdgeWeightedDigraph graph, int vertex) { foreach (var edge in graph.Adj(vertex)) { int w = edge.DestinationVertex; if (!(DistTo[w] > DistTo[vertex] + edge.Weight)) { continue; } DistTo[w] = DistTo[vertex] + edge.Weight; EdgeTo[w] = edge; if (priorityQueue.Contains(w)) { priorityQueue.ChangeKey(w, DistTo[w]); } else { priorityQueue.Insert(w, DistTo[w]); } } }
// Returns shortest path from src to dst (not including src) public List <TileNode> GetShortestPath(Vector2Int src, Vector2Int dst, UnitType unitType) { float[,] distance = new float[width, height]; Vector2Int[,] prev = new Vector2Int[width, height]; IndexMinPQ <float> minPQ = new IndexMinPQ <float>(width * height); distance[src.x, src.y] = 0.0f; prev[src.x, src.y] = src; minPQ.Insert(ToTileIndex1D(src), 0.0f); for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { if (i == src.x && j == src.y) { continue; } distance[i, j] = float.PositiveInfinity; prev[i, j] = new Vector2Int(-1, -1); minPQ.Insert(ToTileIndex1D(i, j), float.PositiveInfinity); } } while (!minPQ.IsEmpty) { float dist = minPQ.MinKey; Vector2Int min = ToTileIndex2D(minPQ.DelMin()); Vector2Int[] neighbors = GetNeighbors(min); foreach (Vector2Int neighbor in neighbors) { int neighborInd = ToTileIndex1D(neighbor); float edgeDist = GetTileMoveWeight(neighbor, unitType); if (minPQ.Contains(neighborInd) && edgeDist != 0.0f) { float currentDist = minPQ.KeyOf(neighborInd); if (dist + edgeDist < currentDist) { distance[neighbor.x, neighbor.y] = dist + edgeDist; prev[neighbor.x, neighbor.y] = min; minPQ.DecreaseKey(neighborInd, dist + edgeDist); } } } } if (distance[dst.x, dst.y] == float.PositiveInfinity) { return(null); } List <TileNode> path = new List <TileNode>(); TileNode dstNode; dstNode.coords = dst; dstNode.dist = distance[dst.x, dst.y]; path.Add(dstNode); Vector2Int tile = dst; while (prev[tile.x, tile.y] != src) { tile = prev[tile.x, tile.y]; TileNode node; node.coords = tile; node.dist = distance[tile.x, tile.y]; path.Add(node); } path.Reverse(); return(path); }