private E GetOriginalEdgeInstance(BaseVertex startVertexForEdge, BaseVertex endVertexForEdge) { string startVertexId = idMapper.GetBackThePreviouslyStoredGeneralStringIdForInteger(startVertexForEdge.GetId()); string endVertexId = idMapper.GetBackThePreviouslyStoredGeneralStringIdForInteger(endVertexForEdge.GetId()); return(base.GetOriginalEdgeInstance(startVertexId, endVertexId)); }
public string predictAccentsWithMultiMatches(string sentence, int nResults, bool getWeight = true) { LinkedHashMap <string, double> output = new LinkedHashMap <string, double>(); string @in = Utils.normaliseString(sentence); string lowercaseIn = @in.ToLower(); string[] words = ("0 " + lowercaseIn + " 0").Split(' '); Graph graph = new VariableGraph(); Dictionary <int, string> idxWordMap = new Dictionary <int, string>(); int index = 0; int[] numberP = new int[words.Length]; string[,] possibleChange = new string[words.Length, maxp]; int[,] indices = new int[words.Length, maxp]; int nVertex = 0; index = buildGraph(words, graph, idxWordMap, index, numberP, possibleChange, indices, nVertex); //Yen Algorithm for kShortestPaths YenTopKShortestPathsAlg yenAlg = new YenTopKShortestPathsAlg(graph); List <Accent.KShortestPaths.Model.Path> shortest_paths_list = yenAlg.get_shortest_paths(graph.get_vertex(0), graph.get_vertex(index - 1), nResults); foreach (Accent.KShortestPaths.Model.Path path in shortest_paths_list) { List <BaseVertex> pathVertex = path.get_vertices(); string text = ""; for (int i = 1; i < pathVertex.Count - 1; i++) { BaseVertex vertext = pathVertex[i]; text += idxWordMap[vertext.get_id()] + " "; if (text.Contains("đầm dáng")) { text.Replace("đầm dáng", "đảm đang"); } if (text.Contains("chào bán")) { text = Regex.Replace(text, "chào bán", "chào bạn"); } if (text.Contains("bị đầu tay")) { text = Regex.Replace(text, "bị đầu tay", "bị đau tay"); } if (text.Contains("tay tôi bị đầu")) { text = Regex.Replace(text, "tay tôi bị đầu", "tay tôi bị đau"); } } output.Add(processOutput(@in, text.Trim()), path.get_weight()); } // Không lấy trọng số đo lường cho các trường hợp thêm dấu. if (!getWeight) { return(output.ToString2()); } return(output.ToString()); }
/** * Do the work */ protected void DetermineShortestPaths(BaseVertex sourceVertex, BaseVertex sinkVertex, bool isSource2sink) { // 0. clean up variables Clear(); // 1. initialize members BaseVertex endVertex = isSource2sink ? sinkVertex : sourceVertex; BaseVertex startVertex = isSource2sink ? sourceVertex : sinkVertex; startVertexDistanceIndex.Add(startVertex, 0d); startVertex.SetWeight(0d); vertexCandidateQueue.add(startVertex, startVertex.GetWeight()); // 2. start searching for the shortest path while (!vertexCandidateQueue.isEmpty()) { BaseVertex curCandidate = vertexCandidateQueue.poll(); if (curCandidate.Equals(endVertex)) { break; } determinedVertexSet.Add(curCandidate); UpdateVertex(curCandidate, isSource2sink); } }
/** * Update the distance from the source to the concerned vertex. * @param vertex */ private void UpdateVertex(BaseVertex vertex, bool isSource2sink) { // 1. get the neighboring vertices ISet <BaseVertex> neighborVertexList = isSource2sink ? graph.GetAdjacentVertices(vertex) : graph.GetPrecedentVertices(vertex); // 2. update the distance passing on current vertex foreach (BaseVertex curAdjacentVertex in neighborVertexList) { // 2.1 skip if visited before if (determinedVertexSet.Contains(curAdjacentVertex)) { continue; } // 2.2 calculate the new distance double distance = startVertexDistanceIndex.ContainsKey(vertex)? startVertexDistanceIndex[vertex] : Graph.DISCONNECTED; distance += isSource2sink ? graph.GetEdgeWeight(vertex, curAdjacentVertex) : graph.GetEdgeWeight(curAdjacentVertex, vertex); // 2.3 update the distance if necessary if (!startVertexDistanceIndex.ContainsKey(curAdjacentVertex) || startVertexDistanceIndex[curAdjacentVertex] > distance) { startVertexDistanceIndex.AddOrReplace(curAdjacentVertex, distance); predecessorIndex.AddOrReplace(curAdjacentVertex, vertex); curAdjacentVertex.SetWeight(distance); vertexCandidateQueue.add(curAdjacentVertex, curAdjacentVertex.GetWeight()); } } }
/// <summary> /// Update the distance from the source to the concerned vertex. </summary> /// <param name="vertex"> </param> private void _improve_to_vertex(BaseVertex vertex, bool is_source2sink) { // 1. get the neighboring vertices HashSet <BaseVertex> neighbor_vertex_list = is_source2sink ? _graph.get_adjacent_vertices(vertex) : _graph.get_precedent_vertices(vertex); // 2. update the distance passing on current vertex foreach (BaseVertex cur_adjacent_vertex in neighbor_vertex_list) { // 2.1 skip if visited before if (_determined_vertex_set.Contains(cur_adjacent_vertex)) { continue; } // 2.2 calculate the new distance double distance = _start_vertex_distance_index.ContainsKey(vertex) ? _start_vertex_distance_index[vertex] : Graph.DISCONNECTED; distance += is_source2sink ? _graph.get_edge_weight(vertex, cur_adjacent_vertex) : _graph.get_edge_weight(cur_adjacent_vertex, vertex); // 2.3 update the distance if necessary if (!_start_vertex_distance_index.ContainsKey(cur_adjacent_vertex) || _start_vertex_distance_index[cur_adjacent_vertex] > distance) { _start_vertex_distance_index[cur_adjacent_vertex] = distance; _predecessor_index[cur_adjacent_vertex] = vertex; cur_adjacent_vertex.set_weight(distance); _vertex_candidate_queue.EnqueueWithoutDuplicates(cur_adjacent_vertex, (float)distance);// Lớp PriorytyQueue quan trong can thuc hien đổi lại } } }
/// <summary> /// Note that currently there seem to be no way for the "yanqi" implementation to actually specify the number /// of shortest paths to return, but it seems to find all paths. /// However, the implementation of this method instead takes care of reducing the result. /// Otherwise, if the semantic of the method is not respected it can not for example be tested /// against results from other implementations since then they would return a different number of paths. /// </summary> /// <param name="startVertex"></param> /// <param name="endVertex"></param> /// <param name="maxNumberOfPaths"></param> /// <returns></returns> protected override IList <P> FindShortestPathHook( V startVertex, V endVertex, int maxNumberOfPaths ) { IList <P> paths = new List <P>(); int startVertexId = idMapper.CreateOrRetrieveIntegerId(startVertex.VertexId); int endVertexId = idMapper.CreateOrRetrieveIntegerId(endVertex.VertexId); YenTopKShortestPathsAlg yenAlg = new YenTopKShortestPathsAlg(graphAdaptee, graphAdaptee.GetVertex(startVertexId), graphAdaptee.GetVertex(endVertexId)); while (yenAlg.HasNext()) { global::edu.asu.emit.algorithm.graph.Path path = yenAlg.Next(); IList <E> edges = new List <E>(); java.util.List <BaseVertex> vertexList = path.GetVertexList(); for (int i = 1; i < vertexList.size(); i++) { BaseVertex startVertexForEdge = vertexList.get(i - 1); BaseVertex endVertexForEdge = vertexList.get(i); E edge = GetOriginalEdgeInstance(startVertexForEdge, endVertexForEdge); edges.Add( edge ); } W totalWeight = base.CreateInstanceWithTotalWeight(path.GetWeight(), edges); paths.Add(base.CreatePath(totalWeight, edges)); if (maxNumberOfPaths == paths.Count) { break; } } return(new ReadOnlyCollection <P>(paths)); }
/** * Correct costs of successors of the input vertex using backward star form. * (FLOWER) * * @param vertex */ public void CorrectCostBackward(BaseVertex vertex) { // 1. initialize the list of vertex to be updated var vertexList = new java.util.LinkedList <BaseVertex>(); vertexList.add(vertex); // 2. update the cost of relevant precedents of the input vertex while (!vertexList.isEmpty()) { BaseVertex curVertex = vertexList.remove(0); double costOfCurVertex = startVertexDistanceIndex[curVertex]; ISet <BaseVertex> preVertexSet = graph.GetPrecedentVertices(curVertex); foreach (BaseVertex preVertex in preVertexSet) { double costOfPreVertex = startVertexDistanceIndex.ContainsKey(preVertex) ? startVertexDistanceIndex[preVertex] : Graph.DISCONNECTED; double freshCost = costOfCurVertex + graph.GetEdgeWeight(preVertex, curVertex); if (costOfPreVertex > freshCost) { startVertexDistanceIndex.AddOrReplace(preVertex, freshCost); predecessorIndex.AddOrReplace(preVertex, curVertex); vertexList.add(preVertex); } } } }
/// <summary> /// Do the work /// </summary> protected internal virtual void determine_shortest_paths(BaseVertex source_vertex, BaseVertex sink_vertex, bool is_source2sink) { // 0. clean up variables clear(); // 1. initialize members BaseVertex end_vertex = is_source2sink ? sink_vertex : source_vertex; BaseVertex start_vertex = is_source2sink ? source_vertex : sink_vertex; _start_vertex_distance_index[start_vertex] = 0d; start_vertex.set_weight(0d); _vertex_candidate_queue.Enqueue(start_vertex, 0); // 2. start searching for the shortest path while (_vertex_candidate_queue.Count() != 0) { BaseVertex cur_candidate = _vertex_candidate_queue.Dequeue(); if (cur_candidate.Equals(end_vertex)) { break; } _determined_vertex_set.Add(cur_candidate); _improve_to_vertex(cur_candidate, is_source2sink); } }
public virtual double GetEdgeWeight(BaseVertex source, BaseVertex sink) { return(vertexPairWeightIndex.ContainsKey( new Pair <int, int>(source.GetId(), sink.GetId()))? vertexPairWeightIndex[ new Pair <int, int>(source.GetId(), sink.GetId())] : DISCONNECTED); }
public static Vector3[] CalculateBaseVertices(Vector3 center, int height) { Vector3[] vertices = (Vector3[])BaseVertex.Clone(); for (int d = 0; d < 6; d++) { vertices[d] = center + vertices[d]; vertices[d].y = height; } return(vertices); }
public void AddVertex(BaseVertex vertex) { if (_vertices == null) { _vertices = new List <BaseVertex>(); } _vertices.Add(vertex); MakeEdges(); }
/** * Calculate the distance from the target vertex to the input * vertex using forward star form. * (FLOWER) * * @param vertex */ public Path UpdateCostForward(BaseVertex vertex) { double cost = Graph.DISCONNECTED; // 1. get the set of successors of the input vertex ISet <BaseVertex> adjVertexSet = graph.GetAdjacentVertices(vertex); // 2. make sure the input vertex exists in the index if (!startVertexDistanceIndex.ContainsKey(vertex)) { startVertexDistanceIndex.Add(vertex, Graph.DISCONNECTED); } // 3. update the distance from the root to the input vertex if necessary foreach (BaseVertex curVertex in adjVertexSet) { // 3.1 get the distance from the root to one successor of the input vertex double distance = startVertexDistanceIndex.ContainsKey(curVertex)? startVertexDistanceIndex[curVertex] : Graph.DISCONNECTED; // 3.2 calculate the distance from the root to the input vertex distance += graph.GetEdgeWeight(vertex, curVertex); //distance += ((VariableGraph)graph).get_edge_weight_of_graph(vertex, curVertex); // 3.3 update the distance if necessary double costOfVertex = startVertexDistanceIndex[vertex]; if (costOfVertex > distance) { startVertexDistanceIndex.AddOrReplace(vertex, distance); predecessorIndex.AddOrReplace(vertex, curVertex); cost = distance; } } // 4. create the subPath if exists Path subPath = null; if (cost < Graph.DISCONNECTED) { subPath = new Path(); subPath.SetWeight(cost); java.util.LinkedList <BaseVertex> vertexList = subPath.GetVertexList(); vertexList.add(vertex); BaseVertex selVertex = predecessorIndex[vertex]; while (selVertex != null) { vertexList.add(selVertex); selVertex = predecessorIndex.GetValueIfExists(selVertex); } } return(subPath); }
/// <summary> /// Return the weight associated with the input edge. /// </summary> /// <param name="source"> </param> /// <param name="sink"> /// @return </param> public override double get_edge_weight(BaseVertex source, BaseVertex sink) { int source_id = source.get_id(); int sink_id = sink.get_id(); if (_rem_vertex_id_set.Contains(source_id) || _rem_vertex_id_set.Contains(sink_id) || _rem_edge_set.Contains(new Pair <int, int>(source_id, sink_id))) { return(Graph.DISCONNECTED); } return(base.get_edge_weight(source, sink)); }
/** * Constructor 2 * * @param graph * @param sourceVertex * @param targetVertex */ public YenTopKShortestPathsAlg(BaseGraph graph, BaseVertex sourceVertex, BaseVertex targetVertex) { if (graph == null) { throw new System.ArgumentException("A NULL graph object occurs!"); } this.graph = new VariableGraph((Graph)graph); this.sourceVertex = sourceVertex; this.targetVertex = targetVertex; Init(); }
/** * Return the weight associated with the input edge. * * @param source * @param sink * @return */ public override double GetEdgeWeight(BaseVertex source, BaseVertex sink) { int sourceId = source.GetId(); int sinkId = sink.GetId(); if (remVertexIdSet.Contains(sourceId) || remVertexIdSet.Contains(sinkId) || remEdgeSet.Contains(new Pair <int, int>(sourceId, sinkId))) { return(Graph.DISCONNECTED); } return(base.GetEdgeWeight(source, sink)); }
/// <summary> /// Constructor 2 /// </summary> /// <param name="graph"> </param> /// <param name="source_vt"> </param> /// <param name="target_vt"> </param> public YenTopKShortestPathsAlg(BaseGraph graph, BaseVertex source_vt, BaseVertex target_vt) { if (graph == null) { throw new System.ArgumentException("A NULL graph object occurs!"); } // _graph = new VariableGraph((Graph)graph); _source_vertex = source_vt; _target_vertex = target_vt; // _init(); }
public virtual void correct_cost_backward(BaseVertex vertex) { // 1. initialize the list of vertex to be updated List <BaseVertex> vertex_list = new List <BaseVertex>(); vertex_list.Add(vertex); // 2. update the cost of relevant precedents of the input vertex if (vertex_list.Count != 0) { //vertex_list.RemoveFirst(); //if (vertex_list.Count > 1) // vertex_list.RemoveAt(0); BaseVertex cur_vertex = vertex_list[0]; double cost_of_cur_vertex = _start_vertex_distance_index[cur_vertex]; HashSet <BaseVertex> pre_vertex_set = _graph.get_precedent_vertices(cur_vertex); foreach (BaseVertex pre_vertex in pre_vertex_set) { double cost_of_pre_vertex = _start_vertex_distance_index.ContainsKey(pre_vertex) ? _start_vertex_distance_index[pre_vertex] : Graph.DISCONNECTED; double fresh_cost = cost_of_cur_vertex + _graph.get_edge_weight(pre_vertex, cur_vertex); //double fresh_cost = cost_of_cur_vertex + ((VariableGraph)_graph).get_edge_weight_of_graph(pre_vertex, cur_vertex); if (cost_of_pre_vertex > fresh_cost) { // _start_vertex_distance_index[pre_vertex] = fresh_cost; if (_start_vertex_distance_index.ContainsKey(pre_vertex)) { _start_vertex_distance_index[pre_vertex] = fresh_cost; } else { _start_vertex_distance_index.Add(pre_vertex, fresh_cost); } //_start_vertex_distance_index[pre_vertex] = fresh_cost; if (_predecessor_index.ContainsKey(pre_vertex)) { _start_vertex_distance_index[pre_vertex] = fresh_cost; } else { _predecessor_index.Add(pre_vertex, cur_vertex); } vertex_list.Add(pre_vertex); } } } }
// Set the leftmost edge as the first edge by definition. public Edge(BaseVertex firstVertex, BaseVertex secondVertex) { if (firstVertex.transform.position.x <= secondVertex.transform.position.x) { FirstVertex = firstVertex; SecondVertex = secondVertex; } else { FirstVertex = secondVertex; SecondVertex = firstVertex; } _distance = (SecondVertex.transform.position - FirstVertex.transform.position).magnitude; }
/// <summary> /// Get the top-K shortest paths connecting the source and the target. /// This is a batch execution of top-K results. /// </summary> /// <param name="source"> </param> /// <param name="sink"> </param> /// <param name="top_k"> /// @return </param> public List <Path> get_shortest_paths(BaseVertex source_vertex, BaseVertex target_vertex, int top_k) { _source_vertex = source_vertex; _target_vertex = target_vertex; _init(); int count = 0; while (has_next() && count < top_k) { next(); ++count; } return(_result_list); }
public bool EdgeExists(BaseVertex currentVertex, BaseVertex siblingVertex) { for (int i = 0; i < _edges.Count; i++) { bool isEdge = (_edges[i].FirstVertex.Equals(currentVertex) && _edges[i].SecondVertex.Equals(siblingVertex)) || (_edges[i].FirstVertex.Equals(siblingVertex) && _edges[i].SecondVertex.Equals(currentVertex)); if (isEdge) { return(true); } } return(false); }
// see comment at the top of the file regarding why the below Comparable<Vertex> methods has been removed // Some methods related to conversion from // Java code to .NET code // (Java Comparable and .NET IComparable) //public int CompareTo(Vertex other) //{ // return compareToo(other); //} //public int compareTo(BaseVertex other) //{ // return compareToo(other); //} //public int CompareTo(BaseVertex other) //{ // return compareToo(other); //} //public int compareTo(Vertex rVertex) { // return compareToo(rVertex); //} public override bool Equals(object obj) { if (this == obj) { return(true); } if (obj == null) { return(false); } if ((obj is Vertex) || (obj is BaseVertex)) { BaseVertex other = (BaseVertex)obj; return(this.GetId() == other.GetId()); } return(false); }
/** * Get the top-K shortest paths connecting the source and the target. * This is a batch execution of top-K results. * * @param source * @param sink * @param k * @return */ public IList <Path> GetShortestPaths(BaseVertex source, BaseVertex target, int k) { sourceVertex = source; targetVertex = target; Init(); int count = 0; while (HasNext() && count < k) { Next(); ++count; } return(resultList); }
// We use methods to manipulate the list of siblings instead of a property to ensure that the list // cannot be accessed directly. public bool AddSibling(BaseVertex newSibling) { if (_siblings == null) { _siblings = new List <BaseVertex>(); } // Add sibling only if it doesn't already exist in the list of siblings. BaseVertex match = _siblings.Find(s => s.Equals(newSibling)); if (match == null) { _siblings.Add(newSibling); return(true); } return(false); }
public bool RemoveSibling(BaseVertex sibling) { if (_siblings == null) { return(false); } // Remove sibling only if it exists in the list of siblings. BaseVertex match = _siblings.Find(s => s.Equals(sibling)); if (match != null) { _siblings.Remove(sibling); return(true); } return(false); }
/** * Note that, the source should not be as same as the sink! (we could extend * this later on) * * @param sourceVertex * @param sinkVertex * @return */ public Path GetShortestPath(BaseVertex sourceVertex, BaseVertex sinkVertex) { DetermineShortestPaths(sourceVertex, sinkVertex, true); // java.util.LinkedList <BaseVertex> vertexList = new java.util.LinkedList <BaseVertex>(); double weight = startVertexDistanceIndex.ContainsKey(sinkVertex) ? startVertexDistanceIndex[sinkVertex] : Graph.DISCONNECTED; if (weight != Graph.DISCONNECTED) { BaseVertex curVertex = sinkVertex; do { vertexList.add(curVertex); curVertex = predecessorIndex[curVertex]; } while (curVertex != null && curVertex != sourceVertex); vertexList.add(sourceVertex); vertexList.reverse(); } return(new Path(vertexList, weight)); }
/** * Get the set of vertices preceding the input vertex. * * @param vertex * @return */ public override ISet <BaseVertex> GetPrecedentVertices(BaseVertex vertex) { ISet <BaseVertex> retSet = new HashSet <BaseVertex>(); if (!remVertexIdSet.Contains(vertex.GetId())) { int endingVertexId = vertex.GetId(); ISet <BaseVertex> preVertexSet = base.GetPrecedentVertices(vertex); foreach (BaseVertex curVertex in preVertexSet) { int startingVertexId = curVertex.GetId(); if (remVertexIdSet.Contains(startingVertexId) || remEdgeSet.Contains(new Pair <int, int>(startingVertexId, endingVertexId))) { continue; } // retSet.Add(curVertex); } } return(retSet); }
/// <summary> /// Get the set of vertices preceding the input vertex. /// </summary> /// <param name="vertex"> /// @return </param> public override HashSet <BaseVertex> get_precedent_vertices(BaseVertex vertex) { HashSet <BaseVertex> ret_set = new HashSet <BaseVertex>(); if (!_rem_vertex_id_set.Contains(vertex.get_id())) { int ending_vertex_id = vertex.get_id(); HashSet <BaseVertex> pre_vertex_set = base.get_precedent_vertices(vertex); foreach (BaseVertex cur_vertex in pre_vertex_set) { int starting_vertex_id = cur_vertex.get_id(); if (_rem_vertex_id_set.Contains(starting_vertex_id) || _rem_edge_set.Contains(new Pair <int, int>(starting_vertex_id, ending_vertex_id))) { continue; } // ret_set.Add(cur_vertex); } } return(ret_set); }
/// <summary> /// Note that, the source should not be as same as the sink! (we could extend /// this later on) /// </summary> /// <param name="source_vertex"> </param> /// <param name="sink_vertex"> /// @return </param> public virtual Path get_shortest_path(BaseVertex source_vertex, BaseVertex sink_vertex) { determine_shortest_paths(source_vertex, sink_vertex, true); // List <BaseVertex> vertex_list = new List <BaseVertex>(); double weight = _start_vertex_distance_index.ContainsKey(sink_vertex) ? _start_vertex_distance_index[sink_vertex] : Graph.DISCONNECTED; if (weight != Graph.DISCONNECTED) { BaseVertex cur_vertex = sink_vertex; do { vertex_list.Add(cur_vertex); cur_vertex = _predecessor_index[cur_vertex]; } while (cur_vertex != null && cur_vertex != source_vertex); // vertex_list.Add(source_vertex); vertex_list.Reverse(); } // return(new Path(vertex_list, weight)); }
// Use this for initialization protected override void Start() { NoiseGenerator perlinNoiseGenerator = new NoiseGenerator(); _terrainVertices = new List <BaseVertex>(); // generate the specified number of vertices for the hill on the terrain, and position them // evenly float pointDistance = _endVertex.transform.position.x - _startVertex.transform.position.x; float xOffset = Mathf.Abs(pointDistance) / (_numDivisionsX + 2.0f); float yRange = _maxHeight - _minHeight; for (int i = 0; i <= _numDivisionsX; i++) { BaseVertex terrainVertex = Instantiate(_baseVertexPrefab, transform).AddComponent <BaseVertex>(); float xPosition = _startVertex.transform.position.x + (i + 1) * xOffset; float yPosition = perlinNoiseGenerator.GetNoise(i, _numDivisionsX, _minHeight, _maxHeight); float radialMask = 1.0f; // the further we are from the center of the hill, the more we attenuate the noise. // This gives a nice mountain-like profile to it. if (i > _numDivisionsX / 2.0f) { radialMask = (_numDivisionsX - i) / (_numDivisionsX / 2.0f); } else { radialMask = i / (_numDivisionsX / 2.0f); } // apply new y position (noise) yPosition += yRange / 2.0f; yPosition = transform.position.y + radialMask * yPosition; // cap the y position if needed, to ensure the level is physically clearable. float maxWorldHeight = transform.position.y + _maxHeight; float minWorldHeight = transform.position.y; if (yPosition > maxWorldHeight) { yPosition = maxWorldHeight; } else if (yPosition < minWorldHeight) { yPosition = minWorldHeight; } terrainVertex.transform.position = new Vector3(xPosition, yPosition, 0); _terrainVertices.Add(terrainVertex); } // make edges out of vertices of the terrain. They will be used for collisions for (int i = 1; i < _terrainVertices.Count - 1; i++) { _terrainVertices[i].AddSibling(_terrainVertices[i - 1]); _terrainVertices[i].AddSibling(_terrainVertices[i + 1]); } int verticesCount = _terrainVertices.Count; if (verticesCount > 1) { _terrainVertices[0].AddSibling(_startVertex); _terrainVertices[verticesCount - 1].AddSibling(_endVertex); _startVertex.AddSibling(_terrainVertices[0]); _endVertex.AddSibling(_terrainVertices[verticesCount - 1]); } AddVertex(_terrainVertices); base.Start(); }
/** * Get the shortest path among all that connecting source with targe. * * @return */ public Path Next() { //3.1 prepare for removing vertices and arcs Path curPath = pathCandidates.Poll(); resultList.Add(curPath); BaseVertex curDerivation = pathDerivationVertexIndex[curPath]; int curPathHash = curPath.GetVertexList().subList(0, curPath.GetVertexList().indexOf(curDerivation)).GetHashCode(); int count = resultList.Count; //3.2 remove the vertices and arcs in the graph for (int i = 0; i < count - 1; ++i) { Path curResultPath = resultList[i]; int curDevVertexId = curResultPath.GetVertexList().indexOf(curDerivation); if (curDevVertexId < 0) { continue; } // Note that the following condition makes sure all candidates should be considered. /// The algorithm in the paper is not correct for removing some candidates by mistake. int pathHash = curResultPath.GetVertexList().subList(0, curDevVertexId).GetHashCode(); if (pathHash != curPathHash) { continue; } BaseVertex curSuccVertex = curResultPath.GetVertexList().get(curDevVertexId + 1); graph.DeleteEdge(new Pair <int, int>( curDerivation.GetId(), curSuccVertex.GetId())); } int pathLength = curPath.GetVertexList().size(); java.util.LinkedList <BaseVertex> curPathVertexList = curPath.GetVertexList(); for (int i = 0; i < pathLength - 1; ++i) { graph.DeleteVertex(curPathVertexList.get(i).GetId()); graph.DeleteEdge(new Pair <int, int>( curPathVertexList.get(i).GetId(), curPathVertexList.get(i + 1).GetId())); } //3.3 calculate the shortest tree rooted at target vertex in the graph DijkstraShortestPathAlg reverseTree = new DijkstraShortestPathAlg(graph); reverseTree.GetShortestPathFlower(targetVertex); //3.4 recover the deleted vertices and update the cost and identify the new candidate results bool isDone = false; for (int i = pathLength - 2; i >= 0 && !isDone; --i) { //3.4.1 get the vertex to be recovered BaseVertex curRecoverVertex = curPathVertexList.get(i); graph.RecoverDeletedVertex(curRecoverVertex.GetId()); //3.4.2 check if we should stop continuing in the next iteration if (curRecoverVertex.GetId() == curDerivation.GetId()) { isDone = true; } //3.4.3 calculate cost using forward star form Path subPath = reverseTree.UpdateCostForward(curRecoverVertex); //3.4.4 get one candidate result if possible if (subPath != null) { ++generatedPathNum; //3.4.4.1 get the prefix from the concerned path double cost = 0; IList <BaseVertex> prePathList = new List <BaseVertex>(); reverseTree.CorrectCostBackward(curRecoverVertex); for (int j = 0; j < pathLength; ++j) { BaseVertex curVertex = curPathVertexList.get(j); if (curVertex.GetId() == curRecoverVertex.GetId()) { j = pathLength; } else { cost += graph.GetEdgeWeightOfGraph(curPathVertexList.get(j), curPathVertexList.get(j + 1)); prePathList.Add(curVertex); } } prePathList.AddAll(subPath.GetVertexList()); //3.4.4.2 compose a candidate subPath.SetWeight(cost + subPath.GetWeight()); subPath.GetVertexList().clear(); subPath.GetVertexList().addAll(prePathList); //3.4.4.3 put it in the candidate pool if new if (!pathDerivationVertexIndex.ContainsKey(subPath)) { pathCandidates.Add(subPath); pathDerivationVertexIndex.Add(subPath, curRecoverVertex); } } //3.4.5 restore the edge BaseVertex succVertex = curPathVertexList.get(i + 1); graph.RecoverDeletedEdge(new Pair <int, int>( curRecoverVertex.GetId(), succVertex.GetId())); //3.4.6 update cost if necessary double cost1 = graph.GetEdgeWeight(curRecoverVertex, succVertex) + reverseTree.GetStartVertexDistanceIndex()[succVertex]; if (reverseTree.GetStartVertexDistanceIndex()[curRecoverVertex] > cost1) { reverseTree.GetStartVertexDistanceIndex().AddOrReplace(curRecoverVertex, cost1); reverseTree.GetPredecessorIndex().AddOrReplace(curRecoverVertex, succVertex); reverseTree.CorrectCostBackward(curRecoverVertex); } } //3.5 restore everything graph.RecoverDeletedEdges(); graph.RecoverDeletedVertices(); return(curPath); }