-
-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathtabu.cpp
More file actions
218 lines (185 loc) · 5.78 KB
/
Copy pathtabu.cpp
File metadata and controls
218 lines (185 loc) · 5.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/*PGR-GNU*****************************************************************
File: tabu.cpp
Copyright (c) 2021 pgRouting developers
Mail: project@pgrouting.org
Developer:
Copyright (c) 2021 Copyright (c) 2021 Joseph Emile Honour Percival
------
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
********************************************************************PGR-GNU*/
#include "initialsol/tabu.hpp"
#include <deque>
#include <algorithm>
#include <limits>
#include "cpp_common/assert.hpp"
#include "cpp_common/messages.hpp"
#include "problem/pickDeliver.hpp"
#if 0
#include "cpp_common/fleet.hpp"
#endif
namespace vrprouting {
namespace initialsol {
namespace tabu {
/**
@invariant assigned UNION unassigned = all_orders
@invariant assigned INTERSECTION unassigned = empty
*/
void
Initial_solution::invariant() const {
pgassert(m_all_orders == (m_assigned + m_unassigned));
pgassert((m_assigned * m_unassigned).empty());
}
/**
@param [in] execution_date used for setting unmovable orders from the past
@param [in] optimize prepare orders for optimization
@param [in] problem_ptr the problem pointer
*/
Initial_solution::Initial_solution(
TTimestamp execution_date,
bool optimize,
problem::PickDeliver &problem_ptr) :
Solution(problem_ptr),
m_all_orders(),
m_unassigned(),
m_assigned() {
invariant();
/**
* Get all the orders
* - when an order is feasible on at least one vehicles is part of the orders set
* - unfeasible orders are ignored
*/
m_all_orders = vehicles().feasible_orders();
m_unassigned = m_all_orders;
process_given_solution_from_user(execution_date, optimize);
pgassert(is_feasible());
/**
* From the of used vehicles
* When there are unassigned orders
* - mark as unmovable all orders on vehicles where the unassigned orders
* are not feasible
*/
if (!m_unassigned.empty()) {
for (auto &v : m_fleet) {
bool is_usable(false);
for (const auto &o : m_unassigned) {
if (v.feasible_orders().has(o)) {
/*
* found an order to be inserted that fits on the vehicle
*/
is_usable = true;
break;
}
}
/*
* No order to be inserted fits on the vehicle
*/
if (!is_usable) v.set_unmovable(std::numeric_limits<TTimestamp>::max());
}
}
/**
* Get the remaining empty unused vehicles
*/
auto unused = vehicles().get_unused_trucks();
m_fleet.insert(m_fleet.end(), unused.begin(), unused.end());
pgassert(is_feasible());
/**
* add the unassigned orders to phony vehicles
*/
process_unassigned();
pgassert(is_feasible());
invariant();
}
/**
* User's initial solution is considered
* @pre m_fleet is empty
* @pre invariant()
* @pre m_fleet has vehicles that have orders
* @post invariant()
* @post is feasible
*/
void
Initial_solution::process_given_solution_from_user(TTimestamp execution_date, bool optimize) {
pgassert(m_fleet.empty());
invariant();
/**
* Set the initial solution given by the user
*/
vehicles().set_initial_solution(orders(), m_assigned, m_unassigned, execution_date, optimize);
/**
* Used vehicles: are the ones that have a solution from the user
*/
auto used_v = vehicles().get_used_trucks();
/**
* The solution fleet are the used vehicles
*/
m_fleet.insert(m_fleet.end(), used_v.begin(), used_v.end());
pgassert(is_feasible());
invariant();
}
/**
@pre invariant()
@pre is_feasible()
@post invariant()
@post is_feasible()
@post unassigned is empty
*/
void
Initial_solution::process_unassigned() {
/**
* test pre conditions
*/
invariant();
pgassert(is_feasible());
Identifiers<size_t> notused;
auto not_assigned = m_unassigned;
/**
* cycle the unassigned orders
*/
for (const auto o : not_assigned) {
/**
* - get a new phony vehicle
*/
auto phony_v = vehicles().get_phony();
if (!phony_v.is_order_feasible(orders()[o])) {
phony_v.push_back(orders()[o]);
m_unassigned -= o;
m_all_orders -= o;
error << "\n**Illegal Order** pick.opens() + tt > drop.closes() can not be inserted on any vehicle";
continue;
}
/**
* - Add the order to the phony vehicle
*/
phony_v.push_back(orders()[o]);
pgassert(phony_v.is_feasible());
/**
* - update for invariant
*/
m_assigned += o;
m_unassigned -= o;
/**
* - Add the vehicle to the fleet
*/
m_fleet.push_back(phony_v);
invariant();
}
/**
* test post conditions
*/
pgassert(m_unassigned.empty());
pgassert(is_feasible());
invariant();
}
} // namespace tabu
} // namespace initialsol
} // namespace vrprouting