Line data Source code
1 : #include <catch2/catch_get_random_seed.hpp>
2 : #include <catch2/catch_test_macros.hpp>
3 : #include <catch2/matchers/catch_matchers_floating_point.hpp>
4 : #include <cmath>
5 : #include <fstream>
6 : #include <ios>
7 : #include <iostream>
8 : #include <istream>
9 : #include <memory>
10 : #include <random>
11 :
12 : #include "Log/ProgressLoggerIgnore.hpp"
13 : #include "Log/ProgressLoggerTableOStream.hpp"
14 : #include "Opt/GeneticIntervalSolver.hpp"
15 : #include "Opt/GoldenSectionSolver.hpp"
16 : #include "Opt/QuadraticGuessSolver.hpp"
17 : #include "Opt/QuadraticSolver.hpp"
18 : #include "Static/algos/ConjugateFrankWolfe.hpp"
19 : #include "Static/algos/DijkstraAoN.hpp"
20 : #include "Static/algos/FrankWolfe.hpp"
21 : #include "Static/algos/IterativeEquilibration.hpp"
22 : #include "Static/supply/BPRConvexNetwork.hpp"
23 : #include "Static/supply/BPRNetwork.hpp"
24 : #include "Static/supply/BPRNotConvexNetwork.hpp"
25 : #include "data/SUMO/EdgeData.hpp"
26 : #include "data/SUMO/Routes.hpp"
27 : #include "data/SUMO/TAZ.hpp"
28 : #include "test/problem/cases.hpp"
29 :
30 : using namespace std;
31 : using Catch::Matchers::WithinAbs;
32 : using Catch::Matchers::WithinRel;
33 :
34 : extern string baseDir;
35 : extern string benchmarkDir;
36 :
37 : typedef chrono::steady_clock clk;
38 :
39 : const double MATRIX_9_10_TOTAL_DEMAND = 102731.0 / (60 * 60);
40 :
41 3 : TEST_CASE("Frank-Wolfe", "[fw]") {
42 3 : Log::ProgressLoggerTableOStream logger;
43 :
44 4 : SECTION("Case 1") {
45 1 : auto problem = getStaticProblemTestCase1();
46 :
47 1 : Static::DijkstraAoN aon;
48 2 : Static::SolutionBase x0 = aon.solve(*problem.first, *problem.second);
49 :
50 2 : REQUIRE_THAT(x0.getFlowInEdge(1), WithinAbs(0.0, 1e-10));
51 2 : REQUIRE_THAT(x0.getFlowInEdge(2), WithinAbs(4.0, 1e-10));
52 2 : REQUIRE_THAT(x0.getFlowInEdge(3), WithinAbs(4.0, 1e-10));
53 :
54 2 : Opt::GoldenSectionSolver solver;
55 1 : solver.setInterval(0.0, 1.0);
56 1 : solver.setStopCriteria(1e-6);
57 :
58 2 : Static::FrankWolfe fw(aon, solver, logger);
59 1 : fw.setStopCriteria(1e-3);
60 2 : Static::Solution x = fw.solve(*problem.first, *problem.second, x0);
61 :
62 1 : double x1 = (-3.0 + sqrt(53)) / 2.0;
63 2 : REQUIRE_THAT(x.getFlowInEdge(1), WithinAbs(x1, 1e-6));
64 2 : REQUIRE_THAT(x.getFlowInEdge(2), WithinAbs(4.0 - x1, 1e-6));
65 2 : REQUIRE_THAT(x.getFlowInEdge(3), WithinAbs(4.0, 1e-10));
66 :
67 2 : REQUIRE_THAT(x.getTotalFlow(), WithinAbs(problem.second->getTotalDemand(), 1e-6));
68 :
69 1 : delete problem.first;
70 2 : delete problem.second;
71 : }
72 :
73 4 : SECTION("Case 2") {
74 1 : auto problem = getStaticProblemTestCase2();
75 :
76 1 : Static::DijkstraAoN aon;
77 2 : Static::SolutionBase x0 = aon.solve(*problem.first, *problem.second);
78 :
79 2 : REQUIRE_THAT(x0.getFlowInEdge(1), WithinAbs(0.0, 1e-10));
80 2 : REQUIRE_THAT(x0.getFlowInEdge(2), WithinAbs(7000.0, 1e-10));
81 :
82 2 : Opt::GoldenSectionSolver solver;
83 1 : solver.setInterval(0.0, 1.0);
84 1 : solver.setStopCriteria(1e-6);
85 :
86 2 : Static::FrankWolfe fw(aon, solver, logger);
87 1 : fw.setStopCriteria(1e-3);
88 2 : Static::Solution x = fw.solve(*problem.first, *problem.second, x0);
89 :
90 1 : double x1 = 3376.36917;
91 2 : REQUIRE_THAT(x.getFlowInEdge(1), WithinAbs(x1, 1e-2));
92 2 : REQUIRE_THAT(x.getFlowInEdge(2), WithinAbs(7000.0 - x1, 1e-2));
93 :
94 2 : REQUIRE_THAT(x.getTotalFlow(), WithinAbs(problem.second->getTotalDemand(), 1e-6));
95 :
96 1 : delete problem.first;
97 2 : delete problem.second;
98 : }
99 :
100 4 : SECTION("Case 3") {
101 1 : auto problem = getStaticProblemTestCase3();
102 :
103 1 : Static::DijkstraAoN aon;
104 2 : Static::SolutionBase x0 = aon.solve(*problem.first, *problem.second);
105 :
106 2 : Opt::GoldenSectionSolver solver;
107 1 : solver.setInterval(0.0, 1.0);
108 1 : solver.setStopCriteria(1e-6);
109 :
110 2 : Static::FrankWolfe fw(aon, solver, logger);
111 1 : fw.setStopCriteria(1e-3);
112 2 : Static::Solution x = fw.solve(*problem.first, *problem.second, x0);
113 :
114 1 : double x1 = 4131.89002;
115 2 : REQUIRE_THAT(x.getFlowInEdge(1), WithinAbs(x1, 1e-2));
116 2 : REQUIRE_THAT(x.getFlowInEdge(2), WithinAbs(7000.0 - x1, 1e-2));
117 :
118 2 : REQUIRE_THAT(x.getTotalFlow(), WithinAbs(problem.second->getTotalDemand(), 1e-6));
119 :
120 1 : delete problem.first;
121 2 : delete problem.second;
122 : }
123 3 : }
124 :
125 : const double PORTO_ARMIS_AON_COST = 442094728.844042182;
126 :
127 0 : TEST_CASE("Frank-Wolfe - Large", "[fw][fw-large][!benchmark]") {
128 0 : Log::ProgressLoggerTableOStream logger;
129 :
130 : // Supply
131 0 : shared_ptr<SUMO::Network> sumoNetwork = SUMO::Network::loadFromFile(benchmarkDir + "data/dynaminator-data/porto-armis.net.xml");
132 0 : SUMO::TAZs sumoTAZs = SUMO::TAZ::loadFromFile(benchmarkDir + "data/dynaminator-data/porto-armis.taz.xml");
133 0 : SUMO::NetworkTAZs sumo{*sumoNetwork, sumoTAZs};
134 :
135 : // Demand
136 0 : VISUM::OFormatDemand oDemand = VISUM::OFormatDemand::loadFromFile(benchmarkDir + "data/dynaminator-data/matrix.9.0.10.0.2.fma");
137 :
138 0 : clk::time_point begin = clk::now();
139 :
140 0 : SECTION("Convex") {
141 0 : Static::BPRNetwork::Loader<SUMO::NetworkTAZs> loader;
142 0 : Static::BPRNetwork *network = loader.load(sumo);
143 :
144 0 : Static::Demand::Loader<const VISUM::OFormatDemand &, const Static::SUMOAdapter &> demandLoader;
145 0 : Static::Demand demand = demandLoader.load(oDemand, loader.adapter);
146 :
147 0 : double totalDemand = demand.getTotalDemand();
148 0 : REQUIRE_THAT(totalDemand, WithinAbs(MATRIX_9_10_TOTAL_DEMAND, 1e-4));
149 :
150 0 : SECTION("Large") {
151 0 : Static::DijkstraAoN aon;
152 0 : Static::SolutionBase x0 = aon.solve(*network, demand);
153 0 : REQUIRE_THAT(network->evaluate(x0), WithinAbs(18094.5701505728, 1e-4));
154 :
155 0 : Opt::QuadraticSolver innerSolver;
156 0 : Opt::QuadraticGuessSolver solver(
157 : innerSolver,
158 : 0.5,
159 : 0.2,
160 : 0.845,
161 : 0.365
162 0 : );
163 0 : solver.setStopCriteria(0.01);
164 :
165 0 : Static::FrankWolfe fw(aon, solver, logger);
166 :
167 0 : double epsilon = 5.0;
168 0 : fw.setStopCriteria(epsilon);
169 0 : fw.setIterations(10000);
170 :
171 0 : Static::Solution x = fw.solve(*network, demand, x0);
172 :
173 0 : REQUIRE_THAT(x.getTotalFlow(), WithinAbs(totalDemand, 1e-4));
174 0 : REQUIRE_THAT(network->evaluate(x), WithinAbs(12330.7051681671, epsilon));
175 : }
176 :
177 0 : delete network;
178 : }
179 :
180 0 : SECTION("Not convex") {
181 0 : Static::BPRNotConvexNetwork::Loader<SUMO::NetworkTAZs> loader;
182 0 : Static::BPRNotConvexNetwork *network = loader.load(sumo);
183 :
184 0 : Static::Demand::Loader<const VISUM::OFormatDemand &, const Static::SUMOAdapter &> demandLoader;
185 0 : Static::Demand demand = demandLoader.load(oDemand, loader.adapter);
186 :
187 0 : double totalDemand = demand.getTotalDemand();
188 0 : REQUIRE_THAT(totalDemand, WithinAbs(MATRIX_9_10_TOTAL_DEMAND, 1e-4));
189 :
190 : // FW
191 0 : Static::DijkstraAoN aon;
192 0 : Static::SolutionBase x0 = aon.solve(*network, demand);
193 0 : REQUIRE_THAT(network->evaluate(x0), WithinRel(PORTO_ARMIS_AON_COST, 0.005));
194 :
195 0 : SECTION("Normal FW") {
196 : // Solver
197 0 : Opt::GeneticIntervalSolver solver(
198 : 8,
199 : 8,
200 : 0.1,
201 : 1000,
202 : 8,
203 0 : std::make_shared<std::mt19937>(0)
204 0 : );
205 0 : solver.setInterval(0, 1);
206 0 : solver.setStopCriteria(1e-6);
207 :
208 0 : Static::FrankWolfe fw(aon, solver, logger);
209 :
210 0 : double epsilon = 1.0;
211 0 : fw.setStopCriteria(epsilon);
212 0 : fw.setIterations(15);
213 :
214 0 : Static::Solution x = fw.solve(*network, demand, x0);
215 :
216 0 : REQUIRE_THAT(x.getTotalFlow(), WithinAbs(totalDemand, 1e-4));
217 0 : REQUIRE_THAT(network->evaluate(x), WithinRel(5397115.9215797437, 0.005));
218 : }
219 :
220 0 : SECTION("Normal FW - convex approximation") {
221 : // Solver
222 0 : Opt::QuadraticSolver innerSolver;
223 0 : Opt::QuadraticGuessSolver solver(
224 : innerSolver,
225 : 0.5,
226 : 0.2,
227 : 0.845,
228 : 0.365
229 0 : );
230 0 : solver.setStopCriteria(0.01);
231 :
232 0 : Static::FrankWolfe fw(aon, solver, logger);
233 :
234 0 : double epsilon = 1.0;
235 0 : fw.setStopCriteria(epsilon);
236 0 : fw.setIterations(25);
237 :
238 0 : Static::Solution zero;
239 :
240 0 : Static::Solution x = fw.solve(network->makeConvex(zero), demand, x0);
241 :
242 0 : REQUIRE_THAT(x.getTotalFlow(), WithinAbs(totalDemand, 1e-4));
243 0 : REQUIRE_THAT(network->evaluate(x), WithinRel(99544739.6486251801, 0.001));
244 : }
245 :
246 0 : delete network;
247 : }
248 :
249 0 : clk::time_point end = clk::now();
250 0 : cout << "Time difference = " << (double)chrono::duration_cast<chrono::nanoseconds>(end - begin).count() * 1e-9 << " [s]" << endl;
251 0 : }
252 :
253 0 : TEST_CASE("Conjugate Frank-Wolfe - large tests", "[cfw][cfw-large][!benchmark]") {
254 0 : Log::ProgressLoggerTableOStream logger;
255 :
256 : // Supply
257 0 : shared_ptr<SUMO::Network> sumoNetwork = SUMO::Network::loadFromFile(benchmarkDir + "data/dynaminator-data/porto-armis.net.xml");
258 0 : SUMO::TAZs sumoTAZs = SUMO::TAZ::loadFromFile(benchmarkDir + "data/dynaminator-data/porto-armis.taz.xml");
259 0 : SUMO::NetworkTAZs sumo{*sumoNetwork, sumoTAZs};
260 :
261 : // Demand
262 0 : VISUM::OFormatDemand oDemand = VISUM::OFormatDemand::loadFromFile(benchmarkDir + "data/dynaminator-data/matrix.9.0.10.0.2.fma");
263 :
264 0 : clk::time_point begin = clk::now();
265 :
266 0 : SECTION("Large") {
267 0 : Static::BPRNetwork::Loader<SUMO::NetworkTAZs> loader;
268 0 : Static::BPRNetwork *network = loader.load(sumo);
269 :
270 0 : Static::Demand::Loader<const VISUM::OFormatDemand &, const Static::SUMOAdapter &> demandLoader;
271 0 : Static::Demand demand = demandLoader.load(oDemand, loader.adapter);
272 :
273 0 : double totalDemand = demand.getTotalDemand();
274 0 : REQUIRE_THAT(totalDemand, WithinAbs(MATRIX_9_10_TOTAL_DEMAND, 1e-4));
275 :
276 0 : Static::DijkstraAoN aon;
277 0 : Static::SolutionBase x0 = aon.solve(*network, demand);
278 0 : REQUIRE_THAT(network->evaluate(x0), WithinAbs(18094.5701505728, 1e-4));
279 :
280 0 : Opt::QuadraticSolver innerSolver;
281 0 : Opt::QuadraticGuessSolver solver(
282 : innerSolver,
283 : 0.5,
284 : 0.2,
285 : 0.845,
286 : 0.365
287 0 : );
288 0 : solver.setStopCriteria(0.01);
289 :
290 0 : Static::ConjugateFrankWolfe fw(aon, solver, logger);
291 :
292 0 : double epsilon = 1.0;
293 0 : fw.setStopCriteria(epsilon);
294 0 : fw.setIterations(10000);
295 :
296 0 : Static::Solution x = fw.solve(*network, demand, x0);
297 :
298 0 : REQUIRE_THAT(x.getTotalFlow(), WithinAbs(totalDemand, 1e-4));
299 0 : REQUIRE_THAT(network->evaluate(x), WithinAbs(12328.3692388374, epsilon));
300 :
301 0 : delete network;
302 : }
303 :
304 0 : SECTION("Large not convex") {
305 0 : Static::BPRNotConvexNetwork::Loader<SUMO::NetworkTAZs> loader;
306 0 : Static::BPRNotConvexNetwork *network = loader.load(sumo);
307 :
308 0 : Static::Demand::Loader<const VISUM::OFormatDemand &, const Static::SUMOAdapter &> demandLoader;
309 0 : Static::Demand demand = demandLoader.load(oDemand, loader.adapter);
310 :
311 0 : double totalDemand = demand.getTotalDemand();
312 0 : REQUIRE_THAT(totalDemand, WithinAbs(MATRIX_9_10_TOTAL_DEMAND, 1e-4));
313 :
314 0 : Static::DijkstraAoN aon;
315 0 : Static::SolutionBase x0 = aon.solve(*network, demand);
316 0 : REQUIRE_THAT(network->evaluate(x0), WithinRel(PORTO_ARMIS_AON_COST, 0.005));
317 :
318 0 : Opt::GeneticIntervalSolver solver(
319 : 8,
320 : 8,
321 : 0.1,
322 : 1000,
323 : 8,
324 0 : std::make_shared<std::mt19937>(0)
325 0 : );
326 0 : solver.setInterval(0, 1);
327 0 : solver.setStopCriteria(1e-6);
328 :
329 0 : Static::ConjugateFrankWolfe fw(aon, solver, logger);
330 :
331 0 : double epsilon = 1.0;
332 0 : fw.setStopCriteria(epsilon);
333 0 : fw.setIterations(15);
334 :
335 0 : Static::Solution x = fw.solve(*network, demand, x0);
336 :
337 0 : REQUIRE_THAT(x.getTotalFlow(), WithinAbs(totalDemand, 1e-4));
338 0 : REQUIRE_THAT(network->evaluate(x), WithinRel(5398577.8846157538, 0.005));
339 :
340 0 : delete network;
341 : }
342 :
343 0 : clk::time_point end = clk::now();
344 0 : cout << "Time difference = " << (double)chrono::duration_cast<chrono::nanoseconds>(end - begin).count() * 1e-9 << " [s]" << endl;
345 0 : }
346 :
347 0 : TEST_CASE("Iterative equilibration", "[ie][!benchmark]") {
348 0 : Log::ProgressLoggerTableOStream logger;
349 :
350 0 : Static::BPRNotConvexNetwork::Loader<SUMO::NetworkTAZs> loader;
351 :
352 : // Supply
353 0 : shared_ptr<SUMO::Network> sumoNetwork = SUMO::Network::loadFromFile(benchmarkDir + "data/dynaminator-data/porto-armis.net.xml");
354 0 : SUMO::TAZs sumoTAZs = SUMO::TAZ::loadFromFile(benchmarkDir + "data/dynaminator-data/porto-armis.taz.xml");
355 0 : SUMO::NetworkTAZs sumo{*sumoNetwork, sumoTAZs};
356 0 : Static::BPRNotConvexNetwork *network = loader.load(sumo);
357 :
358 : // Demand
359 0 : VISUM::OFormatDemand oDemand = VISUM::OFormatDemand::loadFromFile(benchmarkDir + "data/dynaminator-data/matrix.9.0.10.0.2.fma");
360 0 : Static::Demand::Loader<const VISUM::OFormatDemand &, const Static::SUMOAdapter &> demandLoader;
361 0 : Static::Demand demand = demandLoader.load(oDemand, loader.adapter);
362 :
363 0 : double totalDemand = demand.getTotalDemand();
364 0 : REQUIRE_THAT(totalDemand, WithinAbs(MATRIX_9_10_TOTAL_DEMAND, 1e-4));
365 :
366 0 : clk::time_point begin = clk::now();
367 :
368 0 : Static::DijkstraAoN aon;
369 0 : Static::SolutionBase x0 = aon.solve(*network, demand);
370 0 : REQUIRE_THAT(network->evaluate(x0), WithinRel(PORTO_ARMIS_AON_COST, 0.005));
371 :
372 0 : SECTION("FW") {
373 0 : Opt::QuadraticSolver innerSolver;
374 0 : Opt::QuadraticGuessSolver solver(
375 : innerSolver,
376 : 0.5,
377 : 0.2,
378 : 0.845,
379 : 0.365
380 0 : );
381 0 : solver.setStopCriteria(0.01);
382 :
383 0 : Static::FrankWolfe fw(aon, solver, Log::ProgressLoggerIgnore::INSTANCE);
384 :
385 0 : double epsilon = 1.0;
386 0 : fw.setStopCriteria(epsilon);
387 0 : fw.setIterations(3);
388 :
389 0 : Static::IterativeEquilibration<Static::BPRNotConvexNetwork, Static::FrankWolfe> ie(fw, logger);
390 0 : ie.setIterations(15);
391 :
392 0 : Static::Solution x = ie.solve(*network, demand, x0);
393 :
394 0 : clk::time_point end = clk::now();
395 0 : cout << "Time difference = " << (double)chrono::duration_cast<chrono::nanoseconds>(end - begin).count() * 1e-9 << " [s]" << endl;
396 :
397 0 : REQUIRE_THAT(x.getTotalFlow(), WithinAbs(totalDemand, 1e-4));
398 0 : REQUIRE_THAT(network->evaluate(x), WithinRel(5381438.867287376, 0.005));
399 : }
400 :
401 0 : SECTION("CFW") {
402 0 : Opt::QuadraticSolver innerSolver;
403 0 : Opt::QuadraticGuessSolver solver(
404 : innerSolver,
405 : 0.5,
406 : 0.2,
407 : 0.845,
408 : 0.365
409 0 : );
410 0 : solver.setStopCriteria(0.01);
411 :
412 0 : Static::ConjugateFrankWolfe fw(aon, solver, Log::ProgressLoggerIgnore::INSTANCE);
413 :
414 0 : fw.setStopCriteria(0.0);
415 0 : fw.setIterations(5);
416 :
417 0 : Static::IterativeEquilibration<Static::BPRNotConvexNetwork, Static::ConjugateFrankWolfe> ie(fw, logger);
418 0 : ie.setIterations(10);
419 :
420 0 : Static::Solution x = ie.solve(*network, demand, x0);
421 :
422 0 : clk::time_point end = clk::now();
423 0 : cout << "Time difference = " << (double)chrono::duration_cast<chrono::nanoseconds>(end - begin).count() * 1e-9 << " [s]" << endl;
424 :
425 0 : REQUIRE_THAT(x.getTotalFlow(), WithinAbs(totalDemand, 1e-4));
426 0 : REQUIRE_THAT(network->evaluate(x), WithinRel(5380740.3194306595, 0.005));
427 : }
428 :
429 0 : delete network;
430 0 : }
431 :
432 0 : TEST_CASE("Iterative equilibration - Fixed map", "[ie-fixed][!benchmark]") {
433 0 : Log::ProgressLoggerTableOStream logger;
434 :
435 0 : Static::BPRNotConvexNetwork::Loader<SUMO::NetworkTAZs> loader;
436 :
437 : // Supply
438 0 : shared_ptr<SUMO::Network> sumoNetwork = SUMO::Network::loadFromFile(benchmarkDir + "data/dynaminator-data/porto.net.xml");
439 0 : SUMO::TAZs sumoTAZs = SUMO::TAZ::loadFromFile(benchmarkDir + "data/dynaminator-data/porto.taz.xml");
440 0 : SUMO::NetworkTAZs sumo{*sumoNetwork, sumoTAZs};
441 0 : Static::BPRNotConvexNetwork *network = loader.load(sumo);
442 :
443 : // Demand
444 0 : VISUM::OFormatDemand oDemand = VISUM::OFormatDemand::loadFromFile(benchmarkDir + "data/dynaminator-data/matrix.9.0.10.0.2.fma");
445 0 : Static::Demand::Loader<const VISUM::OFormatDemand &, const Static::SUMOAdapter &> demandLoader;
446 0 : Static::Demand demand = demandLoader.load(oDemand, loader.adapter);
447 :
448 0 : double totalDemand = demand.getTotalDemand();
449 0 : REQUIRE_THAT(totalDemand, WithinAbs(MATRIX_9_10_TOTAL_DEMAND, 1e-4));
450 :
451 0 : clk::time_point begin = clk::now();
452 :
453 0 : Static::DijkstraAoN aon;
454 0 : Static::SolutionBase x0 = aon.solve(*network, demand);
455 0 : REQUIRE_THAT(network->evaluate(x0), WithinRel(115488.4860793933, 0.1));
456 :
457 : // SECTION("FW") {
458 : // Opt::QuadraticSolver innerSolver;
459 : // Opt::QuadraticGuessSolver solver(
460 : // innerSolver,
461 : // 0.5,
462 : // 0.2,
463 : // 0.845,
464 : // 0.365
465 : // );
466 : // solver.setStopCriteria(0.01);
467 :
468 : // Static::FrankWolfe fw(aon, solver, loggerNull);
469 :
470 : // double epsilon = 1.0;
471 : // fw.setStopCriteria(epsilon);
472 : // fw.setIterations(3);
473 :
474 : // Static::IterativeEquilibration<Static::BPRNotConvexNetwork, Static::FrankWolfe> ie(fw, logger);
475 : // ie.setIterations(15);
476 :
477 : // Static::Solution x = ie.solve(*network, demand, x0);
478 :
479 : // clk::time_point end = clk::now();
480 : // cout << "Time difference = " << (double)chrono::duration_cast<chrono::nanoseconds>(end - begin).count() * 1e-9 << " [s]" << endl;
481 :
482 : // REQUIRE_THAT(x.getTotalFlow(), WithinAbs(totalDemand, 1e-4));
483 : // REQUIRE_THAT(network->evaluate(x), WithinRel(5381438.867287376, 0.005));
484 : // }
485 :
486 0 : SECTION("CFW") {
487 0 : Opt::QuadraticSolver innerSolver;
488 0 : Opt::QuadraticGuessSolver solver(
489 : innerSolver,
490 : 0.5,
491 : 0.2,
492 : 0.845,
493 : 0.365
494 0 : );
495 0 : solver.setStopCriteria(0.01);
496 :
497 0 : Static::ConjugateFrankWolfe fw(aon, solver, Log::ProgressLoggerIgnore::INSTANCE);
498 :
499 0 : fw.setStopCriteria(0.0);
500 0 : fw.setIterations(5);
501 :
502 0 : Static::IterativeEquilibration<Static::BPRNotConvexNetwork, Static::ConjugateFrankWolfe> ie(fw, logger);
503 0 : ie.setIterations(25);
504 :
505 0 : Static::Solution x = ie.solve(*network, demand, x0);
506 :
507 0 : clk::time_point end = clk::now();
508 0 : cout << "Time difference = " << (double)chrono::duration_cast<chrono::nanoseconds>(end - begin).count() * 1e-9 << " [s]" << endl;
509 :
510 0 : REQUIRE_THAT(x.getTotalFlow(), WithinAbs(totalDemand, 1e-4));
511 0 : REQUIRE_THAT(network->evaluate(x), WithinRel(13372.6692234558, 0.1));
512 :
513 : // clang-format off
514 0 : SUMO::EdgeData::Loader<
515 : const SUMO::NetworkTAZs &,
516 : const Static::BPRNetwork &,
517 : const Static::Solution &,
518 : const Static::SUMOAdapter &
519 : > edgeDataLoader;
520 : // clang-format on
521 0 : SUMO::EdgeData edgeData = edgeDataLoader.load(sumo, *network, x, loader.adapter);
522 0 : edgeData.saveToFile(baseDir + "data/out/edgedata-static.xml");
523 :
524 : // clang-format off
525 0 : SUMO::Routes::Loader<
526 : const Static::Network &,
527 : const Static::Solution &,
528 : const Static::SUMOAdapter &
529 : > routesLoader;
530 : // clang-format on
531 0 : SUMO::Routes routes = routesLoader.load(*network, x, loader.adapter);
532 0 : routes.saveToFile(baseDir + "data/out/routes-static.xml");
533 : }
534 :
535 0 : delete network;
536 0 : }
|