Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use Models::X.create and not .new
Browse files Browse the repository at this point in the history
senhalil committed Aug 2, 2021
1 parent 6102e96 commit 1fae9cb
Showing 21 changed files with 100 additions and 82 deletions.
2 changes: 1 addition & 1 deletion lib/filters.rb
Original file line number Diff line number Diff line change
@@ -209,7 +209,7 @@ def self.merge_timewindows(vrp)
# latest_day_index = day_indices.include?(nil) ? nil : day_indices.max
earliest_start = starts.include?(nil) ? nil : starts.min
latest_end = ends.include?(nil) ? nil : ends.max
new_timewindows << Models::Timewindow.new(start: earliest_start, end: latest_end, day_index: earliest_day_index)
new_timewindows << Models::Timewindow.create(start: earliest_start, end: latest_end, day_index: earliest_day_index)
}
service.activity.timewindows = new_timewindows
}
2 changes: 1 addition & 1 deletion lib/heuristics/dichotomious_approach.rb
Original file line number Diff line number Diff line change
@@ -211,7 +211,7 @@ def self.build_initial_routes(results)
mission_ids = route[:activities].map{ |activity| activity[:service_id] }.compact
next if mission_ids.empty?

Models::Route.new(
Models::Route.create(
vehicle: {
id: route[:vehicle_id]
},
2 changes: 1 addition & 1 deletion lib/heuristics/periodic_heuristic.rb
Original file line number Diff line number Diff line change
@@ -1184,7 +1184,7 @@ def prepare_output_and_collect_routes(vrp)
unassigned = collect_unassigned
vrp[:preprocessing_heuristic_result] = {
cost: @cost,
cost_details: Models::CostDetails.new({}), # TODO: fulfill with solution costs
cost_details: Models::CostDetails.create({}), # TODO: fulfill with solution costs
solvers: ['heuristic'],
iterations: 0,
routes: solution,
2 changes: 1 addition & 1 deletion lib/interpreters/compute_several_solutions.rb
Original file line number Diff line number Diff line change
@@ -214,7 +214,7 @@ def self.find_best_heuristic(service_vrp)
}.compact
next if mission_ids.empty?

Models::Route.new(vehicle: vrp.vehicles.find{ |v| v[:id] == route[:vehicle_id] }, mission_ids: mission_ids)
Models::Route.create(vehicle: vrp.vehicles.find{ |v| v[:id] == route[:vehicle_id] }, mission_ids: mission_ids)
}.compact
end

6 changes: 3 additions & 3 deletions lib/interpreters/multi_modal.rb
Original file line number Diff line number Diff line change
@@ -145,7 +145,7 @@ def generate_subproblems(patterns)
sub_vrp.vehicles += (1..duplicate_vehicles).collect{ |index|
if vehicle_skills && !vehicle_skills.empty?
vehicle_skills.collect{ |alternative|
Models::Vehicle.new(
Models::Vehicle.create(
id: "subtour_#{alternative.join('-')}_#{transmodal_id}_#{index}",
router_mode: sub_tour.router_mode,
router_dimension: sub_tour.router_dimension,
@@ -158,7 +158,7 @@ def generate_subproblems(patterns)
)
}
else
Models::Vehicle.new(
Models::Vehicle.create(
id: "subtour_#{transmodal_id}_#{index}",
router_mode: sub_tour.router_mode,
router_dimension: sub_tour.router_dimension,
@@ -227,7 +227,7 @@ def override_original_vrp(subresults)
subresult[:routes].collect{ |route|
next unless route[:activities].size > 2

service = Models::Service.new(
service = Models::Service.create(
id: route[:vehicle_id],
activity: {
point: @original_vrp.points.find{ |point| point.id == route[:activities].first[:point_id] },
90 changes: 54 additions & 36 deletions lib/interpreters/periodic_visits.rb
Original file line number Diff line number Diff line change
@@ -41,7 +41,6 @@ def expand(vrp, job, &block)
return vrp unless vrp.schedule?

vehicles_linking_relations = save_vehicle_linking_relations(vrp)
vrp.relations = generate_relations(vrp)
vrp.rests = []
vrp.vehicles = generate_vehicles(vrp).sort{ |a, b|
(a.global_day_index && b.global_day_index && a.global_day_index != b.global_day_index) ? a.global_day_index <=> b.global_day_index : a.id <=> b.id
@@ -53,6 +52,7 @@ def expand(vrp, job, &block)
end

vrp.services = generate_services(vrp)
vrp.relations = generate_relations(vrp)

@periods.uniq!
generate_relations_on_periodic_vehicles(vrp, vehicles_linking_relations)
@@ -78,8 +78,8 @@ def generate_timewindows(timewindows_set)

if first_day
(first_day..@schedule_end).step(timewindow.day_index ? 7 : 1).collect{ |day_index|
Models::Timewindow.new(start: timewindow.start + day_index * 86400,
end: (timewindow.end || 86400) + day_index * 86400)
Models::Timewindow.create(start: timewindow.start + day_index * 86400,
end: (timewindow.end || 86400) + day_index * 86400)
}
end
else
@@ -89,21 +89,22 @@ def generate_timewindows(timewindows_set)
end

def generate_relations(vrp)
vrp.relations.collect{ |relation|
related_missions = relation.linked_services
vrp.relations.flat_map{ |relation|
unless relation.linked_ids.uniq{ |s_id| @expanded_services[s_id].size }.size <= 1
raise "Cannot expand relations of #{relation.linked_ids} because they have different visits_number"
end

visits_number = related_missions.first&.visits_number
next unless related_missions.any? && related_missions.all?{ |mission| mission.visits_number == visits_number }
# keep the original relation if it is another type of relation or if it doesn't belong to an unexpanded service.
next relation if relation.linked_services.empty? || @expanded_services[relation.linked_ids.first].empty?

(1..visits_number).collect{ |relation_index|
linked_ids = related_missions.collect{ |mission|
"#{mission.id}_#{relation_index}_#{mission.visits_number}"
}
new_relation = Models::Relation.create(type: relation.type, linked_ids: linked_ids,
lapse: relation.lapse, periodicity: relation.periodicity)
new_relation
Array.new(@expanded_services[relation.linked_ids.first].size){ |visit_index|
linked_ids = relation.linked_ids.collect{ |s_id| @expanded_services[s_id][visit_index].id }

Models::Relation.create(
type: relation.type, linked_ids: linked_ids, lapse: relation.lapse, periodicity: relation.periodicity
)
}
}.compact.flatten
}
end

def generate_relations_between_visits(vrp, mission)
@@ -113,34 +114,43 @@ def generate_relations_between_visits(vrp, mission)
if mission.minimum_lapse && mission.maximum_lapse
(2..mission.visits_number).each{ |index|
current_lapse = (index - 1) * mission.minimum_lapse.to_i
vrp.relations << Models::Relation.new(type: :minimum_day_lapse,
linked_ids: ["#{mission.id}_1_#{mission.visits_number}", "#{mission.id}_#{index}_#{mission.visits_number}"],
lapse: current_lapse)
vrp.relations << Models::Relation.create(
type: :minimum_day_lapse,
linked_ids: ["#{mission.id}_1_#{mission.visits_number}", "#{mission.id}_#{index}_#{mission.visits_number}"],
lapse: current_lapse
)
}
(2..mission.visits_number).each{ |index|
current_lapse = (index - 1) * mission.maximum_lapse.to_i
vrp.relations << Models::Relation.new(type: :maximum_day_lapse,
linked_ids: ["#{mission.id}_1_#{mission.visits_number}", "#{mission.id}_#{index}_#{mission.visits_number}"],
lapse: current_lapse)
vrp.relations << Models::Relation.create(
type: :maximum_day_lapse,
linked_ids: ["#{mission.id}_1_#{mission.visits_number}", "#{mission.id}_#{index}_#{mission.visits_number}"],
lapse: current_lapse
)
}
elsif mission.minimum_lapse
(2..mission.visits_number).each{ |index|
current_lapse = mission.minimum_lapse.to_i
vrp.relations << Models::Relation.new(type: :minimum_day_lapse,
linked_ids: ["#{mission.id}_#{index - 1}_#{mission.visits_number}", "#{mission.id}_#{index}_#{mission.visits_number}"],
lapse: current_lapse)
vrp.relations << Models::Relation.create(
type: :minimum_day_lapse,
linked_ids: ["#{mission.id}_#{index - 1}_#{mission.visits_number}", "#{mission.id}_#{index}_#{mission.visits_number}"],
lapse: current_lapse
)
}
elsif mission.maximum_lapse
(2..mission.visits_number).each{ |index|
current_lapse = mission.maximum_lapse.to_i
vrp.relations << Models::Relation.new(type: :maximum_day_lapse,
linked_ids: ["#{mission.id}_#{index - 1}_#{mission.visits_number}", "#{mission.id}_#{index}_#{mission.visits_number}"],
lapse: current_lapse)
vrp.relations << Models::Relation.create(
type: :maximum_day_lapse,
linked_ids: ["#{mission.id}_#{index - 1}_#{mission.visits_number}", "#{mission.id}_#{index}_#{mission.visits_number}"],
lapse: current_lapse
)
}
end
end

def generate_services(vrp)
@expanded_services = Hash.new{ |h, k| h[k] = [] }
vrp.services.collect{ |service|
# transform service data into periodic data
(service.activity ? [service.activity] : service.activities).each{ |activity|
@@ -149,10 +159,9 @@ def generate_services(vrp)

# generate one service per visit
# TODO : create visit in model
generate_relations_between_visits(vrp, service)
@periods << service.visits_number

(0..service.visits_number - 1).collect{ |visit_index|
visits = (0..service.visits_number - 1).collect{ |visit_index|
next if service.unavailable_visit_indices.include?(visit_index)

new_service = duplicate_safe(
@@ -164,8 +173,14 @@ def generate_services(vrp)
)
new_service.skills += ["#{visit_index + 1}_f_#{service.visits_number}"] if !service.minimum_lapse && !service.maximum_lapse && service.visits_number > 1

@expanded_services[service.id] << new_service

new_service
}.compact

generate_relations_between_visits(vrp, service)

visits
}.flatten
end

@@ -201,7 +216,7 @@ def generate_vehicles(vrp)
else
timewindows.select{ |timewindow| timewindow.day_index.nil? || timewindow.day_index == vehicle_day_index % 7 }.collect{ |associated_timewindow|
new_vehicle = build_vehicle(vrp, vehicle, vehicle_day_index, rests_durations)
new_vehicle.timewindow = Models::Timewindow.new(start: associated_timewindow.start || 0, end: associated_timewindow.end || 86400)
new_vehicle.timewindow = Models::Timewindow.create(start: associated_timewindow.start || 0, end: associated_timewindow.end || 86400)
if @have_day_index
new_vehicle.timewindow.start += vehicle_day_index * 86400
new_vehicle.timewindow.end += vehicle_day_index * 86400
@@ -212,7 +227,7 @@ def generate_vehicles(vrp)
}.compact

if vehicle.overall_duration
new_relation = Models::Relation.new(
new_relation = Models::Relation.create(
type: :vehicle_group_duration,
linked_vehicle_ids: @equivalent_vehicles[vehicle.original_id],
lapse: vehicle.overall_duration + rests_durations[index]
@@ -405,10 +420,11 @@ def compute_possible_days(vrp)
end

def save_vehicle_linking_relations(vrp)
vrp.relations.select{ |r|
vehicle_linking_relations, vrp.relations = vrp.relations.partition{ |r|
[:vehicle_group_duration, :vehicle_group_duration_on_weeks, :vehicle_group_duration_on_months,
:vehicle_trips].include?(r.type)
}
vehicle_linking_relations
end

def cut_linking_vehicle_relation_by_period(relation, periods, relation_type)
@@ -421,7 +437,7 @@ def cut_linking_vehicle_relation_by_period(relation, periods, relation_type)
relation_vehicles = vehicles_in_relation.select{ |id| days_in_period.include?(id.split('_').last.to_i) }
next unless relation_vehicles.any?

additional_relations << Models::Relation.new(
additional_relations << Models::Relation.create(
linked_vehicle_ids: relation_vehicles,
lapse: relation.lapse,
type: relation_type
@@ -447,9 +463,11 @@ def generate_relations_on_periodic_vehicles(vrp, vehicle_linking_relations)
vrp.relations.concat(vehicle_linking_relations.flat_map{ |relation|
case relation[:type]
when :vehicle_group_duration
Models::Relation.new(
type: :vehicle_group_duration, lapse: relation.lapse,
linked_vehicle_ids: relation[:linked_vehicle_ids].flat_map{ |v| @equivalent_vehicles[v] })
Models::Relation.create(
type: :vehicle_group_duration,
linked_vehicle_ids: relation[:linked_vehicle_ids].flat_map{ |v| @equivalent_vehicles[v] },
lapse: relation.lapse
)
when :vehicle_group_duration_on_weeks
schedule_week_indices = collect_weeks_in_schedule
cut_linking_vehicle_relation_by_period(relation, schedule_week_indices, :vehicle_group_duration)
2 changes: 1 addition & 1 deletion lib/interpreters/split_clustering.rb
Original file line number Diff line number Diff line change
@@ -874,7 +874,7 @@ def self.duplicate_vehicle(vehicle, timewindow, schedule)
available_days.collect{ |day|
next unless (schedule[:start]..schedule[:end]).any?{ |day_index| day_index % 7 == day }

tw = timewindow ? Marshal.load(Marshal.dump(timewindow)) : Models::Timewindow.new({})
tw = timewindow ? Marshal.load(Marshal.dump(timewindow)) : Models::Timewindow.create({})
tw.day_index = day
provide_work_day_skill(vehicle, day)
new_vehicle = Marshal.load(Marshal.dump(vehicle))
2 changes: 1 addition & 1 deletion models/solution/cost_details.rb
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ class CostDetails < Base
field :overload, default: 0

def +(other)
merged_cost = CostDetails.new({})
merged_cost = CostDetails.create({})
self.attributes.each_key{ |key|
merged_cost[key] = (self[key] || 0) + (other[key] || 0)
}
2 changes: 1 addition & 1 deletion optimizer_wrapper.rb
Original file line number Diff line number Diff line change
@@ -703,7 +703,7 @@ def self.empty_route(vrp, vehicle)
{
vehicle_id: vehicle.id,
original_vehicle_id: vehicle.original_id,
cost_details: Models::CostDetails.new({}),
cost_details: Models::CostDetails.create({}),
activities: [], # TODO: check if depot activities are needed
# or-tools returns depot_start -> depot_end for empty vehicles
# in that case route_end_time needs to be corrected
2 changes: 1 addition & 1 deletion test/lib/heuristics/periodic_functions_test.rb
Original file line number Diff line number Diff line change
@@ -524,7 +524,7 @@ def test_compute_latest_authorized_day

if visits_number == 10
vrp.vehicles.first.sequence_timewindows = (0..4).collect{ |day_index|
Models::Timewindow.new(start: 0, end: 20, day_index: day_index)
Models::Timewindow.create(start: 0, end: 20, day_index: day_index)
}
vrp.vehicles.first.timewindow = nil
end
4 changes: 2 additions & 2 deletions test/lib/heuristics/periodic_test.rb
Original file line number Diff line number Diff line change
@@ -514,8 +514,8 @@ def test_fix_unfeasible_initial_solution
vrp = TestHelper.load_vrp(self, fixture_file: 'instance_baleares2')
vrp.routes = [Models::Route.create(vehicle: vrp.vehicles.first, mission_ids: %w[5482 0833 8595 0352 0799 2047 5446 0726 0708], day_index: 0)]

vrp.services.find{ |s| s[:id] == vrp.routes.first.mission_ids[0] }[:activity][:timewindows] = [Models::Timewindow.new(start: 43500, end: 55500)]
vrp.services.find{ |s| s[:id] == vrp.routes.first.mission_ids[1] }[:activity][:timewindows] = [Models::Timewindow.new(start: 31500, end: 43500)]
vrp.services.find{ |s| s[:id] == vrp.routes.first.mission_ids[0] }[:activity][:timewindows] = [Models::Timewindow.create(start: 43500, end: 55500)]
vrp.services.find{ |s| s[:id] == vrp.routes.first.mission_ids[1] }[:activity][:timewindows] = [Models::Timewindow.create(start: 31500, end: 43500)]

vrp.vehicles = TestHelper.expand_vehicles(vrp)
periodic = Wrappers::PeriodicHeuristic.new(vrp)
2 changes: 1 addition & 1 deletion test/lib/interpreters/interpreter_test.rb
Original file line number Diff line number Diff line change
@@ -451,7 +451,7 @@ def test_minimum_lapse_3_visits
}
}],
services: [{
id: 'point_1',
id: 'service_1',
priority: 2,
visits_number: 3,
minimum_lapse: 10,
22 changes: 11 additions & 11 deletions test/lib/interpreters/split_clustering_test.rb
Original file line number Diff line number Diff line change
@@ -35,14 +35,14 @@ def test_same_location_different_clusters
service_vrp[:vrp].vehicles.each{ |v|
v.capacities = []
service_vrp[:vrp].units.each{ |u|
v.capacities << Models::Capacity.new(unit: u, limit: total[u.id] * 0.65)
v.capacities << Models::Capacity.create(unit: u, limit: total[u.id] * 0.65)
}
}

# entity: `vehicle` setting only works if the number of clusters is equal to the number of vehicles.
original = service_vrp[:vrp].vehicles.first
service_vrp[:vrp].vehicles = [original]
service_vrp[:vrp].vehicles << Models::Vehicle.new(
service_vrp[:vrp].vehicles << Models::Vehicle.create(
id: "#{original.id}_copy",
duration: original.duration,
matrix_id: original.matrix_id,
@@ -910,7 +910,7 @@ def test_clustering_with_sticky_vehicles
def test_list_vehicles
# with timewindow
vrp = TestHelper.create(VRP.basic)
vrp.vehicles.first.timewindow = Models::Timewindow.new(start: 0, end: 10)
vrp.vehicles.first.timewindow = Models::Timewindow.create(start: 0, end: 10)
# one vehicle with no day index : we should generate one vehicle per week_day :
assert_equal 7, Interpreters::SplitClustering.list_vehicles({ start: 0, end: 6 }, vrp.vehicles, :work_day).size
assert_equal 7, Interpreters::SplitClustering.list_vehicles({ start: 0, end: 10 }, vrp.vehicles, :work_day).size
@@ -925,8 +925,8 @@ def test_list_vehicles
# with sequence_timewindows
vrp = TestHelper.create(VRP.basic)
vrp.vehicles.first.sequence_timewindows = [
Models::Timewindow.new(start: 0, end: 10),
Models::Timewindow.new(start: 15, end: 35)
Models::Timewindow.create(start: 0, end: 10),
Models::Timewindow.create(start: 15, end: 35)
]
# we generate one cluster per week day, for each vehicle sequence timewindow
assert_equal 14, Interpreters::SplitClustering.list_vehicles({ start: 0, end: 6 }, vrp.vehicles, :work_day).size
@@ -935,21 +935,21 @@ def test_list_vehicles
assert_equal 8, Interpreters::SplitClustering.list_vehicles({ start: 0, end: 3 }, vrp.vehicles, :work_day).size

vrp.vehicles.first.sequence_timewindows = [
Models::Timewindow.new(start: 0, end: 10, day_index: 0),
Models::Timewindow.new(start: 15, end: 35, day_index: 1)
Models::Timewindow.create(start: 0, end: 10, day_index: 0),
Models::Timewindow.create(start: 15, end: 35, day_index: 1)
]
assert_equal 2, Interpreters::SplitClustering.list_vehicles({ start: 0, end: 6 }, vrp.vehicles, :work_day).size
assert_equal 1, Interpreters::SplitClustering.list_vehicles({ start: 1, end: 6 }, vrp.vehicles, :work_day).size

vrp.vehicles.first.sequence_timewindows = [
Models::Timewindow.new(start: 0, end: 10, day_index: 0),
Models::Timewindow.new(start: 15, end: 35)
Models::Timewindow.create(start: 0, end: 10, day_index: 0),
Models::Timewindow.create(start: 15, end: 35)
]
assert_equal 8, Interpreters::SplitClustering.list_vehicles({ start: 0, end: 6 }, vrp.vehicles, :work_day).size

vrp.vehicles.first.sequence_timewindows = [
Models::Timewindow.new(start: 0, end: 10, day_index: 0),
Models::Timewindow.new(start: 15, end: 35, day_index: 0)
Models::Timewindow.create(start: 0, end: 10, day_index: 0),
Models::Timewindow.create(start: 15, end: 35, day_index: 0)
]
assert_equal 2, Interpreters::SplitClustering.list_vehicles({ start: 0, end: 7 }, vrp.vehicles, :work_day).size

4 changes: 2 additions & 2 deletions test/models/vehicle_test.rb
Original file line number Diff line number Diff line change
@@ -65,11 +65,11 @@ def test_total_work_time_in_range
assert_equal 2**32, vrp.vehicles.first.total_work_time_in_range(0, 3)

vrp.vehicles.first.reset_computed_data
vrp.vehicles.first.sequence_timewindows = [Models::Timewindow.new({ start: 1, end: 4 })]
vrp.vehicles.first.sequence_timewindows = [Models::Timewindow.create({ start: 1, end: 4 })]
assert_equal 12, vrp.vehicles.first.total_work_time_in_range(0, 3)

vrp.vehicles.first.reset_computed_data
vrp.vehicles.first.sequence_timewindows << Models::Timewindow.new({ start: 5, end: 6, day_index: 0 })
vrp.vehicles.first.sequence_timewindows << Models::Timewindow.create({ start: 5, end: 6, day_index: 0 })
assert_equal 13, vrp.vehicles.first.total_work_time_in_range(0, 3)
end
end
2 changes: 1 addition & 1 deletion test/models/vrp_consistency_test.rb
Original file line number Diff line number Diff line change
@@ -567,7 +567,7 @@ def test_pickup_timewindow_after_delivery_timewindow
assert_raises OptimizerWrapper::DiscordantProblemError do
OptimizerWrapper.wrapper_vrp('demo', { services: { vrp: [:demo] }}, TestHelper.create(problem.dup), nil)
end
problem[:shipments].first[:delivery][:timewindows] = [Models::Timewindow.new(start: 1, end: 9)]
problem[:shipments].first[:delivery][:timewindows] = [Models::Timewindow.create(start: 1, end: 9)]

OptimizerWrapper.wrapper_vrp('demo', { services: { vrp: [:demo] }}, TestHelper.create(problem), nil)
end
16 changes: 8 additions & 8 deletions test/wrapper_test.rb
Original file line number Diff line number Diff line change
@@ -2860,17 +2860,17 @@ def test_number_of_service_vrps_generated_in_split_independent
# add services that can not be served by any vehicle (different configurations)
vrp = TestHelper.create(VRP.independent_skills)
vrp.matrices = nil
vrp.services << Models::Service.new(id: 'fake_service_1', skills: ['fake_skill1'], activity: { point: vrp.points.first })
vrp.services << Models::Service.new(id: 'fake_service_2', skills: ['fake_skill1'], activity: { point: vrp.points.first })
vrp.services << Models::Service.create(id: 'fake_service_1', skills: ['fake_skill1'], activity: { point: vrp.points.first })
vrp.services << Models::Service.create(id: 'fake_service_2', skills: ['fake_skill1'], activity: { point: vrp.points.first })
services_vrps = OptimizerWrapper.split_independent_vrp_by_skills(vrp)
assert_equal 6, services_vrps.size, 'Split_independent_vrp_by_skills function does not generate expected number of services_vrps'
assert_equal vrp.resolution_duration, services_vrps.sum(&:resolution_duration)
assert_equal 3, (services_vrps.count{ |s| s.resolution_duration.zero? })

vrp = TestHelper.create(VRP.independent_skills)
vrp.matrices = nil
vrp.services << Models::Service.new(id: 'fake_service_1', skills: ['fake_skill1'], activity: { point: vrp.points.first })
vrp.services << Models::Service.new(id: 'fake_service_3', skills: ['fake_skill2'], activity: { point: vrp.points.first })
vrp.services << Models::Service.create(id: 'fake_service_1', skills: ['fake_skill1'], activity: { point: vrp.points.first })
vrp.services << Models::Service.create(id: 'fake_service_3', skills: ['fake_skill2'], activity: { point: vrp.points.first })
services_vrps = OptimizerWrapper.split_independent_vrp_by_skills(vrp)
assert_equal 7, services_vrps.size, 'Split_independent_vrp_by_skills function does not generate expected number of services_vrps'
assert_equal vrp.resolution_duration, services_vrps.sum(&:resolution_duration)
@@ -2879,14 +2879,14 @@ def test_number_of_service_vrps_generated_in_split_independent

def test_split_independent_vrps_with_useless_vehicle
vrp = TestHelper.create(VRP.independent_skills)
vrp.vehicles << Models::Vehicle.new(id: 'useless_vehicle')
vrp.vehicles << Models::Vehicle.create(id: 'useless_vehicle')
result = OptimizerWrapper.wrapper_vrp('ortools', { services: { vrp: [:ortools] }}, vrp, nil)
assert_equal vrp.vehicles.size, result[:routes].size, 'All vehicles should appear in result, even though they can serve no service'
end

def test_split_independent_vrp_by_sticky_vehicle_with_useless_vehicle
vrp = TestHelper.create(VRP.independent)
vrp.vehicles << Models::Vehicle.new(id: 'useless_vehicle')
vrp.vehicles << Models::Vehicle.create(id: 'useless_vehicle')
expected_number_of_vehicles = vrp.vehicles.size
services_vrps = OptimizerWrapper.split_independent_vrp_by_sticky_vehicle(vrp)
assert_equal expected_number_of_vehicles, services_vrps.collect{ |sub_vrp| sub_vrp.vehicles.size }.sum, 'some vehicles disapear because of split_independent_vrp_by_sticky_vehicle function'
@@ -3006,8 +3006,8 @@ def test_assert_inapplicable_relations

problem[:relations] = [{
type: :vehicle_group_duration,
linked_ids: ['vehicle_0'],
linked_vehicle_ids: [],
linked_ids: [],
linked_vehicle_ids: ['vehicle_0'],
lapse: 1
}]

12 changes: 6 additions & 6 deletions test/wrappers/ortools_test.rb
Original file line number Diff line number Diff line change
@@ -4900,7 +4900,7 @@ def test_subproblem_with_one_vehicle_and_no_possible_service
end

def test_build_rest
rest = Models::Rest.new(duration: 1)
rest = Models::Rest.create(duration: 1)
assert OptimizerWrapper.config[:services][:ortools].send(:build_rest, rest)
end

@@ -4981,11 +4981,11 @@ def test_minimum_duration_lapse_shipments
pickup0 = vrp.services.find{ |service| service.id == "#{ordered_pickup_ids[0]}_pickup" }

# add consecutivity :
relation = Models::Relation.new(type: :minimum_duration_lapse,
linked_services: [delivery1, pickup0],
linked_ids: [delivery1.id, pickup0.id],
lapse: 1800)
vrp.relations << relation
vrp.relations << Models::Relation.create(
type: :minimum_duration_lapse,
linked_ids: [delivery1.id, pickup0.id],
lapse: 1800
)
result = OptimizerWrapper.wrapper_vrp('demo', { services: { vrp: [:ortools] }}, vrp, nil)
shipment1_route = result[:routes].find{ |r|
r[:activities].any?{ |stop| stop[:pickup_shipment_id] == delivery1.original_id }
2 changes: 1 addition & 1 deletion wrappers/demo.rb
Original file line number Diff line number Diff line change
@@ -65,7 +65,7 @@ def build_route_depot(point)
def solve(vrp, _job = nil, _thread_proc = nil, &_block)
{
cost: 0,
cost_details: Models::CostDetails.new({}),
cost_details: Models::CostDetails.create({}),
solvers: [:demo],
total_travel_distance: 0,
total_travel_time: 0,
2 changes: 1 addition & 1 deletion wrappers/ortools.rb
Original file line number Diff line number Diff line change
@@ -385,7 +385,7 @@ def kill
private

def build_cost_details(cost_details)
cost = Models::CostDetails.new(
cost = Models::CostDetails.create(
fixed: cost_details&.fixed || 0,
time: cost_details && (cost_details.time + cost_details.time_fake + cost_details.time_without_wait) || 0,
distance: cost_details && (cost_details.distance + cost_details.distance_fake) || 0,
2 changes: 1 addition & 1 deletion wrappers/vroom.rb
Original file line number Diff line number Diff line change
@@ -115,7 +115,7 @@ def solve(vrp, job = nil, _thread_proc = nil)

result = {
cost: cost,
cost_details: Models::CostDetails.new({}), # TODO: fulfill with solution costs
cost_details: Models::CostDetails.create({}), # TODO: fulfill with solution costs
solvers: ['vroom'],
elapsed: elapsed_time, # ms
# total_travel_distance: 0,
2 changes: 1 addition & 1 deletion wrappers/wrapper.rb
Original file line number Diff line number Diff line change
@@ -1249,7 +1249,7 @@ def empty_result(solver, vrp, unassigned_reason = nil, already_expanded = true)
OptimizerWrapper.parse_result(vrp, {
solvers: [solver],
cost: nil,
cost_details: Models::CostDetails.new({}),
cost_details: Models::CostDetails.create({}),
iterations: nil,
routes: vrp.vehicles.collect{ |vehicle|
OptimizerWrapper.empty_route(vrp, vehicle)

0 comments on commit 1fae9cb

Please sign in to comment.