Free cookie consent management tool by TermsFeed Policy Generator

source: branches/RoutePlanning/HeuristicLab.Algorithms.GraphRouting/3.3/BidirectionalDijkstraAlgorithmV2.cs @ 8481

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

#1894:

  • adapted AStar and Dijkstra algorithms for new graph representation
  • test program modified
File size: 5.3 KB
Line 
1
2using System;
3using System.Collections.Generic;
4using HeuristicLab.Problems.RoutePlanning.Graph;
5namespace HeuristicLab.Algorithms.GraphRouting {
6  public class BidrectionalDijkstraAlgorithmV2 : IRouter {
7    private IGraph graph;
8
9    private HashSet<long> visitedNodesForward;
10    private HashSet<long> visitedNodesBackward;
11    private HashSet<long> unvisitedNodesForward;
12    private HashSet<long> unvisitedNodesBackward;
13    private Dictionary<long, float> distancesForward;
14    private Dictionary<long, long> predecessorsForward;
15    private Dictionary<long, float> distancesBackward;
16    private Dictionary<long, long> predecessorsBackward;
17
18    public BidrectionalDijkstraAlgorithmV2(IGraph graph) {
19      this.graph = graph;
20    }
21
22    #region IRouter Members
23
24    public long[] Calculate(long sourceNodeId, long targetNodeId) {
25      visitedNodesForward = new HashSet<long>();
26      visitedNodesBackward = new HashSet<long>();
27
28      unvisitedNodesForward = new HashSet<long>();
29      unvisitedNodesBackward = new HashSet<long>();
30
31      distancesForward = new Dictionary<long, float>();
32      predecessorsForward = new Dictionary<long, long>();
33
34      distancesBackward = new Dictionary<long, float>();
35      predecessorsBackward = new Dictionary<long, long>();
36
37      List<long> resultRouteForward = new List<long>();
38      List<long> resultRouteBackward = new List<long>();
39
40      if (sourceNodeId == targetNodeId) {
41        resultRouteForward.Add(sourceNodeId);
42        return resultRouteForward.ToArray();
43      }
44
45      long currentNodeForward = sourceNodeId;
46      distancesForward.Add(currentNodeForward, 0);
47      unvisitedNodesForward.Add(currentNodeForward);
48
49      long currentNodeBackward = targetNodeId;
50      distancesBackward.Add(currentNodeBackward, 0);
51      unvisitedNodesBackward.Add(currentNodeBackward);
52
53      while (unvisitedNodesForward.Count > 0 && unvisitedNodesBackward.Count > 0) {
54        currentNodeForward = GetMinimumDistance(distancesForward, unvisitedNodesForward);
55        visitedNodesForward.Add(currentNodeForward);
56        unvisitedNodesForward.Remove(currentNodeForward);
57
58        currentNodeBackward = GetMinimumDistance(distancesBackward, unvisitedNodesBackward);
59        visitedNodesBackward.Add(currentNodeBackward);
60        unvisitedNodesBackward.Remove(currentNodeBackward);
61
62        if (visitedNodesForward.Contains(currentNodeBackward)) {
63          return GetRoute(currentNodeBackward).ToArray();
64        }
65
66        if (visitedNodesBackward.Contains(currentNodeForward)) {
67          return GetRoute(currentNodeForward).ToArray();
68        }
69
70        FindMinimalWeightForward(currentNodeForward);
71        FindMinimalWeightBackward(currentNodeBackward);
72      }
73
74      throw new Exception(string.Format("No route found from {0} to {1}", sourceNodeId, targetNodeId));
75    }
76
77    #endregion
78
79    private long GetMinimumDistance(Dictionary<long, float> distances, HashSet<long> nodeIds) {
80      long minimum = -1;
81      foreach (long id in nodeIds) {
82        if (minimum == -1) minimum = id;
83        else {
84          if (GetDistance(distances, id) < GetDistance(distances, minimum)) {
85            minimum = id;
86          }
87        }
88      }
89      return minimum;
90    }
91
92    private float GetDistance(Dictionary<long, float> distances, long id) {
93      float d;
94      if (distances.TryGetValue(id, out d)) {
95        return d;
96      } else { return float.MaxValue; }
97    }
98
99    private void FindMinimalWeightForward(long nodeId) {
100      Dictionary<long, float> currentNeighbors = graph.GetNeighborsWithWeight(nodeId);
101      foreach (KeyValuePair<long, float> neighbor in currentNeighbors) {
102        // update relax
103        float totalWeight = GetDistance(distancesForward, nodeId) + neighbor.Value;
104        if (GetDistance(distancesForward, neighbor.Key) > totalWeight) {
105          distancesForward[neighbor.Key] = totalWeight;
106          predecessorsForward[neighbor.Key] = nodeId;
107          unvisitedNodesForward.Add(neighbor.Key);
108        }
109      }
110    }
111
112    private void FindMinimalWeightBackward(long nodeId) {
113      Dictionary<long, float> currentNeighbors = graph.GetNeighborsWithWeightReversed(nodeId);
114      foreach (KeyValuePair<long, float> neighbor in currentNeighbors) {
115        // update relax
116        float totalWeight = GetDistance(distancesBackward, nodeId) + neighbor.Value;
117        if (GetDistance(distancesBackward, neighbor.Key) > totalWeight) {
118          distancesBackward[neighbor.Key] = totalWeight;
119          predecessorsBackward[neighbor.Key] = nodeId;
120          unvisitedNodesBackward.Add(neighbor.Key);
121        }
122      }
123    }
124
125    private List<long> GetRoute(long nodeId) {
126      List<long> route = new List<long>();
127      long current = nodeId;
128      long next;
129
130      if (!predecessorsForward.TryGetValue(current, out next)) {
131        return null;
132      }
133      route.Add(current);
134      while (predecessorsForward.TryGetValue(current, out next)) {
135        current = predecessorsForward[current];
136        route.Add(current);
137      }
138      route.Reverse();
139
140      current = nodeId;
141      while (predecessorsBackward.TryGetValue(current, out next)) {
142        current = predecessorsBackward[current];
143        route.Add(current);
144      }
145
146      return route;
147    }
148  }
149}
Note: See TracBrowser for help on using the repository browser.