PGROUTING  3.2
Dmatrix.cpp
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 
3 FILE: Dmatrix.cpp
4 
5 Copyright (c) 2015 pgRouting developers
7 
8 ------
9 
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14 
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 
24  ********************************************************************PGR-GNU*/
25 
26 #include "cpp_common/Dmatrix.h"
27 
28 #include <string.h>
29 #include <sstream>
30 #include <algorithm>
31 #include <limits>
32 #include <vector>
33 #include <map>
34 #include <cmath>
35 
36 #include "tsp/tour.h"
37 #include "cpp_common/pgr_assert.h"
38 
39 
40 namespace pgrouting {
41 namespace tsp {
42 
43 double
44 Dmatrix::tourCost(const Tour &tour) const {
45  double total_cost(0);
46  if (tour.cities.empty()) return total_cost;
47 
48  auto prev_id = tour.cities.front();
49  for (const auto &id : tour.cities) {
50  if (id == tour.cities.front()) continue;
51 
52  pgassert(distance(prev_id, id) != (std::numeric_limits<double>::max)());
53 
54  total_cost += costs[prev_id][id];
55  prev_id = id;
56  }
57  total_cost += costs[prev_id][tour.cities.front()];
58  return total_cost;
59 }
60 
61 
62 
63 void
64 Dmatrix::set_ids(const std::vector < Matrix_cell_t > &data_costs) {
65  ids.reserve(data_costs.size() * 2);
66  for (const auto &cost : data_costs) {
67  ids.push_back(cost.from_vid);
68  ids.push_back(cost.to_vid);
69  }
70  std::sort(ids.begin(), ids.end());
71  ids.erase(std::unique(ids.begin(), ids.end()), ids.end());
72  /*
73  * freeing up unused space
74  */
75  ids.shrink_to_fit();
76 }
77 
78 bool
79 Dmatrix::has_id(int64_t id) const {
80  for (const auto &i : ids) {
81  if (i == id) return true;
82  }
83  return false;
84 }
85 
86 
92 size_t
93 Dmatrix::get_index(int64_t id) const {
94  for (size_t pos = 0; pos < ids.size(); ++pos) {
95  if (ids[pos] == id) return pos;
96  }
97  throw std::make_pair(std::string("(INTERNAL) Dmatrix: Unable to find node on matrix"), id);
98 }
99 
100 int64_t
101 Dmatrix::get_id(size_t id) const {
102  return ids[id];
103 }
104 
105 /*
106  * Transforms the input data to a matrix
107  */
108 Dmatrix::Dmatrix(const std::vector < Matrix_cell_t > &data_costs) {
109  set_ids(data_costs);
110  costs.resize(
111  ids.size(),
112  std::vector<double>(
113  ids.size(),
114  (std::numeric_limits<double>::max)()));
115 
116  for (const auto &data : data_costs) {
117  costs[get_index(data.from_vid)][get_index(data.to_vid)] = data.cost;
118  }
119 
120  for (size_t i = 0; i < costs.size(); ++i) {
121  costs[i][i] = 0;
122  }
123 }
124 
125 
126 double
127 get_distance(std::pair<double, double> p1 , std::pair<double, double> p2) {
128  auto dx = p1.first - p2.first;
129  auto dy = p1.second - p2.second;
130  return std::sqrt(dx * dx + dy * dy);
131 }
132 
133 /*
134  * constructor for euclidean
135  */
136 Dmatrix::Dmatrix(const std::map<std::pair<double, double>, int64_t> &euclidean_data) {
137  ids.reserve(euclidean_data.size());
138  for (const auto &e: euclidean_data) {
139  ids.push_back(e.second);
140  }
141  costs.resize(
142  ids.size(),
143  std::vector<double>(
144  ids.size(),
145  (std::numeric_limits<double>::max)()));
146 
147  for (const auto &from : euclidean_data) {
148  for (const auto &to : euclidean_data) {
149  auto from_id = get_index(from.second);
150  auto to_id = get_index(to.second);
151  costs[from_id][to_id] = get_distance(from.first, to.first);
152  costs[to_id][from_id] = costs[from_id][to_id];
153  }
154  }
155 
156  for (size_t i = 0; i < costs.size(); ++i) {
157  costs[i][i] = 0;
158  }
159 }
160 
161 bool
163  for (const auto &row : costs) {
164  for (const auto &val : row) {
165  if (val == (std::numeric_limits<double>::infinity)()) return false;
166  if (val == (std::numeric_limits<double>::max)()) return false;
167  }
168  }
169  return true;
170 }
171 
172 
180 bool
182  for (size_t i = 0; i < costs.size(); ++i) {
183  for (size_t j = 0; j < costs.size(); ++j) {
184  for (size_t k = 0; k < costs.size(); ++k) {
185  if (!(costs[i][k] <= (costs[i][j] + costs[j][k]))) return false;
186  }
187  }
188  }
189  return true;
190 }
191 
192 bool
194  for (size_t i = 0; i < costs.size(); ++i) {
195  for (size_t j = 0; j < costs.size(); ++j) {
196  if (0.000001 < std::fabs(costs[i][j] - costs[j][i])) {
197  std::ostringstream log;
198  log << "i \t" << i
199  << "j \t" << j
200  << "costs[i][j] \t" << costs[i][j]
201  << "costs[j][i] \t" << costs[j][i]
202  << "\n";
203  log << (*this);
204  pgassertwm(false, log.str());
205  return false;
206  }
207  }
208  }
209  return true;
210 }
211 
212 
216 std::ostream& operator<<(std::ostream &log, const Dmatrix &matrix) {
217  for (const auto id : matrix.ids) {
218  log << "\t" << id;
219  }
220  log << "\n";
221  size_t i = 0;
222  for (const auto &row : matrix.costs) {
223  size_t j = 0;
224  for (const auto cost : row) {
225  log << "Internal(" << i << "," << j << ")"
226  << "\tUsers(" << matrix.ids[i] << "," << matrix.ids[j] << ")"
227  << "\t = " << cost
228 #if 0
229  << "\t(" << matrix.get_index(matrix.ids[i])
230  << "," << matrix.get_index(matrix.ids[j]) << ")"
231  << "\t = " << matrix.costs[i][j]
232  << "\t = " << matrix.costs[j][i]
233  << "=inf:"
234  << (matrix.costs[i][j] ==
235  (std::numeric_limits<double>::infinity)())
236  << "=inf:"
237  << (matrix.costs[j][i] ==
238  (std::numeric_limits<double>::infinity)())
239 #endif
240  << "\n";
241  ++j;
242  }
243  ++i;
244  }
245 #if 0
246  for (size_t i = 0; i < matrix.costs.size(); ++i) {
247  for (size_t j = 0; j < matrix.costs.size(); ++j) {
248  for (size_t k = 0; k < matrix.costs.size(); ++k) {
249  log << matrix.costs[i][k] << " <= ("
250  << matrix.costs[i][j] << " + " << matrix.costs[j][k] << ")"
251  << (matrix.costs[i][k]
252  <= (matrix.costs[i][j] + matrix.costs[j][k]))
253  << "\n";
254  }
255  }
256  }
257 #endif
258  return log;
259 }
260 
261 
262 } // namespace tsp
263 } // namespace pgrouting
pgrouting::tsp::Dmatrix::get_index
size_t get_index(int64_t id) const
original id -> idx
Definition: Dmatrix.cpp:93
pgrouting::tsp::Tour
Definition: tour.h:42
pgrouting::tsp::Dmatrix::tourCost
double tourCost(const Tour &tour) const
tour evaluation
Definition: Dmatrix.cpp:44
pgassertwm
#define pgassertwm(expr, msg)
Adds a message to the assertion.
Definition: pgr_assert.h:117
pgrouting::tsp::Dmatrix::is_symmetric
bool is_symmetric() const
Definition: Dmatrix.cpp:193
pgrouting::tsp::Dmatrix::has_no_infinity
bool has_no_infinity() const
Definition: Dmatrix.cpp:162
pgassert
#define pgassert(expr)
Uses the standard assert syntax.
Definition: pgr_assert.h:94
pgrouting::tsp::Dmatrix::has_id
bool has_id(int64_t id) const
original id -> true
Definition: Dmatrix.cpp:79
pgrouting::tsp::Dmatrix::ids
std::vector< int64_t > ids
Definition: Dmatrix.h:124
pgrouting::tsp::operator<<
std::ostream & operator<<(std::ostream &log, const Dmatrix &matrix)
Definition: Dmatrix.cpp:216
pgrouting::tsp::Dmatrix::get_id
int64_t get_id(size_t idx) const
idx -> original id
Definition: Dmatrix.cpp:101
pgrouting::tsp::Tour::cities
std::vector< size_t > cities
Definition: tour.h:156
pgrouting::tsp::Dmatrix::costs
Costs costs
Definition: Dmatrix.h:128
pgr_assert.h
An assert functionality that uses C++ throw().
pgrouting::tsp::Dmatrix::obeys_triangle_inequality
bool obeys_triangle_inequality() const
Triangle Inequality Theorem.
Definition: Dmatrix.cpp:181
Dmatrix.h
pgrouting::tsp::Dmatrix::set_ids
void set_ids(const std::vector< matrix_cell > &data_costs)
Definition: Dmatrix.cpp:64
tour.h
pgrouting::tsp::Dmatrix::distance
double distance(int64_t i, int64_t j) const
Definition: Dmatrix.h:108
pgrouting::tsp::get_distance
double get_distance(std::pair< double, double > p1, std::pair< double, double > p2)
Definition: Dmatrix.cpp:127
pgrouting::tsp::Dmatrix::Dmatrix
Dmatrix()=default
pgrouting::tsp::Dmatrix
Definition: Dmatrix.h:43
pgrouting
Book keeping class for swapping orders between vehicles.
Definition: pgr_alphaShape.cpp:56