-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathoptimizer_wrapper.rb
More file actions
93 lines (86 loc) · 3.3 KB
/
optimizer_wrapper.rb
File metadata and controls
93 lines (86 loc) · 3.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
# Copyright © Mapotempo, 2016
#
# This file is part of Mapotempo.
#
# Mapotempo is free software. You can redistribute it and/or
# modify since you respect the terms of the GNU Affero General
# Public License as published by the Free Software Foundation,
# either version 3 of the License, or (at your option) any later version.
#
# Mapotempo 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 Licenses for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Mapotempo. If not, see:
# <http://www.gnu.org/licenses/agpl.html>
#
# frozen_string_literal: true
require_all 'lib'
require_all 'util'
require_all 'core'
module OptimizerWrapper
extend Core::Services::ClusteringService
extend Core::Services::JobService
extend Core::Strategies::Orchestration
extend Core::Components::Solution
extend Core::Components::Vehicle
extend Core::Components::Vrp
extend Core::Components::Zone
def self.wrapper_vrp(api_key, profile, vrp, checksum, job_id = nil)
inapplicable_services = []
apply_zones(vrp)
adjust_vehicles_duration(vrp)
Filters.filter(vrp)
vrp.configuration.resolution.repetition ||=
if !vrp.configuration.preprocessing.partitions.empty? && vrp.periodic_heuristic?
config[:solve][:repetition]
else
1
end
solver_priority = filtered_solver_priority(vrp, profile)
services_vrps =
split_independent_vrp(vrp).map{ |vrp_element|
resolution_context = Models::ResolutionContext.new(vrp: vrp_element, job_id: job_id)
solver_priority.find{ |s|
inapplicable = config[:services][s].inapplicable_solve?(vrp_element)
if inapplicable.empty?
log "Select service #{s}"
resolution_context.service = s
true
else
resolution_context.skipped_services << Models::SkippedService.new(service: s, reasons: inapplicable)
inapplicable_services << inapplicable
log "Skip inapplicable #{s}: #{inapplicable.join(', ')}"
false
end
}
resolution_context
}
if services_vrps.any?{ |sv| !sv.service }
{
solvers: [],
skipped_services: services_vrps.map(&:skipped_services).flatten
}
elsif config[:solve][:synchronously] || (
services_vrps.size == 1 &&
!vrp.configuration.preprocessing.cluster_threshold &&
config[:services][services_vrps[0].service].solve_synchronous?(vrp)
)
# The job seems easy enough to perform it with the server
define_main_process(services_vrps, job_id)
else
# Delegate the job to a worker (expire is defined resque config)
job_id = Job.enqueue_to(profile[:queue], Job, services_vrps: Base64.encode64(Marshal.dump(services_vrps)),
api_key: api_key,
checksum: checksum,
pids: [])
JobList.add(api_key, job_id)
{
job_id: job_id,
solvers: services_vrps.map(&:service),
skipped_services: services_vrps.map(&:skipped_services).flatten
}
end
end
end