Skip to content

Commit

Permalink
active_hash related fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
senhalil committed Jul 13, 2021
1 parent fd46419 commit cdbcc3b
Show file tree
Hide file tree
Showing 16 changed files with 36 additions and 34 deletions.
20 changes: 9 additions & 11 deletions lib/heuristics/dichotomious_approach.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,15 @@ def self.dichotomious_heuristic(service_vrp, job = nil, &block)
if sub_service_vrp[:vrp].resolution_minimum_duration
sub_service_vrp[:vrp].resolution_minimum_duration *= sub_service_vrp[:vrp].services.size / service_vrp[:vrp].services.size.to_f * 2
end
matrix_indices = sub_service_vrp[:vrp].points.map{ |point|
service_vrp[:vrp].points.find{ |r_point| point.id == r_point.id }.matrix_index
}
SplitClustering.update_matrix_index(sub_service_vrp[:vrp])
SplitClustering.update_matrix(service_vrp[:vrp].matrices, sub_service_vrp[:vrp], matrix_indices)
result = OptimizerWrapper.define_process(sub_service_vrp, job, &block)
if index.zero? && result
transfer_unused_vehicles(result, sub_service_vrps)
matrix_indices = sub_service_vrps[1][:vrp].points.map{ |point|
service_vrp[:vrp].points.find{ |r_point| point.id == r_point.id }.matrix_index
}
SplitClustering.update_matrix_index(sub_service_vrps[1][:vrp])
SplitClustering.update_matrix(service_vrp[:vrp].matrices, sub_service_vrps[1][:vrp], matrix_indices)
end

transfer_unused_vehicles(result, sub_service_vrps) if index.zero? && result

result
}
service_vrp[:vrp].resolution_split_number = sub_service_vrps[1][:vrp].resolution_split_number
Expand Down Expand Up @@ -212,9 +212,7 @@ def self.build_initial_routes(results)
next if mission_ids.empty?

Models::Route.create(
vehicle: {
id: route[:vehicle_id]
},
vehicle_id: route[:vehicle_id],
mission_ids: mission_ids
)
}
Expand Down
2 changes: 1 addition & 1 deletion lib/heuristics/periodic_heuristic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1167,7 +1167,7 @@ def prepare_output_and_collect_routes(vrp)
computed_activities, start_time, end_time = get_activities(day, route_data, vrp, vrp_vehicle)

routes << {
vehicle: { id: vrp_vehicle.id },
vehicle_id: vrp_vehicle.id,
mission_ids: computed_activities.collect{ |stop| stop[:service_id] }.compact
}

Expand Down
13 changes: 7 additions & 6 deletions lib/tsp_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@
module TSPHelper
def self.create_tsp(vrp, vehicle)
services = []
tsp_suffix = Digest::MD5.hexdigest((vrp.points.map(&:id) + vrp.services.map(&:id) + vrp.vehicles.map(&:id)).join)
vrp.points.each{ |pt|
service = vrp.services.find{ |service_| service_.activity.point_id == pt.id }
next if !service

services << {
id: service[:id],
id: "#{tsp_suffix}_#{service[:id]}",
activity: {
point_id: service.activity.point_id,
point_id: "#{tsp_suffix}_#{service.activity.point_id}",
duration: service.activity.duration
}
}
Expand All @@ -36,19 +37,19 @@ def self.create_tsp(vrp, vehicle)
matrices: vrp.matrices,
points: vrp.points.collect{ |pt|
{
id: pt.id,
id: "#{tsp_suffix}_#{pt.id}",
matrix_index: pt.matrix_index
}
},
vehicles: [{
id: vehicle.id,
start_point_id: vehicle.start_point_id,
id: "#{tsp_suffix}_#{vehicle.id}",
start_point_id: "#{tsp_suffix}_#{vehicle.start_point_id}",
matrix_id: vehicle.matrix_id
}],
services: services
}

Models::Vrp.create(problem)
Models::Vrp.create(problem, false)
end

def self.solve(tsp)
Expand Down
1 change: 1 addition & 0 deletions optimizer_wrapper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ def self.define_main_process(services_vrps, job = nil, &block)
msg = "#{"repetition #{repetition_index + 1}/#{service_vrp_repeats.size} - " if service_vrp_repeats.size > 1}#{message}" unless message.nil?
callback_join&.call(wrapper, avancement, total, msg, cost, time, solution)
}
Models.delete_all # needed to prevent duplicate ids because expand_repeat uses Marshal.load/dump
}

(result, position) = repeated_results.each.with_index(1).min_by { |result, _| result[:unassigned].size } # find the best result and its index
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/instance_andalucia1_two_vehicles.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion test/fixtures/instance_andalucia2.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion test/fixtures/instance_baleares2.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion test/fixtures/instance_clustered.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion test/fixtures/instance_fr_g1g2.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion test/fixtures/instance_fr_hv11.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion test/fixtures/instance_fr_tv1.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion test/fixtures/instance_same_point_day.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion test/fixtures/no_dichotomious_when_no_location.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion test/lib/heuristics/periodic_functions_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,9 @@ def test_add_missing_visits
vrp = TestHelper.load_vrp(self, fixture_file: 'periodic_with_post_process')
vrp.vehicles = TestHelper.expand_vehicles(vrp)
s = Wrappers::PeriodicHeuristic.new(vrp)
s.instance_variable_set(:@candidate_routes, Marshal.load(File.binread('test/fixtures/add_missing_visits_candidate_routes.bindump'))) # rubocop: disable Security/MarshalLoad
add_missing_visits_candidate_routes = Marshal.load(File.binread('test/fixtures/add_missing_visits_candidate_routes.bindump')) # rubocop: disable Security/MarshalLoad
add_missing_visits_candidate_routes.each_value{ |vehicle| vehicle.each_value{ |route| route[:matrix_id] = vrp.vehicles.first.matrix_id } }
s.instance_variable_set(:@candidate_routes, add_missing_visits_candidate_routes)
s.instance_variable_set(:@uninserted, Marshal.load(File.binread('test/fixtures/add_missing_visits_uninserted.bindump'))) # rubocop: disable Security/MarshalLoad
services_data = Marshal.load(File.binread('test/fixtures/add_missing_visits_services_data.bindump')) # rubocop: disable Security/MarshalLoad
s.instance_variable_set(:@services_data, services_data)
Expand Down
10 changes: 5 additions & 5 deletions test/models/vrp_consistency_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ def test_point_id_not_defined
exception = assert_raises ActiveHash::RecordNotFound do
OptimizerWrapper.wrapper_vrp('demo', { services: { vrp: [:demo] }}, TestHelper.create(vrp), nil)
end
assert_equal('Couldn\'t find Models::Point with ID=missing_point_id', exception.message)
assert_equal("Couldn't find Models::Point with ID=#{vrp[:services][0][:activity][:point_id].inspect}", exception.message)
end

def test_reject_if_shipments_and_periodic_heuristic
Expand Down Expand Up @@ -336,7 +336,7 @@ def test_shipments_should_have_a_pickup_and_a_delivery
{ type: 'shipment', linked_ids: ['service_2'] },
{ type: 'shipment', linked_ids: ['service_1', 'service_3'] }]
error = assert_raises OptimizerWrapper::DiscordantProblemError do
Models::Vrp.create(TestHelper.coerce(vrp))
TestHelper.create(TestHelper.coerce(vrp))
end
assert_equal 'Shipment relations need to have two services -- a pickup and a delivery. ' \
'Relations of following services does not have exactly two linked_ids: ' \
Expand All @@ -350,12 +350,12 @@ def test_multi_pickup_or_multi_delivery_relations_are_accepted
# multi-pickup single delivery
vrp[:relations] = [{ type: 'shipment', linked_ids: ['service_1', 'service_3'] },
{ type: 'shipment', linked_ids: ['service_2', 'service_3'] }]
assert Models::Vrp.create(TestHelper.coerce(vrp)), 'Multi-pickup shipment should not be rejected'
assert TestHelper.create(TestHelper.coerce(vrp)), 'Multi-pickup shipment should not be rejected'

# single pickup multi-delivery
vrp[:relations] = [{ type: 'shipment', linked_ids: ['service_1', 'service_3'] },
{ type: 'shipment', linked_ids: ['service_1', 'service_2'] }]
assert Models::Vrp.create(TestHelper.coerce(vrp)), 'Multi-delivery shipment should not be rejected'
assert TestHelper.create(TestHelper.coerce(vrp)), 'Multi-delivery shipment should not be rejected'
end

def test_ensure_no_skill_matches_with_internal_skills_format
Expand All @@ -371,7 +371,7 @@ def test_reject_when_duplicated_ids
vrp = VRP.toy
vrp[:services] << vrp[:services].first

assert_raises OptimizerWrapper::DiscordantProblemError do
assert_raises ActiveHash::IdError do
OptimizerWrapper.wrapper_vrp('demo', { services: { vrp: [:demo] }}, TestHelper.create(vrp), nil)
end
end
Expand Down
2 changes: 1 addition & 1 deletion test/models/vrp_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ def test_original_skills_and_skills_are_equal_after_create
vrp[:vehicles].first[:skills] = [['skill_to_output']]
vrp[:services].first[:skills] = ['skill_to_output']

created_vrp = Models::Vrp.create(vrp)
created_vrp = TestHelper.create(vrp)
assert_equal 1, created_vrp.services.first.skills.size
assert_equal created_vrp.services.first.original_skills.size, created_vrp.services.first.skills.size
end
Expand Down

0 comments on commit cdbcc3b

Please sign in to comment.