Skip to content

Commit

Permalink
Init Solution Models
Browse files Browse the repository at this point in the history
  • Loading branch information
Braktar committed Jun 17, 2021
1 parent a17301b commit 9f13ae1
Show file tree
Hide file tree
Showing 11 changed files with 247 additions and 78 deletions.
2 changes: 1 addition & 1 deletion models/rest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
require './models/concerns/validate_timewindows'

module Models
class Rest < Base
class Rest < Activity
field :duration, default: 0
field :late_multiplier, default: 0
field :exclusion_cost, default: nil
Expand Down
9 changes: 9 additions & 0 deletions models/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,14 @@ class Service < Base
has_many :sticky_vehicles, class_name: 'Models::Vehicle'
has_many :quantities, class_name: 'Models::Quantity'
has_many :relations, class_name: 'Models::Relation'

def route_activity(index)
Models::RouteActivity.new(
service_id: self.original_id || self.id,
type: self.type,
alternative: index,
details: index && self.activities[index] || self.activity
)
end
end
end
36 changes: 36 additions & 0 deletions models/solution/activity.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright © Mapotempo, 2021
#
# 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>
#
require './models/base'

module Models
class RouteActivity < Base
# field :point_id
field :type
field :alternative
field :reason, default: nil
# TODO: The following fields should be merged in v2
field :service_id
field :pickup_shipment_id
field :delivery_shipment_id
field :rest_id

belongs_to :load, class_name: 'Models::Load'
belongs_to :details, class_name: 'Models::Activity'
belongs_to :timings, class_name: 'Models::Timings'
end
end
28 changes: 14 additions & 14 deletions models/solution/cost_details.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@

module Models
class CostDetails < Base
field :total, default: 0
field :fixed, default: 0
field :time, default: 0
field :distance, default: 0
field :value, default: 0
field :lateness, default: 0
field :overload, default: 0
field :total, default: 0
field :fixed, default: 0
field :time, default: 0
field :distance, default: 0
field :value, default: 0
field :lateness, default: 0
field :overload, default: 0

def +(other)
merged_cost = CostDetails.new({})
self.attributes.each_key{ |key|
merged_cost[key] = (self[key] || 0) + (other[key] || 0)
}
merged_cost
end
def +(other)
merged_cost = CostDetails.new({})
self.attributes.each_key{ |key|
merged_cost[key] = (self[key] || 0) + (other[key] || 0)
}
merged_cost
end
end
end
26 changes: 26 additions & 0 deletions models/solution/load.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright © Mapotempo, 2021
#
# 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>
#
require './models/base'

module Models
class Load < Base
field :current_load

belongs_to :quantity, class_name: 'Models::Quantity'
end
end
31 changes: 31 additions & 0 deletions models/solution/route.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright © Mapotempo, 2021
#
# 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>
#
require './models/base'

module Models
class SolutionRoute < Base
field :geometry

has_many :activities, class_name: 'Models::RouteActivity'
has_many :initial_loads, class_name: 'Models::Load'

belongs_to :cost_details, class_name: 'Models::CostDetails'
belongs_to :details, class_name: 'Models::RouteDetails'
belongs_to :vehicle, class_name: 'Models::Vehicle'
end
end
31 changes: 31 additions & 0 deletions models/solution/route_details.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright © Mapotempo, 2021
#
# 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>
#
require './models/base'

module Models
class RouteDetails < Base
field :total_time
field :total_travel_time
field :total_waiting_time

field :total_distance

field :start_time
field :end_time
end
end
34 changes: 34 additions & 0 deletions models/solution/solution.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright © Mapotempo, 2021
#
# 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>
#
require './models/base'

module Models
class Solution < Base
field :cost, default: 0
field :elapsed, default: 0
field :heuristic_synthesis, default: {}
field :iterations
field :solvers, default: []

has_many :routes, class_name: 'Models::SolutionRoute'
has_many :unassigned, class_name: 'Models::RouteActivity'

belongs_to :costs, class_name: 'Models::CostDetails'
belongs_to :details, class_name: 'Models::RouteDetails'
end
end
36 changes: 36 additions & 0 deletions models/solution/timings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright © Mapotempo, 2021
#
# 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>
#
require './models/base'

module Models
class Timings < Base
field :day_week_num
field :day_week

field :travel_distance, default: 0
field :travel_time, default: 0
field :travel_value, default: 0

field :waiting_time, default: 0
field :begin_time, default: 0
field :end_time, default: 0
field :departure_time, default: 0

field :current_distance, default: 0
end
end
16 changes: 16 additions & 0 deletions models/vehicle.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,22 @@ def self.create(hash)
super(hash)
end

def start_depot_activity
Models::RouteActivity.new(
service_id: self.start_point&.id,
type: :depot,
details: Models::Activity.new(point: self.start_point)
)
end

def end_depot_activity
Models::RouteActivity.new(
service_id: self.end_point&.id,
type: :depot,
details: Models::Activity.new(point: self.end_point)
)
end

def need_matrix_time?
cost_time_multiplier.positive? || timewindow&.end || cost_late_multiplier&.positive? ||
cost_setup_time_multiplier.positive? || !rests.empty? || maximum_ride_time || duration || overall_duration
Expand Down
76 changes: 13 additions & 63 deletions wrappers/demo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,72 +23,22 @@ def initialize(hash = {})
super(hash)
end

def build_route_activity(mission, type, activity)
timewindows = []
if activity.timewindows && !activity.timewindows.empty?
timewindows = [{
start: timewindows&.first&.start,
end: timewindows&.first&.end,
}]
end
{
point_id: activity.point.id,
travel_time: 0,
travel_distance: 0,
travel_start_time: 0,
waiting_time: 0,
arrival_time: 0,
departure_time: 0,
type: type,
begin_time: 0,
end_time: 0,
detail: build_detail(mission, activity, activity.point, nil, nil, nil)
def solve(vrp, _job = nil, _thread_proc = nil, &_block)
routes = vrp.vehicles.map{ |vehicle|
activities = [vehicle.start_depot_activity] +
vrp.services.map{ |service|
service.route_activity(service.activities.any? && 0)
} + [vehicle.end_depot_activity]
Models::SolutionRoute.new(
vehicle: vehicle,
activities: activities.compact
)
}
end

def build_route_depot(point)
point && {
point_id: point.id,
travel_time: 0,
travel_distance: 0,
travel_start_time: 0,
type: 'depot',
begin_time: 0,
end_time: 0,
detail: {
lat: point.location&.lat,
lon: point.location&.lon,
}
}
end

def solve(vrp, _job = nil, _thread_proc = nil, &_block)
{
cost: 0,
cost_details: Models::CostDetails.new({}),
Models::Solution.new(
solvers: [:demo],
total_travel_distance: 0,
total_travel_time: 0,
total_waiting_time: 0,
start_time: 0,
end_time: 0,
routes: vrp.vehicles.collect{ |vehicle|
{
vehicle_id: vehicle.id,
original_vehicle_id: vehicle.original_id,
activities: (
[build_route_depot(vehicle.start_point)] +
vrp.services.collect{ |service|
mission_hash = build_route_activity(service, service.type, service.activity || service.activities.first)
mission_hash[:service_id] = service.id
mission_hash
} +
[build_route_depot(vehicle.end_point)]
).compact
}
} || [],
unassigned: []
}
routes: routes
)
end
end
end

0 comments on commit 9f13ae1

Please sign in to comment.