Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1894:

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