Free cookie consent management tool by TermsFeed Policy Generator

source: branches/1894_RoutePlanning/HeuristicLab.Algorithms.GraphRouting/3.3/AStarAlgorithmV4.cs @ 17987

Last change on this file since 17987 was 8527, checked in by spimming, 12 years ago

#1894:

  • introduced heap interface
  • various heap implementation used as priority queues
  • very simple logger added
  • various versions of Astar algorithm
File size: 4.6 KB
Line 
1
2using System;
3using System.Collections.Generic;
4using HeuristicLab.Algorithms.GraphRouting.Interfaces;
5using HeuristicLab.Problems.RoutePlanning.Interfaces;
6using HeuristicLab.Problems.RoutePlanning.RoutingGraph;
7namespace HeuristicLab.Algorithms.GraphRouting {
8  public class AStarAlgorithmV4 : IRouter {
9    private IGraph graph;
10    private ICostCalculator costCalculator;
11
12    private Dictionary<long, float> distances;
13    private Dictionary<long, long> predecessors;
14    private List<long> closedList;
15    private HashSet<long> closedListLookup;
16    private SortedSet<NodeData> openList;
17    private Dictionary<long, NodeData> openListLookup;
18
19    public AStarAlgorithmV4(IGraph graph)
20      : this(graph, new TravelTimeCostCalculator()) {
21    }
22
23    public AStarAlgorithmV4(IGraph graph, ICostCalculator costCalc) {
24      this.graph = graph;
25      this.costCalculator = costCalc;
26    }
27
28    #region IRouter Members
29
30    public long[] Calculate(long sourceNodeId, long targetNodeId) {
31      distances = new Dictionary<long, float>();
32      predecessors = new Dictionary<long, long>();
33      closedList = new List<long>();
34      closedListLookup = new HashSet<long>();
35      openList = new SortedSet<NodeData>();
36      openListLookup = new Dictionary<long, NodeData>();
37
38      long currentNode = sourceNodeId;
39
40      NodeData nd = new NodeData(currentNode, 0);
41      openList.Add(nd);
42      openListLookup.Add(currentNode, nd);
43      distances.Add(currentNode, 0);
44
45      while (openList.Count > 0) {
46        NodeData data = openList.Min;
47        openList.Remove(data);
48        openListLookup.Remove(data.Node);
49        currentNode = data.Node;
50        if (currentNode == targetNodeId) {
51          return ReconstructPath(currentNode).ToArray();
52        }
53
54        //--------------
55        //Logger.LogToFile("cn = " + currentNode + " (" + data.Costs + ")");
56        //--------------
57
58        Dictionary<long, float> currentNeighbors = graph.GetNeighborsWithWeight(currentNode);
59        foreach (KeyValuePair<long, float> neighbor in currentNeighbors) {
60          if (closedListLookup.Contains(neighbor.Key))
61            continue;
62
63          float costsFromStart = GetDistance(currentNode) + neighbor.Value;
64
65          if (openListLookup.ContainsKey(neighbor.Key) && costsFromStart > GetDistance(neighbor.Key))
66            continue;
67
68          distances[neighbor.Key] = costsFromStart;
69          predecessors[neighbor.Key] = currentNode;
70
71          Vertex vertNeigh = graph.GetVertex(neighbor.Key);
72          Vertex vertTarget = graph.GetVertex(targetNodeId);
73          float f = costsFromStart + costCalculator.EstimatedCosts(vertNeigh, vertTarget);
74
75          //--------------
76          //Logger.LogToFile("    neigb:" + neighbor.Key + " (" + costsFromStart + " / " + f + ")");
77          //--------------
78
79          if (openListLookup.ContainsKey(neighbor.Key)) {
80            openList.Remove(openListLookup[neighbor.Key]);
81            openListLookup.Remove(neighbor.Key);
82          }
83
84          NodeData newNode = new NodeData(neighbor.Key, f);
85          while (!openList.Add(newNode)) {
86            newNode.Costs = newNode.Costs + 0.0000001f;
87          }
88          openListLookup.Add(newNode.Node, newNode);
89        }
90        closedList.Add(currentNode);
91        closedListLookup.Add(currentNode);
92        //--------------
93        //Logger.LogToFile("");
94        //--------------
95      }
96      throw new Exception(string.Format("No route found from {0} to {1}", sourceNodeId, targetNodeId));
97    }
98
99    #endregion
100
101    private float GetDistance(long id) {
102      float d;
103      if (distances.TryGetValue(id, out d)) {
104        return d;
105      } else { return float.MaxValue; }
106    }
107
108    private List<long> ReconstructPath(long nodeId) {
109      List<long> route = new List<long>();
110      long current = nodeId;
111      long next;
112
113      if (!predecessors.TryGetValue(current, out next)) {
114        return null;
115      }
116      route.Add(current);
117      while (predecessors.TryGetValue(current, out next)) {
118        current = predecessors[current];
119        route.Add(current);
120      }
121      route.Reverse();
122      return route;
123    }
124
125    private class NodeData : IComparable<NodeData> {
126      public long Node { get; set; }
127      public float Costs { get; set; }
128
129      public NodeData(long nodeId, float f) {
130        Node = nodeId;
131        Costs = f;
132      }
133
134      #region IComparable<NodeData> Members
135
136      public int CompareTo(NodeData other) {
137        return this.Costs > other.Costs ? 1 : this.Costs < other.Costs ? -1 : 0;
138      }
139
140      #endregion
141    }
142  }
143}
Note: See TracBrowser for help on using the repository browser.