1    // ============================================================================
2    //   Copyright 2006, 2007, 2008 Daniel W. Dyer
3    //
4    //   Licensed under the Apache License, Version 2.0 (the "License");
5    //   you may not use this file except in compliance with the License.
6    //   You may obtain a copy of the License at
7    //
8    //       http://www.apache.org/licenses/LICENSE-2.0
9    //
10   //   Unless required by applicable law or agreed to in writing, software
11   //   distributed under the License is distributed on an "AS IS" BASIS,
12   //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   //   See the License for the specific language governing permissions and
14   //   limitations under the License.
15   // ============================================================================
16   package org.uncommons.watchmaker.examples.travellingsalesman;
17   
18   import java.util.ArrayList;
19   import java.util.Collections;
20   import java.util.HashMap;
21   import java.util.List;
22   import java.util.Map;
23   
24   /**
25    * This class contains data about cities in Europe and the distances
26    * between them.
27    * @author Daniel Dyer
28    */
29   public final class EuropeanDistanceLookup implements DistanceLookup
30   {
31       private static final Map<String, Map<String, Integer>> DISTANCES = new HashMap<String, Map<String, Integer>>(15);
32       static
33       {
34           // Distances are in km as the crow flies (from http://www.indo.com/distance/)
35   
36           Map<String, Integer> amsterdam = new HashMap<String, Integer>(20);
37           amsterdam.put("Amsterdam", 0);
38           amsterdam.put("Athens", 2162);
39           amsterdam.put("Berlin", 576);
40           amsterdam.put("Brussels", 171);
41           amsterdam.put("Copenhagen", 622);
42           amsterdam.put("Dublin", 757);
43           amsterdam.put("Helsinki", 1506);
44           amsterdam.put("Lisbon", 1861);
45           amsterdam.put("London", 356);
46           amsterdam.put("Luxembourg", 318);
47           amsterdam.put("Madrid", 1477);
48           amsterdam.put("Paris", 429);
49           amsterdam.put("Rome", 1304);
50           amsterdam.put("Stockholm", 1132);
51           amsterdam.put("Vienna", 938);
52           DISTANCES.put("Amsterdam", amsterdam);
53   
54           Map<String, Integer> athens = new HashMap<String, Integer>(20);
55           athens.put("Amsterdam", 2162);
56           athens.put("Athens", 0);
57           athens.put("Berlin", 1801);
58           athens.put("Brussels", 2089);
59           athens.put("Copenhagen", 2140);
60           athens.put("Dublin", 2860);
61           athens.put("Helsinki", 2464);
62           athens.put("Lisbon", 2854);
63           athens.put("London", 2391);
64           athens.put("Luxembourg", 1901);
65           athens.put("Madrid", 2374);
66           athens.put("Paris", 2097);
67           athens.put("Rome", 1040);
68           athens.put("Stockholm", 2410);
69           athens.put("Vienna", 1280);
70           DISTANCES.put("Athens", athens);
71   
72           Map<String, Integer> berlin = new HashMap<String, Integer>(20);
73           berlin.put("Amsterdam", 576);
74           berlin.put("Athens", 1801);
75           berlin.put("Berlin", 0);
76           berlin.put("Brussels", 648);
77           berlin.put("Copenhagen", 361);
78           berlin.put("Dublin", 1315);
79           berlin.put("Helsinki", 1108);
80           berlin.put("Lisbon", 2310);
81           berlin.put("London", 929);
82           berlin.put("Luxembourg", 595);
83           berlin.put("Madrid", 1866);
84           berlin.put("Paris", 877);
85           berlin.put("Rome", 1185);
86           berlin.put("Stockholm", 818);
87           berlin.put("Vienna", 525);
88           DISTANCES.put("Berlin", berlin);
89   
90           Map<String, Integer> brussels = new HashMap<String, Integer>(20);
91           brussels.put("Amsterdam", 171);
92           brussels.put("Athens", 2089);
93           brussels.put("Berlin", 648);
94           brussels.put("Brussels", 0);
95           brussels.put("Copenhagen", 764);
96           brussels.put("Dublin", 780);
97           brussels.put("Helsinki", 1649);
98           brussels.put("Lisbon", 1713);
99           brussels.put("London", 321);
100          brussels.put("Luxembourg", 190);
101          brussels.put("Madrid", 1315);
102          brussels.put("Paris", 266);
103          brussels.put("Rome", 1182);
104          brussels.put("Stockholm", 1284);
105          brussels.put("Vienna", 917);
106          DISTANCES.put("Brussels", brussels);
107  
108          Map<String, Integer> copenhagen = new HashMap<String, Integer>(20);
109          copenhagen.put("Amsterdam", 622);
110          copenhagen.put("Athens", 2140);
111          copenhagen.put("Berlin", 361);
112          copenhagen.put("Brussels", 764);
113          copenhagen.put("Copenhagen", 0);
114          copenhagen.put("Dublin", 1232);
115          copenhagen.put("Helsinki", 885);
116          copenhagen.put("Lisbon", 2477);
117          copenhagen.put("London", 953);
118          copenhagen.put("Luxembourg", 799);
119          copenhagen.put("Madrid", 2071);
120          copenhagen.put("Paris", 1028);
121          copenhagen.put("Rome", 1540);
122          copenhagen.put("Stockholm", 526);
123          copenhagen.put("Vienna", 876);
124          DISTANCES.put("Copenhagen", copenhagen);
125  
126          Map<String, Integer> dublin = new HashMap<String, Integer>(20);
127          dublin.put("Amsterdam", 757);
128          dublin.put("Athens", 2860);
129          dublin.put("Berlin", 1315);
130          dublin.put("Brussels", 780);
131          dublin.put("Copenhagen", 1232);
132          dublin.put("Dublin", 0);
133          dublin.put("Helsinki", 2021);
134          dublin.put("Lisbon", 1652);
135          dublin.put("London", 469);
136          dublin.put("Luxembourg", 961);
137          dublin.put("Madrid", 1458);
138          dublin.put("Paris", 787);
139          dublin.put("Rome", 1903);
140          dublin.put("Stockholm", 1625);
141          dublin.put("Vienna", 1687);
142          DISTANCES.put("Dublin", dublin);
143  
144          Map<String, Integer> helsinki = new HashMap<String, Integer>(20);
145          helsinki.put("Amsterdam", 1506);
146          helsinki.put("Athens", 2464);
147          helsinki.put("Berlin", 1108);
148          helsinki.put("Brussels", 1649);
149          helsinki.put("Copenhagen", 885);
150          helsinki.put("Dublin", 2021);
151          helsinki.put("Helsinki", 0);
152          helsinki.put("Lisbon", 3362);
153          helsinki.put("London", 1823);
154          helsinki.put("Luxembourg", 1667);
155          helsinki.put("Madrid", 2949);
156          helsinki.put("Paris", 1912);
157          helsinki.put("Rome", 2202);
158          helsinki.put("Stockholm", 396);
159          helsinki.put("Vienna", 1439);
160          DISTANCES.put("Helsinki", helsinki);
161  
162          Map<String, Integer> lisbon = new HashMap<String, Integer>(20);
163          lisbon.put("Amsterdam", 1861);
164          lisbon.put("Athens", 2854);
165          lisbon.put("Berlin", 2310);
166          lisbon.put("Brussels", 1713);
167          lisbon.put("Copenhagen", 2477);
168          lisbon.put("Dublin", 1652);
169          lisbon.put("Helsinki", 3362);
170          lisbon.put("Lisbon", 0);
171          lisbon.put("London", 1585);
172          lisbon.put("Luxembourg", 1716);
173          lisbon.put("Madrid", 501);
174          lisbon.put("Paris", 1452);
175          lisbon.put("Rome", 1873);
176          lisbon.put("Stockholm", 2993);
177          lisbon.put("Vienna", 2300);
178          DISTANCES.put("Lisbon", lisbon);
179  
180          Map<String, Integer> london = new HashMap<String, Integer>(20);
181          london.put("Amsterdam", 356);
182          london.put("Athens", 2391);
183          london.put("Berlin", 929);
184          london.put("Brussels", 321);
185          london.put("Copenhagen", 953);
186          london.put("Dublin", 469);
187          london.put("Helsinki", 1823);
188          london.put("Lisbon", 1585);
189          london.put("London", 0);
190          london.put("Luxembourg", 494);
191          london.put("Madrid", 1261);
192          london.put("Paris", 343);
193          london.put("Rome", 1444);
194          london.put("Stockholm", 1436);
195          london.put("Vienna", 1237);
196          DISTANCES.put("London", london);
197  
198          Map<String, Integer> luxembourg = new HashMap<String, Integer>(20);
199          luxembourg.put("Amsterdam", 318);
200          luxembourg.put("Athens", 1901);
201          luxembourg.put("Berlin", 595);
202          luxembourg.put("Brussels", 190);
203          luxembourg.put("Copenhagen", 799);
204          luxembourg.put("Dublin", 961);
205          luxembourg.put("Helsinki", 1667);
206          luxembourg.put("Lisbon", 1716);
207          luxembourg.put("London", 494);
208          luxembourg.put("Luxembourg", 0);
209          luxembourg.put("Madrid", 1282);
210          luxembourg.put("Paris", 294);
211          luxembourg.put("Rome", 995);
212          luxembourg.put("Stockholm", 1325);
213          luxembourg.put("Vienna", 761);
214          DISTANCES.put("Luxembourg", luxembourg);
215  
216          Map<String, Integer> madrid = new HashMap<String, Integer>(20);
217          madrid.put("Amsterdam", 1477);
218          madrid.put("Athens", 2374);
219          madrid.put("Berlin", 1866);
220          madrid.put("Brussels", 1315);
221          madrid.put("Copenhagen", 2071);
222          madrid.put("Dublin", 1458);
223          madrid.put("Helsinki", 2949);
224          madrid.put("Lisbon", 501);
225          madrid.put("London", 1261);
226          madrid.put("Luxembourg", 1282);
227          madrid.put("Madrid", 0);
228          madrid.put("Paris", 1050);
229          madrid.put("Rome", 1377);
230          madrid.put("Stockholm", 2596);
231          madrid.put("Vienna", 1812);
232          DISTANCES.put("Madrid", madrid);
233  
234          Map<String, Integer> paris = new HashMap<String, Integer>(20);
235          paris.put("Amsterdam", 429);
236          paris.put("Athens", 2097);
237          paris.put("Berlin", 877);
238          paris.put("Brussels", 266);
239          paris.put("Copenhagen", 1028);
240          paris.put("Dublin", 787);
241          paris.put("Helsinki", 1912);
242          paris.put("Lisbon", 1452);
243          paris.put("London", 343);
244          paris.put("Luxembourg", 294);
245          paris.put("Madrid", 1050);
246          paris.put("Paris", 0);
247          paris.put("Rome", 1117);
248          paris.put("Stockholm", 1549);
249          paris.put("Vienna", 1037);
250          DISTANCES.put("Paris", paris);
251  
252          Map<String, Integer> rome = new HashMap<String, Integer>(20);
253          rome.put("Amsterdam", 1304);
254          rome.put("Athens", 1040);
255          rome.put("Berlin", 1185);
256          rome.put("Brussels", 1182);
257          rome.put("Copenhagen", 1540);
258          rome.put("Dublin", 1903);
259          rome.put("Helsinki", 2202);
260          rome.put("Lisbon", 1873);
261          rome.put("London", 1444);
262          rome.put("Luxembourg", 995);
263          rome.put("Madrid", 1377);
264          rome.put("Paris", 1117);
265          rome.put("Rome", 0);
266          rome.put("Stockholm", 1984);
267          rome.put("Vienna", 765);
268          DISTANCES.put("Rome", rome);
269  
270          Map<String, Integer> stockholm = new HashMap<String, Integer>(20);
271          stockholm.put("Amsterdam", 1132);
272          stockholm.put("Athens", 2410);
273          stockholm.put("Berlin", 818);
274          stockholm.put("Brussels", 1284);
275          stockholm.put("Copenhagen", 526);
276          stockholm.put("Dublin", 1625);
277          stockholm.put("Helsinki", 396);
278          stockholm.put("Lisbon", 2993);
279          stockholm.put("London", 1436);
280          stockholm.put("Luxembourg", 1325);
281          stockholm.put("Madrid", 2596);
282          stockholm.put("Paris", 1549);
283          stockholm.put("Rome", 1984);
284          stockholm.put("Stockholm", 0);
285          stockholm.put("Vienna", 1247);
286          DISTANCES.put("Stockholm", stockholm);
287  
288          Map<String, Integer> vienna = new HashMap<String, Integer>(20);
289          vienna.put("Amsterdam", 938);
290          vienna.put("Athens", 1280);
291          vienna.put("Berlin", 525);
292          vienna.put("Brussels", 917);
293          vienna.put("Copenhagen", 876);
294          vienna.put("Dublin", 1687);
295          vienna.put("Helsinki", 1439);
296          vienna.put("Lisbon", 2300);
297          vienna.put("London", 1237);
298          vienna.put("Luxembourg", 761);
299          vienna.put("Madrid", 1812);
300          vienna.put("Paris", 1037);
301          vienna.put("Rome", 765);
302          vienna.put("Stockholm", 1247);
303          vienna.put("Vienna", 0);
304          DISTANCES.put("Vienna", vienna);
305      }
306  
307  
308      /**
309       * {@inheritDoc}
310       */
311      public List<String> getKnownCities()
312      {
313          List<String> cities = new ArrayList<String>(DISTANCES.keySet());
314          Collections.sort(cities);
315          return cities;
316      }
317  
318  
319      /**
320       * {@inheritDoc}
321       */
322      public int getDistance(String startingCity, String destinationCity)
323      {
324          return DISTANCES.get(startingCity).get(destinationCity);
325      }
326  }
327