Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DistanceMeasures/PathMeasure.cs @ 8670

Last change on this file since 8670 was 8670, checked in by svonolfe, 12 years ago

Added first version of the dynamic vehicle routing addon (#1955)

File size: 8.8 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
6using HeuristicLab.Common;
7using HeuristicLab.Data;
8using HeuristicLab.Parameters;
9using HeuristicLab.PDPSimulation.DomainModel;
10
11namespace HeuristicLab.PDPSimulation.DistanceMeasures {
12  [StorableClass]
13  public class PathMeasure: DistanceMatrixMeasure {
14    private ValueParameter<BoolMatrix> EdgesParameter {
15      get { return (ValueParameter<BoolMatrix>)Parameters["Edges"]; }
16    }
17
18    private ValueParameter<IntMatrix> VerticesParameter {
19      get { return (ValueParameter<IntMatrix>)Parameters["Vertices"]; }
20    }
21
22    public ValueParameter<BoolValue> UseDistanceMatrix {
23      get { return (ValueParameter<BoolValue>)Parameters["UseDistanceMatrix"]; }
24    }
25
26    public ValueParameter<DoubleValue> PixelScalingFactor {
27      get { return (ValueParameter<DoubleValue>)Parameters["PixelScalingFactor"]; }
28    }
29
30    public BoolMatrix Edges {
31      get {
32        return EdgesParameter.Value;
33      }
34      set {
35        EdgesParameter.Value = value;
36      }
37    }
38
39    public IntMatrix Vertices {
40      get {
41        return VerticesParameter.Value;
42      }
43      set {
44        VerticesParameter.Value = value;
45      }
46    }
47
48    public PathMeasure()
49      : base() {
50        Parameters.Add(new ValueParameter<BoolMatrix>("Edges", new BoolMatrix()));
51        Parameters.Add(new ValueParameter<IntMatrix>("Vertices", new IntMatrix()));
52        Parameters.Add(new ValueParameter<BoolValue>("UseDistanceMatrix", new BoolValue(true)));
53        Parameters.Add(new ValueParameter<DoubleValue>("PixelScalingFactor", new DoubleValue(1.0)));
54
55        EdgesParameter.GetsCollected = false;
56        VerticesParameter.GetsCollected = false;
57
58        graph = null;
59
60        AttachEventHandlers();
61    }
62   
63    [StorableConstructor]
64    private PathMeasure(bool deserializing) : base(deserializing) {
65    }
66    private PathMeasure(PathMeasure original, Cloner cloner)
67      : base(original, cloner) {
68    }
69    public override IDeepCloneable Clone(Cloner cloner) {
70      return new PathMeasure(this, cloner);
71    }
72
73    private void AttachEventHandlers() {
74      EdgesParameter.ValueChanged += new EventHandler(EdgesParameter_ValueChanged);
75      VerticesParameter.ValueChanged += new EventHandler(VerticesParameter_ValueChanged);
76    }
77
78    void VerticesParameter_ValueChanged(object sender, EventArgs e) {
79      graph = null;
80    }
81    void EdgesParameter_ValueChanged(object sender, EventArgs e) {
82      graph = null;
83    }
84
85    [StorableHook(HookType.AfterDeserialization)]
86    private void AfterDeserializationHook() {
87      graph = null;
88      AttachEventHandlers();
89    }
90
91    #region Graph
92    private List<Vertex> graph;
93
94    class Vertex {
95      public int Index { get; set; }
96      public Dictionary<Vertex, double> Edges { get; set; }
97
98      public Vertex() {
99        Edges = new Dictionary<Vertex, double>();
100      }
101    }
102
103    private void BuildGraph() {
104      graph = new List<Vertex>();
105     
106      IntMatrix vertices = VerticesParameter.Value;
107      BoolMatrix edges = EdgesParameter.Value;
108      for (int i = 0; i < vertices.Rows; i++) {
109        Vertex v = new Vertex();
110        v.Index = i;
111        graph.Add(v);
112      }
113
114      for (int i = 0; i < vertices.Rows; i++) {
115        for (int j = 0; j < vertices.Rows; j++) {
116          if (edges[i, j]) {
117            double weight = GetEuclideanDistance(vertices[i, 0], vertices[i, 1], vertices[j, 0], vertices[j, 1]);
118            graph[i].Edges.Add(graph[j], weight);
119          }
120        }
121      }
122    }
123
124    private List<Vertex> FindShortestPath(Vertex source, Vertex destination) {   
125      Dictionary<Vertex, double> distance = new Dictionary<Vertex, double>();
126      Dictionary<Vertex, Vertex> previous = new Dictionary<Vertex, Vertex>();
127      foreach (Vertex v in graph) {
128        distance[v] = double.MaxValue;
129        previous[v] = null;
130      }
131
132      List<Vertex> Q = new List<Vertex>(graph);
133      distance[source] = 0;
134      Q.Remove(source);
135      Q.Insert(0, source);
136
137      bool found = false;
138      while (!found && Q.Count > 0) {
139        Vertex u = Q[0];
140        if (distance[u] == double.MaxValue)
141          break;
142        Q.Remove(u);
143        if (u == destination) {
144          found = true;
145        } else {
146          foreach (Vertex v in u.Edges.Keys) {
147            if (Q.Contains(v)) {
148              double alt = distance[u] + u.Edges[v];
149              if (alt < distance[v]) {
150                distance[v] = alt;
151                previous[v] = u;
152
153                Q.Remove(v);
154                int i = 0;
155                while (i < Q.Count && distance[Q[i]] < alt) {
156                  i++;
157                }
158                Q.Insert(i, v);
159              }
160            }
161          }
162        }
163      }
164
165      if (found) {
166        List<Vertex> shortestPath = new List<Vertex>();
167        Vertex u = destination;
168
169        while (previous[u] != null) {
170          shortestPath.Insert(0, u);
171          u = previous[u];
172        }
173
174        shortestPath.Insert(0, source);
175
176        if(shortestPath.Count == 1)
177          shortestPath.Insert(0, source);
178
179        return shortestPath;
180      } else {
181        return null;
182      }
183    }
184
185    private double GetPathLength(List<Vertex> path) {     
186      double length = 0;
187
188      if (path.Count > 2) {
189        for (int i = 0; i < path.Count - 1; i++) {
190          length += path[i].Edges[path[i + 1]];
191        }
192      }
193
194      return length;
195    }
196    #endregion
197
198    protected int GetVertexMapping(double x, double y) {
199      IntMatrix vertices = VerticesParameter.Value;
200      int index = -1;
201
202      int ix = (int)Math.Round(x);
203      int iy = (int)Math.Round(y);
204
205      int i = 0;
206      while (index < 0 && i < vertices.Rows) {
207        if (vertices[i, 0] == ix && vertices[i, 1] == iy) {
208          index = i;
209        }
210        i++;
211      }
212
213      return index;
214    }
215
216    public override double GetDistance(double sourceX, double sourceY,
217    double destX, double destY) {
218      if (UseDistanceMatrix.Value.Value)
219        return base.GetDistance(sourceX, sourceY, destX, destY);
220      else {
221        int i = GetVertexMapping(sourceX, sourceY);
222        int j = GetVertexMapping(destX, destY);
223
224        if (graph == null)
225          BuildGraph();
226
227        List<Vertex> path = FindShortestPath(graph[i], graph[j]);
228        if (path == null)
229          return int.MaxValue;
230        else
231          return GetPathLength(path) / PixelScalingFactor.Value.Value;
232      }
233    }
234
235    public override void Move(double sourceX, double sourceY,
236      double currentX, double currentY,
237      double destX, double destY, double time, Vehicle.MoveInformation moveInfo,
238      out double newPosX, out double newPosY, out double length) {
239      if (graph == null)
240         BuildGraph();
241     
242      int i = GetVertexMapping(sourceX, sourceY);
243      int j = GetVertexMapping(destX, destY);
244
245      if (moveInfo.Source != i || moveInfo.Dest != j) {
246        moveInfo.Source = i;
247        moveInfo.Dest = j;
248        moveInfo.Segment = 0;
249        moveInfo.Path = null;
250      }
251
252      if (moveInfo.Path == null) {
253        moveInfo.Path = FindShortestPath(graph[i], graph[j]);
254      }
255      List<Vertex> path = (List<Vertex>)(moveInfo.Path);
256      double step = 0;
257      double pathDist = GetPathLength(path);
258      double actualDist = 0;
259      if (UseDistanceMatrix.Value.Value)
260        actualDist = base.GetDistance(sourceX, sourceY, destX, destY);
261      else
262        actualDist = pathDist / PixelScalingFactor.Value.Value;
263
264      if (actualDist != 0)
265        step = pathDist / actualDist;
266
267      IntMatrix vertices = VerticesParameter.Value;
268      length = 0;
269      newPosX = currentX;
270      newPosY = currentY;
271      while (time > 0 && moveInfo.Segment < path.Count - 1) {
272        int nextIndex = path[moveInfo.Segment + 1].Index;
273        double nextX = vertices[nextIndex, 0];
274        double nextY = vertices[nextIndex, 1];
275
276        double distance = 0;
277        if(step != 0)
278          distance = GetEuclideanDistance(newPosX, newPosY, nextX, nextY) / step;
279        if (distance <= time) {
280          newPosX = nextX;
281          newPosY = nextY;
282
283          length += distance;
284          time -= distance;
285          moveInfo.Segment++;
286        } else {
287          double vx = nextX - newPosX;
288          double vy = nextY - newPosY;
289          double vl = GetEuclideanDistance(newPosX, newPosY, nextX, nextY);
290          vx = (vx / vl) * time * step;
291          vy = (vy / vl) * time * step;
292
293          length += GetEuclideanDistance(newPosX, newPosY, newPosX + vx, newPosY + vy) / step;
294          newPosX = newPosX + vx;
295          newPosY = newPosY + vy;
296          time = 0;
297        }
298      }
299    }
300  }
301}
Note: See TracBrowser for help on using the repository browser.