-
-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathoptimize.sql
More file actions
160 lines (125 loc) · 4.3 KB
/
optimize.sql
File metadata and controls
160 lines (125 loc) · 4.3 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
/*PGR-GNU*****************************************************************
File: optimize.sql
Copyright (c) 2021 pgRouting developers
Mail: project@pgrouting.org
Function's developer:
Copyright (c) 2021 Celia Virginia Vergara Castillo
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*/
CREATE OR REPLACE PROCEDURE vrp_optimize(
TEXT, -- orders sql (required)
TEXT, -- vehicles sql (required)
TEXT, -- time matrix sql (required)
TEXT, -- time dependencies SQL
vehicles_tbl REGCLASS, -- vehicles table to update
execution_date TIMESTAMP,
factor FLOAT,
max_cycles INTEGER
)
AS
$BODY$
DECLARE
curr_time RECORD;
curr_vehicles BIGINT[];
prev_vehicles BIGINT[];
ok_orders BIGINT [];
orders_sql TEXT;
vehicles_sql TEXT;
BEGIN
DROP TABLE IF EXISTS __results;
/** cycle to extract the times where the vehicle opens or ends **/
FOR curr_time IN EXECUTE format($$
SELECT s_tw_open AS start_time
FROM (%1$s) a
WHERE date_trunc('day', %2$L::TIMESTAMP) <= s_tw_open
UNION
SELECT e_tw_close
FROM (%1$s) b
WHERE date_trunc('day', %2$L::TIMESTAMP) <= s_tw_open
ORDER BY start_time $$,
$2, execution_date)
LOOP
IF (curr_time.start_time < date_trunc('day', execution_date)) THEN
RAISE EXCEPTION 'NOT OPTIMIZING % Belongs to the past, should never appear because the cycle does not allow to optimize on the past', curr_time;
CONTINUE;
END IF;
SELECT array_agg(id) FROM _vrp_vehiclesAtTime($2, curr_time.start_time, dryrun => false) INTO curr_vehicles;
IF prev_vehicles = curr_vehicles THEN
RAISE DEBUG 'NOT OPTIMIZING % vehicles % set of vehicles did not change', curr_time, curr_vehicles;
CONTINUE;
END IF;
SELECT cmd FROM _vrp_vehiclesAtTime($2, curr_time.start_time, dryrun => true) LIMIT 1 INTO vehicles_sql;
EXECUTE format($$
WITH
v AS (%1$s),
orders_q AS (
SELECT unnest(stops) AS orders_id FROM v
)
SELECT array_agg(DISTINCT orders_id)
FROM orders_q WHERE orders_id IS NOT NULL
$$,
vehicles_sql)
INTO ok_orders;
orders_sql = format($$
SELECT *
FROM (%1$s) a
WHERE id ::BIGINT IN (SELECT unnest('%2$s'::BIGINT[]))
$$,
$1, ok_orders);
IF ok_orders IS NULL THEN
RAISE WARNING 'NOT OPTIMIZING % No orders found %', curr_time, curr_vehicles;
CONTINUE;
END IF;
RAISE NOTICE 'OPTIMIZING time:% vehicles %', curr_time, curr_vehicles;
BEGIN
CREATE TEMP TABLE __results ON COMMIT DROP AS
SELECT *
FROM vrp_pickDeliver(
orders_sql,
vehicles_sql,
$3,
$4,
execution_date,
optimize => true,
factor => factor,
max_cycles => max_cycles,
stop_on_all_served => false);
EXCEPTION WHEN OTHERS THEN
RAISE WARNING 'COULD NOT OPTIMIZE %', curr_time;
RAISE WARNING 'SQLERRM %', SQLERRM;
CONTINUE;
END;
EXECUTE format($$
WITH
new_stops AS (
SELECT vehicle_id AS id, array_remove(array_agg(shipment_id ORDER BY seq)::BIGINT[],-1::BIGINT) AS stops
FROM __results
GROUP BY vehicle_id
)
UPDATE %1$I AS v
SET stops = n.stops
FROM new_stops AS n WHERE v.id = n.id
$$, vehicles_tbl);
COMMIT;
prev_vehicles := curr_vehicles;
END LOOP;
END;
$BODY$
LANGUAGE plpgsql;
COMMENT ON PROCEDURE vrp_optimize(TEXT, TEXT, TEXT, TEXT, REGCLASS, TIMESTAMP, FLOAT, INTEGER)
IS 'vrp_optimize
- Documentation:
- ${PROJECT_DOC_LINK}/vrp_optimize.html
';