Giter VIP home page Giter VIP logo

or-tools-ruby's Introduction

OR-Tools Ruby

OR-Tools - operations research tools - for Ruby

Build Status

Installation

Add this line to your application’s Gemfile:

gem "or-tools"

Installation can take a few minutes as OR-Tools downloads and builds.

Getting Started

Higher Level Interfaces

Linear Optimization

Integer Optimization

Constraint Optimization

Assignment

Routing

Bin Packing

Network Flows

Scheduling

Other Examples

Higher Level Interfaces

Scheduling

Specify people and their availabililty

people = [
  {
    availability: [
      {starts_at: Time.parse("2020-01-01 08:00:00"), ends_at: Time.parse("2020-01-01 16:00:00")},
      {starts_at: Time.parse("2020-01-02 08:00:00"), ends_at: Time.parse("2020-01-02 16:00:00")}
    ],
    max_hours: 40 # optional, applies to entire scheduling period
  },
  {
    availability: [
      {starts_at: Time.parse("2020-01-01 08:00:00"), ends_at: Time.parse("2020-01-01 16:00:00")},
      {starts_at: Time.parse("2020-01-03 08:00:00"), ends_at: Time.parse("2020-01-03 16:00:00")}
    ],
    max_hours: 20
  }
]

Specify shifts

shifts = [
  {starts_at: Time.parse("2020-01-01 08:00:00"), ends_at: Time.parse("2020-01-01 16:00:00")},
  {starts_at: Time.parse("2020-01-02 08:00:00"), ends_at: Time.parse("2020-01-02 16:00:00")},
  {starts_at: Time.parse("2020-01-03 08:00:00"), ends_at: Time.parse("2020-01-03 16:00:00")}
]

Run the scheduler

scheduler = ORTools::BasicScheduler.new(people: people, shifts: shifts)

The scheduler maximizes the number of assigned hours. A person must be available for the entire shift to be considered for it.

Get assignments (returns indexes of people and shifts)

scheduler.assignments
# [
#   {person: 2, shift: 0},
#   {person: 0, shift: 1},
#   {person: 1, shift: 2}
# ]

Get assigned hours and total hours

scheduler.assigned_hours
scheduler.total_hours

Feel free to create an issue if you have a scheduling use case that’s not covered.

Seating

Create a seating chart based on personal connections. Uses this approach.

Specify connections

connections = [
  {people: ["A", "B", "C"], weight: 2},
  {people: ["C", "D", "E", "F"], weight: 1}
]

Use different weights to prioritize seating. For a wedding, it may look like:

connections = [
  {people: knows_partner1, weight: 1},
  {people: knows_partner2, weight: 1},
  {people: relationship1, weight: 100},
  {people: relationship2, weight: 100},
  {people: relationship3, weight: 100},
  {people: friend_group1, weight: 10},
  {people: friend_group2, weight: 10},
  # ...
]

If two people have multiple connections, weights are added.

Specify tables and their capacity

tables = [3, 3]

Assign seats

seating = ORTools::Seating.new(connections: connections, tables: tables)

Each person will have a connection with at least one other person at their table.

Get tables

seating.assigned_tables

Get assignments by person

seating.assignments

Get all connections for a person

seating.connections_for(person)

Get connections for a person at their table

seating.connections_for(person, same_table: true)

Traveling Salesperson Problem (TSP)

Create locations - the first location will be the starting and ending point

locations = [
  {name: "Tokyo", latitude: 35.6762, longitude: 139.6503},
  {name: "Delhi", latitude: 28.7041, longitude: 77.1025},
  {name: "Shanghai", latitude: 31.2304, longitude: 121.4737},
  {name: "São Paulo", latitude: -23.5505, longitude: -46.6333},
  {name: "Mexico City", latitude: 19.4326, longitude: -99.1332},
  {name: "Cairo", latitude: 30.0444, longitude: 31.2357},
  {name: "Mumbai", latitude: 19.0760, longitude: 72.8777},
  {name: "Beijing", latitude: 39.9042, longitude: 116.4074},
  {name: "Dhaka", latitude: 23.8103, longitude: 90.4125},
  {name: "Osaka", latitude: 34.6937, longitude: 135.5023},
  {name: "New York City", latitude: 40.7128, longitude: -74.0060},
  {name: "Karachi", latitude: 24.8607, longitude: 67.0011},
  {name: "Buenos Aires", latitude: -34.6037, longitude: -58.3816}
]

Locations can have any fields - only latitude and longitude are required

Get route

tsp = ORTools::TSP.new(locations)
tsp.route # [{name: "Tokyo", ...}, {name: "Osaka", ...}, ...]

Get distances between locations on route

tsp.distances # [392.441, 1362.926, 1067.31, ...]

Distances are in kilometers - multiply by 0.6214 for miles

Get total distance

tsp.total_distance

Sudoku

Create a puzzle with zeros in empty cells

grid = [
  [0, 6, 0, 0, 5, 0, 0, 2, 0],
  [0, 0, 0, 3, 0, 0, 0, 9, 0],
  [7, 0, 0, 6, 0, 0, 0, 1, 0],
  [0, 0, 6, 0, 3, 0, 4, 0, 0],
  [0, 0, 4, 0, 7, 0, 1, 0, 0],
  [0, 0, 5, 0, 9, 0, 8, 0, 0],
  [0, 4, 0, 0, 0, 1, 0, 0, 6],
  [0, 3, 0, 0, 0, 8, 0, 0, 0],
  [0, 2, 0, 0, 4, 0, 0, 5, 0]
]
sudoku = ORTools::Sudoku.new(grid)
sudoku.solution

It can also solve more advanced puzzles like The Miracle

grid = [
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 1, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 2, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0]
]
sudoku = ORTools::Sudoku.new(grid, anti_knight: true, anti_king: true, non_consecutive: true)
sudoku.solution

And this 4-digit puzzle

grid = [
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
  [3, 8, 4, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 2]
]
sudoku = ORTools::Sudoku.new(grid, x: true, anti_knight: true, magic_square: true)
sudoku.solution

Linear Optimization

Solving an LP Problem

Guide

# declare the solver
solver = ORTools::Solver.new("GLOP")

# create the variables
x = solver.num_var(0, solver.infinity, "x")
y = solver.num_var(0, solver.infinity, "y")
puts "Number of variables = #{solver.num_variables}"

# define the constraints
solver.add(x + 2 * y <= 14)
solver.add(3 * x - y >= 0)
solver.add(x - y <= 2)
puts "Number of constraints = #{solver.num_constraints}"

# define the objective function
solver.maximize(3 * x + 4 * y)

# invoke the solver
status = solver.solve

# display the solution
if status == :optimal
  puts "Solution:"
  puts "Objective value = #{solver.objective.value}"
  puts "x = #{x.solution_value}"
  puts "y = #{y.solution_value}"
else
  puts "The problem does not have an optimal solution."
end

Integer Optimization

Solving a MIP Problem

Guide

# declare the MIP solver
solver = ORTools::Solver.new("CBC")

# define the variables
infinity = solver.infinity
x = solver.int_var(0, infinity, "x")
y = solver.int_var(0, infinity, "y")

puts "Number of variables = #{solver.num_variables}"

# define the constraints
solver.add(x + 7 * y <= 17.5)
solver.add(x <= 3.5)

puts "Number of constraints = #{solver.num_constraints}"

# define the objective
solver.maximize(x + 10 * y)

# call the solver
status = solver.solve

# display the solution
if status == :optimal
  puts "Solution:"
  puts "Objective value = #{solver.objective.value}"
  puts "x = #{x.solution_value}"
  puts "y = #{y.solution_value}"
else
  puts "The problem does not have an optimal solution."
end

Constraint Optimization

CP-SAT Solver

Guide

# declare the model
model = ORTools::CpModel.new

# create the variables
num_vals = 3
x = model.new_int_var(0, num_vals - 1, "x")
y = model.new_int_var(0, num_vals - 1, "y")
z = model.new_int_var(0, num_vals - 1, "z")

# create the constraint
model.add(x != y)

# call the solver
solver = ORTools::CpSolver.new
status = solver.solve(model)

# display the first solution
if status == :optimal || status == :feasible
  puts "x = #{solver.value(x)}"
  puts "y = #{solver.value(y)}"
  puts "z = #{solver.value(z)}"
else
  puts "No solution found."
end

Solving a CP Problem

Guide

# declare the model
model = ORTools::CpModel.new

# create the variables
var_upper_bound = [50, 45, 37].max
x = model.new_int_var(0, var_upper_bound, "x")
y = model.new_int_var(0, var_upper_bound, "y")
z = model.new_int_var(0, var_upper_bound, "z")

# define the constraints
model.add(x*2 + y*7 + z*3 <= 50)
model.add(x*3 - y*5 + z*7 <= 45)
model.add(x*5 + y*2 - z*6 <= 37)

# define the objective function
model.maximize(x*2 + y*2 + z*3)

# call the solver
solver = ORTools::CpSolver.new
status = solver.solve(model)

# display the solution
if status == :optimal || status == :feasible
  puts "Maximum of objective function: #{solver.objective_value}"
  puts "x = #{solver.value(x)}"
  puts "y = #{solver.value(y)}"
  puts "z = #{solver.value(z)}"
else
  puts "No solution found."
end

Cryptarithmetic

Guide

# define the variables
model = ORTools::CpModel.new

base = 10

c = model.new_int_var(1, base - 1, "C")
p = model.new_int_var(0, base - 1, "P")
i = model.new_int_var(1, base - 1, "I")
s = model.new_int_var(0, base - 1, "S")
f = model.new_int_var(1, base - 1, "F")
u = model.new_int_var(0, base - 1, "U")
n = model.new_int_var(0, base - 1, "N")
t = model.new_int_var(1, base - 1, "T")
r = model.new_int_var(0, base - 1, "R")
e = model.new_int_var(0, base - 1, "E")

letters = [c, p, i, s, f, u, n, t, r, e]

# define the constraints
model.add_all_different(letters)

model.add(c * base + p + i * base + s + f * base * base + u * base +
  n == t * base * base * base + r * base * base + u * base + e)

# define the solution printer
class VarArraySolutionPrinter < ORTools::CpSolverSolutionCallback
  attr_reader :solution_count

  def initialize(variables)
    super()
    @variables = variables
    @solution_count = 0
  end

  def on_solution_callback
    @solution_count += 1
    @variables.each do |v|
      print "%s=%i " % [v.name, value(v)]
    end
    puts
  end
end

# invoke the solver
solver = ORTools::CpSolver.new
solution_printer = VarArraySolutionPrinter.new(letters)
status = solver.search_for_all_solutions(model, solution_printer)

puts
puts "Statistics"
puts "  - status          : %s" % status
puts "  - conflicts       : %i" % solver.num_conflicts
puts "  - branches        : %i" % solver.num_branches
puts "  - wall time       : %f s" % solver.wall_time
puts "  - solutions found : %i" % solution_printer.solution_count

The N-queens Problem

Guide

# declare the model
board_size = 8
model = ORTools::CpModel.new

# create the variables
queens = board_size.times.map { |i| model.new_int_var(0, board_size - 1, "x%i" % i) }

# create the constraints
board_size.times do |i|
  diag1 = []
  diag2 = []
  board_size.times do |j|
    q1 = model.new_int_var(0, 2 * board_size, "diag1_%i" % i)
    diag1 << q1
    model.add(q1 == queens[j] + j)
    q2 = model.new_int_var(-board_size, board_size, "diag2_%i" % i)
    diag2 << q2
    model.add(q2 == queens[j] - j)
  end
  model.add_all_different(diag1)
  model.add_all_different(diag2)
end

# create a solution printer
class SolutionPrinter < ORTools::CpSolverSolutionCallback
  attr_reader :solution_count

  def initialize(variables)
    super()
    @variables = variables
    @solution_count = 0
  end

  def on_solution_callback
    @solution_count += 1
    @variables.each do |v|
      print "%s = %i " % [v.name, value(v)]
    end
    puts
  end
end

# call the solver and display the results
solver = ORTools::CpSolver.new
solution_printer = SolutionPrinter.new(queens)
status = solver.search_for_all_solutions(model, solution_printer)
puts
puts "Solutions found : %i" % solution_printer.solution_count

Setting Solver Limits

Guide

# create the model
model = ORTools::CpModel.new

# create the variables
num_vals = 3
x = model.new_int_var(0, num_vals - 1, "x")
y = model.new_int_var(0, num_vals - 1, "y")
z = model.new_int_var(0, num_vals - 1, "z")

# add an all-different constraint
model.add(x != y)

# create the solver
solver = ORTools::CpSolver.new

# set a time limit of 10 seconds.
solver.parameters.max_time_in_seconds = 10

# solve the model
status = solver.solve(model)

# display the first solution
if status == :optimal
  puts "x = #{solver.value(x)}"
  puts "y = #{solver.value(y)}"
  puts "z = #{solver.value(z)}"
end

Assignment

Solving an Assignment Problem

Guide

# create the data
costs = [
  [90, 80, 75, 70],
  [35, 85, 55, 65],
  [125, 95, 90, 95],
  [45, 110, 95, 115],
  [50, 100, 90, 100]
]
num_workers = costs.length
num_tasks = costs[0].length

# create the solver
solver = ORTools::Solver.new("CBC")

# create the variables
x = {}
num_workers.times do |i|
  num_tasks.times do |j|
    x[[i, j]] = solver.int_var(0, 1, "")
  end
end

# create the constraints
# each worker is assigned to at most 1 task
num_workers.times do |i|
  solver.add(num_tasks.times.sum { |j| x[[i, j]] } <= 1)
end

# each task is assigned to exactly one worker
num_tasks.times do |j|
  solver.add(num_workers.times.sum { |i| x[[i, j]] } == 1)
end

# create the objective function
objective_terms = []
num_workers.times do |i|
  num_tasks.times do |j|
    objective_terms << (costs[i][j] * x[[i, j]])
  end
end
solver.minimize(objective_terms.sum)

# invoke the solver
status = solver.solve

# print the solution
if status == :optimal || status == :feasible
  puts "Total cost = #{solver.objective.value}"
  num_workers.times do |i|
    num_tasks.times do |j|
      # test if x[i,j] is 1 (with tolerance for floating point arithmetic)
      if x[[i, j]].solution_value > 0.5
        puts "Worker #{i} assigned to task #{j}. Cost = #{costs[i][j]}"
      end
    end
  end
else
  puts "No solution found."
end

Assignment with Teams of Workers

Guide

# create the data
costs = [
  [90, 76, 75, 70],
  [35, 85, 55, 65],
  [125, 95, 90, 105],
  [45, 110, 95, 115],
  [60, 105, 80, 75],
  [45, 65, 110, 95]
]
num_workers = costs.length
num_tasks = costs[1].length

team1 = [0, 2, 4]
team2 = [1, 3, 5]
team_max = 2

# create the solver
solver = ORTools::Solver.new("CBC")

# create the variables
x = {}
num_workers.times do |i|
  num_tasks.times do |j|
    x[[i, j]] = solver.bool_var("x[#{i},#{j}]")
  end
end

# add the constraints
# each worker is assigned at most 1 task
num_workers.times do |i|
  solver.add(num_tasks.times.sum { |j| x[[i, j]] } <= 1)
end

# each task is assigned to exactly one worker
num_tasks.times do |j|
  solver.add(num_workers.times.sum { |i| x[[i, j]] } == 1)
end

# each team takes at most two tasks
solver.add(team1.flat_map { |i| num_tasks.times.map { |j| x[[i, j]] } }.sum <= team_max)
solver.add(team2.flat_map { |i| num_tasks.times.map { |j| x[[i, j]] } }.sum <= team_max)

# create the objective
solver.minimize(
  num_workers.times.flat_map { |i| num_tasks.times.map { |j| x[[i, j]] * costs[i][j] } }.sum
)

# invoke the solver
status = solver.solve

# display the results
if status == :optimal || status == :feasible
  puts "Total cost = #{solver.objective.value}"
  num_workers.times do |worker|
    num_tasks.times do |task|
      if x[[worker, task]].solution_value > 0.5
        puts "Worker #{worker} assigned to task #{task}. Cost = #{costs[worker][task]}"
      end
    end
  end
else
  puts "No solution found."
end

Linear Sum Assignment Solver

Guide

# create the data
costs = [
  [90, 76, 75, 70],
  [35, 85, 55, 65],
  [125, 95, 90, 105],
  [45, 110, 95, 115],
]
num_workers = costs.length
num_tasks = costs[0].length

# create the solver
assignment = ORTools::LinearSumAssignment.new

# add the constraints
num_workers.times do |worker|
  num_tasks.times do |task|
    if costs[worker][task]
      assignment.add_arc_with_cost(worker, task, costs[worker][task])
    end
  end
end

# invoke the solver
status = assignment.solve

# display the results
case status
when :optimal
  puts "Total cost = #{assignment.optimal_cost}"
  assignment.num_nodes.times do |i|
    puts "Worker #{i} assigned to task #{assignment.right_mate(i)}. Cost = #{assignment.assignment_cost(i)}"
  end
when :infeasible
  puts "No assignment is possible."
when :possible_overflow
  puts "Some input costs are too large and may cause an integer overflow."
end

Routing

Traveling Salesperson Problem (TSP)

Guide

# create the data
data = {}
data[:distance_matrix] = [
  [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972],
  [2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579],
  [713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260],
  [1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987],
  [1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371],
  [1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999],
  [2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701],
  [213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099],
  [2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600],
  [875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162],
  [1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200],
  [2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504],
  [1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]
]
data[:num_vehicles] = 1
data[:depot] = 0

# create the distance callback
manager = ORTools::RoutingIndexManager.new(data[:distance_matrix].length, data[:num_vehicles], data[:depot])
routing = ORTools::RoutingModel.new(manager)

distance_callback = lambda do |from_index, to_index|
  from_node = manager.index_to_node(from_index)
  to_node = manager.index_to_node(to_index)
  data[:distance_matrix][from_node][to_node]
end

transit_callback_index = routing.register_transit_callback(distance_callback)
routing.set_arc_cost_evaluator_of_all_vehicles(transit_callback_index)

# run the solver
assignment = routing.solve(first_solution_strategy: :path_cheapest_arc)

# print the solution
puts "Objective: #{assignment.objective_value} miles"
index = routing.start(0)
plan_output = String.new("Route for vehicle 0:\n")
route_distance = 0
while !routing.end?(index)
  plan_output += " #{manager.index_to_node(index)} ->"
  previous_index = index
  index = assignment.value(routing.next_var(index))
  route_distance += routing.arc_cost_for_vehicle(previous_index, index, 0)
end
plan_output += " #{manager.index_to_node(index)}\n"
puts plan_output

Vehicle Routing Problem (VRP)

Guide

# create the data
data = {}
data[:distance_matrix] = [
  [0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662],
  [548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210],
  [776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754],
  [696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358],
  [582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244],
  [274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708],
  [502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480],
  [194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856],
  [308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514],
  [194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468],
  [536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354],
  [502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844],
  [388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730],
  [354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536],
  [468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194],
  [776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798],
  [662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0]
]
data[:num_vehicles] = 4
data[:depot] = 0

# define the distance callback
manager = ORTools::RoutingIndexManager.new(data[:distance_matrix].length, data[:num_vehicles], data[:depot])
routing = ORTools::RoutingModel.new(manager)

distance_callback = lambda do |from_index, to_index|
  from_node = manager.index_to_node(from_index)
  to_node = manager.index_to_node(to_index)
  data[:distance_matrix][from_node][to_node]
end

transit_callback_index = routing.register_transit_callback(distance_callback)
routing.set_arc_cost_evaluator_of_all_vehicles(transit_callback_index)

# add a distance dimension
dimension_name = "Distance"
routing.add_dimension(transit_callback_index, 0, 3000, true, dimension_name)
distance_dimension = routing.mutable_dimension(dimension_name)
distance_dimension.global_span_cost_coefficient = 100

# run the solver
solution = routing.solve(first_solution_strategy: :path_cheapest_arc)

# print the solution
max_route_distance = 0
data[:num_vehicles].times do |vehicle_id|
  index = routing.start(vehicle_id)
  plan_output = String.new("Route for vehicle #{vehicle_id}:\n")
  route_distance = 0
  while !routing.end?(index)
    plan_output += " #{manager.index_to_node(index)} -> "
    previous_index = index
    index = solution.value(routing.next_var(index))
    route_distance += routing.arc_cost_for_vehicle(previous_index, index, vehicle_id)
  end
  plan_output += "#{manager.index_to_node(index)}\n"
  plan_output += "Distance of the route: #{route_distance}m\n\n"
  puts plan_output
  max_route_distance = [route_distance, max_route_distance].max
end
puts "Maximum of the route distances: #{max_route_distance}m"

Capacity Constraints

Guide

data = {}
data[:distance_matrix] = [
  [0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662],
  [548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210],
  [776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754],
  [696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358],
  [582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244],
  [274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708],
  [502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480],
  [194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856],
  [308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514],
  [194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468],
  [536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354],
  [502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844],
  [388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730],
  [354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536],
  [468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194],
  [776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798],
  [662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0]
]
data[:demands] = [0, 1, 1, 2, 4, 2, 4, 8, 8, 1, 2, 1, 2, 4, 4, 8, 8]
data[:vehicle_capacities] = [15, 15, 15, 15]
data[:num_vehicles] = 4
data[:depot] = 0

manager = ORTools::RoutingIndexManager.new(data[:distance_matrix].size, data[:num_vehicles], data[:depot])
routing = ORTools::RoutingModel.new(manager)

distance_callback = lambda do |from_index, to_index|
  from_node = manager.index_to_node(from_index)
  to_node = manager.index_to_node(to_index)
  data[:distance_matrix][from_node][to_node]
end

transit_callback_index = routing.register_transit_callback(distance_callback)

routing.set_arc_cost_evaluator_of_all_vehicles(transit_callback_index)

demand_callback = lambda do |from_index|
  from_node = manager.index_to_node(from_index)
  data[:demands][from_node]
end

demand_callback_index = routing.register_unary_transit_callback(demand_callback)
routing.add_dimension_with_vehicle_capacity(
  demand_callback_index,
  0,  # null capacity slack
  data[:vehicle_capacities],  # vehicle maximum capacities
  true,  # start cumul to zero
  "Capacity"
)

solution = routing.solve(first_solution_strategy: :path_cheapest_arc)

total_distance = 0
total_load = 0
data[:num_vehicles].times do |vehicle_id|
  index = routing.start(vehicle_id)
  plan_output = String.new("Route for vehicle #{vehicle_id}:\n")
  route_distance = 0
  route_load = 0
  while !routing.end?(index)
    node_index = manager.index_to_node(index)
    route_load += data[:demands][node_index]
    plan_output += " #{node_index} Load(#{route_load}) -> "
    previous_index = index
    index = solution.value(routing.next_var(index))
    route_distance += routing.arc_cost_for_vehicle(previous_index, index, vehicle_id)
  end
  plan_output += " #{manager.index_to_node(index)} Load(#{route_load})\n"
  plan_output += "Distance of the route: #{route_distance}m\n"
  plan_output += "Load of the route: #{route_load}\n\n"
  puts plan_output
  total_distance += route_distance
  total_load += route_load
end
puts "Total distance of all routes: #{total_distance}m"
puts "Total load of all routes: #{total_load}"

Pickups and Deliveries

Guide

data = {}
data[:distance_matrix] = [
  [0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662],
  [548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210],
  [776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754],
  [696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358],
  [582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244],
  [274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708],
  [502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480],
  [194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856],
  [308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514],
  [194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468],
  [536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354],
  [502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844],
  [388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730],
  [354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536],
  [468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194],
  [776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798],
  [662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0]
]
data[:pickups_deliveries] = [
  [1, 6],
  [2, 10],
  [4, 3],
  [5, 9],
  [7, 8],
  [15, 11],
  [13, 12],
  [16, 14],
]
data[:num_vehicles] = 4
data[:depot] = 0

manager = ORTools::RoutingIndexManager.new(data[:distance_matrix].size, data[:num_vehicles], data[:depot])
routing = ORTools::RoutingModel.new(manager)

distance_callback = lambda do |from_index, to_index|
  from_node = manager.index_to_node(from_index)
  to_node = manager.index_to_node(to_index)
  data[:distance_matrix][from_node][to_node]
end

transit_callback_index = routing.register_transit_callback(distance_callback)
routing.set_arc_cost_evaluator_of_all_vehicles(transit_callback_index)

dimension_name = "Distance"
routing.add_dimension(
  transit_callback_index,
  0,  # no slack
  3000,  # vehicle maximum travel distance
  true,  # start cumul to zero
  dimension_name
)
distance_dimension = routing.mutable_dimension(dimension_name)
distance_dimension.global_span_cost_coefficient = 100

data[:pickups_deliveries].each do |request|
  pickup_index = manager.node_to_index(request[0])
  delivery_index = manager.node_to_index(request[1])
  routing.add_pickup_and_delivery(pickup_index, delivery_index)
  routing.solver.add(routing.vehicle_var(pickup_index) == routing.vehicle_var(delivery_index))
  routing.solver.add(distance_dimension.cumul_var(pickup_index) <= distance_dimension.cumul_var(delivery_index))
end

solution = routing.solve(first_solution_strategy: :parallel_cheapest_insertion)

total_distance = 0
data[:num_vehicles].times do |vehicle_id|
  index = routing.start(vehicle_id)
  plan_output = String.new("Route for vehicle #{vehicle_id}:\n")
  route_distance = 0
  while !routing.end?(index)
    plan_output += " #{manager.index_to_node(index)} -> "
    previous_index = index
    index = solution.value(routing.next_var(index))
    route_distance += routing.arc_cost_for_vehicle(previous_index, index, vehicle_id)
  end
  plan_output += "#{manager.index_to_node(index)}\n"
  plan_output += "Distance of the route: #{route_distance}m\n\n"
  puts plan_output
  total_distance += route_distance
end
puts "Total Distance of all routes: #{total_distance}m"

Time Window Constraints

Guide

data = {}
data[:time_matrix] = [
  [0, 6, 9, 8, 7, 3, 6, 2, 3, 2, 6, 6, 4, 4, 5, 9, 7],
  [6, 0, 8, 3, 2, 6, 8, 4, 8, 8, 13, 7, 5, 8, 12, 10, 14],
  [9, 8, 0, 11, 10, 6, 3, 9, 5, 8, 4, 15, 14, 13, 9, 18, 9],
  [8, 3, 11, 0, 1, 7, 10, 6, 10, 10, 14, 6, 7, 9, 14, 6, 16],
  [7, 2, 10, 1, 0, 6, 9, 4, 8, 9, 13, 4, 6, 8, 12, 8, 14],
  [3, 6, 6, 7, 6, 0, 2, 3, 2, 2, 7, 9, 7, 7, 6, 12, 8],
  [6, 8, 3, 10, 9, 2, 0, 6, 2, 5, 4, 12, 10, 10, 6, 15, 5],
  [2, 4, 9, 6, 4, 3, 6, 0, 4, 4, 8, 5, 4, 3, 7, 8, 10],
  [3, 8, 5, 10, 8, 2, 2, 4, 0, 3, 4, 9, 8, 7, 3, 13, 6],
  [2, 8, 8, 10, 9, 2, 5, 4, 3, 0, 4, 6, 5, 4, 3, 9, 5],
  [6, 13, 4, 14, 13, 7, 4, 8, 4, 4, 0, 10, 9, 8, 4, 13, 4],
  [6, 7, 15, 6, 4, 9, 12, 5, 9, 6, 10, 0, 1, 3, 7, 3, 10],
  [4, 5, 14, 7, 6, 7, 10, 4, 8, 5, 9, 1, 0, 2, 6, 4, 8],
  [4, 8, 13, 9, 8, 7, 10, 3, 7, 4, 8, 3, 2, 0, 4, 5, 6],
  [5, 12, 9, 14, 12, 6, 6, 7, 3, 3, 4, 7, 6, 4, 0, 9, 2],
  [9, 10, 18, 6, 8, 12, 15, 8, 13, 9, 13, 3, 4, 5, 9, 0, 9],
  [7, 14, 9, 16, 14, 8, 5, 10, 6, 5, 4, 10, 8, 6, 2, 9, 0],
]
data[:time_windows] = [
  [0, 5],  # depot
  [7, 12],  # 1
  [10, 15],  # 2
  [16, 18],  # 3
  [10, 13],  # 4
  [0, 5],  # 5
  [5, 10],  # 6
  [0, 4],  # 7
  [5, 10],  # 8
  [0, 3],  # 9
  [10, 16],  # 10
  [10, 15],  # 11
  [0, 5],  # 12
  [5, 10],  # 13
  [7, 8],  # 14
  [10, 15],  # 15
  [11, 15],  # 16
]
data[:num_vehicles] = 4
data[:depot] = 0

manager = ORTools::RoutingIndexManager.new(data[:time_matrix].size, data[:num_vehicles], data[:depot])
routing = ORTools::RoutingModel.new(manager)

time_callback = lambda do |from_index, to_index|
  from_node = manager.index_to_node(from_index)
  to_node = manager.index_to_node(to_index)
  data[:time_matrix][from_node][to_node]
end

transit_callback_index = routing.register_transit_callback(time_callback)
routing.set_arc_cost_evaluator_of_all_vehicles(transit_callback_index)
time = "Time"
routing.add_dimension(
  transit_callback_index,
  30,  # allow waiting time
  30,  # maximum time per vehicle
  false,  # don't force start cumul to zero
  time
)
time_dimension = routing.mutable_dimension(time)

data[:time_windows].each_with_index do |time_window, location_idx|
  next if location_idx == 0
  index = manager.node_to_index(location_idx)
  time_dimension.cumul_var(index).set_range(time_window[0], time_window[1])
end

data[:num_vehicles].times do |vehicle_id|
  index = routing.start(vehicle_id)
  time_dimension.cumul_var(index).set_range(data[:time_windows][0][0], data[:time_windows][0][1])
end

data[:num_vehicles].times do |i|
  routing.add_variable_minimized_by_finalizer(time_dimension.cumul_var(routing.start(i)))
  routing.add_variable_minimized_by_finalizer(time_dimension.cumul_var(routing.end(i)))
end

solution = routing.solve(first_solution_strategy: :path_cheapest_arc)

time_dimension = routing.mutable_dimension("Time")
total_time = 0
data[:num_vehicles].times do |vehicle_id|
  index = routing.start(vehicle_id)
  plan_output = String.new("Route for vehicle #{vehicle_id}:\n")
  while !routing.end?(index)
    time_var = time_dimension.cumul_var(index)
    plan_output += "#{manager.index_to_node(index)} Time(#{solution.min(time_var)},#{solution.max(time_var)}) -> "
    index = solution.value(routing.next_var(index))
  end
  time_var = time_dimension.cumul_var(index)
  plan_output += "#{manager.index_to_node(index)} Time(#{solution.min(time_var)},#{solution.max(time_var)})\n"
  plan_output += "Time of the route: #{solution.min(time_var)}min\n\n"
  puts plan_output
  total_time += solution.min(time_var)
end
puts "Total time of all routes: #{total_time}min"

Resource Constraints

Guide

data = {}
data[:time_matrix] = [
  [0, 6, 9, 8, 7, 3, 6, 2, 3, 2, 6, 6, 4, 4, 5, 9, 7],
  [6, 0, 8, 3, 2, 6, 8, 4, 8, 8, 13, 7, 5, 8, 12, 10, 14],
  [9, 8, 0, 11, 10, 6, 3, 9, 5, 8, 4, 15, 14, 13, 9, 18, 9],
  [8, 3, 11, 0, 1, 7, 10, 6, 10, 10, 14, 6, 7, 9, 14, 6, 16],
  [7, 2, 10, 1, 0, 6, 9, 4, 8, 9, 13, 4, 6, 8, 12, 8, 14],
  [3, 6, 6, 7, 6, 0, 2, 3, 2, 2, 7, 9, 7, 7, 6, 12, 8],
  [6, 8, 3, 10, 9, 2, 0, 6, 2, 5, 4, 12, 10, 10, 6, 15, 5],
  [2, 4, 9, 6, 4, 3, 6, 0, 4, 4, 8, 5, 4, 3, 7, 8, 10],
  [3, 8, 5, 10, 8, 2, 2, 4, 0, 3, 4, 9, 8, 7, 3, 13, 6],
  [2, 8, 8, 10, 9, 2, 5, 4, 3, 0, 4, 6, 5, 4, 3, 9, 5],
  [6, 13, 4, 14, 13, 7, 4, 8, 4, 4, 0, 10, 9, 8, 4, 13, 4],
  [6, 7, 15, 6, 4, 9, 12, 5, 9, 6, 10, 0, 1, 3, 7, 3, 10],
  [4, 5, 14, 7, 6, 7, 10, 4, 8, 5, 9, 1, 0, 2, 6, 4, 8],
  [4, 8, 13, 9, 8, 7, 10, 3, 7, 4, 8, 3, 2, 0, 4, 5, 6],
  [5, 12, 9, 14, 12, 6, 6, 7, 3, 3, 4, 7, 6, 4, 0, 9, 2],
  [9, 10, 18, 6, 8, 12, 15, 8, 13, 9, 13, 3, 4, 5, 9, 0, 9],
  [7, 14, 9, 16, 14, 8, 5, 10, 6, 5, 4, 10, 8, 6, 2, 9, 0]
]
data[:time_windows] = [
  [0, 5],  # depot
  [7, 12],  # 1
  [10, 15],  # 2
  [5, 14],  # 3
  [5, 13],  # 4
  [0, 5],  # 5
  [5, 10],  # 6
  [0, 10],  # 7
  [5, 10],  # 8
  [0, 5],  # 9
  [10, 16],  # 10
  [10, 15],  # 11
  [0, 5],  # 12
  [5, 10],  # 13
  [7, 12],  # 14
  [10, 15],  # 15
  [5, 15],  # 16
]
data[:num_vehicles] = 4
data[:vehicle_load_time] = 5
data[:vehicle_unload_time] = 5
data[:depot_capacity] = 2
data[:depot] = 0

manager = ORTools::RoutingIndexManager.new(data[:time_matrix].size, data[:num_vehicles], data[:depot])
routing = ORTools::RoutingModel.new(manager)

time_callback = lambda do |from_index, to_index|
  from_node = manager.index_to_node(from_index)
  to_node = manager.index_to_node(to_index)
  data[:time_matrix][from_node][to_node]
end

transit_callback_index = routing.register_transit_callback(time_callback)

routing.set_arc_cost_evaluator_of_all_vehicles(transit_callback_index)

time = "Time"
routing.add_dimension(
  transit_callback_index,
  60,  # allow waiting time
  60,  # maximum time per vehicle
  false,  # don't force start cumul to zero
  time
)
time_dimension = routing.mutable_dimension(time)
data[:time_windows].each_with_index do |time_window, location_idx|
  next if location_idx == 0
  index = manager.node_to_index(location_idx)
  time_dimension.cumul_var(index).set_range(time_window[0], time_window[1])
end

data[:num_vehicles].times do |vehicle_id|
  index = routing.start(vehicle_id)
  time_dimension.cumul_var(index).set_range(data[:time_windows][0][0], data[:time_windows][0][1])
end

solver = routing.solver
intervals = []
data[:num_vehicles].times do |i|
  intervals << solver.fixed_duration_interval_var(
    time_dimension.cumul_var(routing.start(i)),
    data[:vehicle_load_time],
    "depot_interval"
  )
  intervals << solver.fixed_duration_interval_var(
    time_dimension.cumul_var(routing.end(i)),
    data[:vehicle_unload_time],
    "depot_interval"
  )
end

depot_usage = [1] * intervals.size
solver.add(solver.cumulative(intervals, depot_usage, data[:depot_capacity], "depot"))

data[:num_vehicles].times do |i|
  routing.add_variable_minimized_by_finalizer(time_dimension.cumul_var(routing.start(i)))
  routing.add_variable_minimized_by_finalizer(time_dimension.cumul_var(routing.end(i)))
end

solution = routing.solve(first_solution_strategy: :path_cheapest_arc)

time_dimension = routing.mutable_dimension("Time")
total_time = 0
data[:num_vehicles].times do |vehicle_id|
  index = routing.start(vehicle_id)
  plan_output = String.new("Route for vehicle #{vehicle_id}:\n")
  while !routing.end?(index)
    time_var = time_dimension.cumul_var(index)
    plan_output += "#{manager.index_to_node(index)} Time(#{solution.min(time_var)},#{solution.max(time_var)}) -> "
    index = solution.value(routing.next_var(index))
  end
  time_var = time_dimension.cumul_var(index)
  plan_output += "#{manager.index_to_node(index)} Time(#{solution.min(time_var)},#{solution.max(time_var)})\n"
  plan_output += "Time of the route: #{solution.min(time_var)}min\n\n"
  puts plan_output
  total_time += solution.min(time_var)
end
puts "Total time of all routes: #{total_time}min"

Penalties and Dropping Visits

Guide

data = {}
data[:distance_matrix] = [
  [0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662],
  [548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210],
  [776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754],
  [696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358],
  [582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244],
  [274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708],
  [502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480],
  [194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856],
  [308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514],
  [194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468],
  [536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354],
  [502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844],
  [388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730],
  [354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536],
  [468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194],
  [776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798],
  [662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0]
]
data[:demands] = [0, 1, 1, 3, 6, 3, 6, 8, 8, 1, 2, 1, 2, 6, 6, 8, 8]
data[:vehicle_capacities] = [15, 15, 15, 15]
data[:num_vehicles] = 4
data[:depot] = 0

manager = ORTools::RoutingIndexManager.new(data[:distance_matrix].size, data[:num_vehicles], data[:depot])
routing = ORTools::RoutingModel.new(manager)

distance_callback = lambda do |from_index, to_index|
  from_node = manager.index_to_node(from_index)
  to_node = manager.index_to_node(to_index)
  data[:distance_matrix][from_node][to_node]
end

transit_callback_index = routing.register_transit_callback(distance_callback)

routing.set_arc_cost_evaluator_of_all_vehicles(transit_callback_index)

demand_callback = lambda do |from_index|
  from_node = manager.index_to_node(from_index)
  data[:demands][from_node]
end

demand_callback_index = routing.register_unary_transit_callback(demand_callback)
routing.add_dimension_with_vehicle_capacity(
  demand_callback_index,
  0,  # null capacity slack
  data[:vehicle_capacities],  # vehicle maximum capacities
  true,  # start cumul to zero
  "Capacity"
)

penalty = 1000
1.upto(data[:distance_matrix].size - 1) do |node|
  routing.add_disjunction([manager.node_to_index(node)], penalty)
end

assignment = routing.solve(first_solution_strategy: :path_cheapest_arc)

dropped_nodes = String.new("Dropped nodes:")
routing.size.times do |node|
  next if routing.start?(node) || routing.end?(node)

  if assignment.value(routing.next_var(node)) == node
    dropped_nodes += " #{manager.index_to_node(node)}"
  end
end
puts dropped_nodes

total_distance = 0
total_load = 0
data[:num_vehicles].times do |vehicle_id|
  index = routing.start(vehicle_id)
  plan_output = "Route for vehicle #{vehicle_id}:\n"
  route_distance = 0
  route_load = 0
  while !routing.end?(index)
    node_index = manager.index_to_node(index)
    route_load += data[:demands][node_index]
    plan_output += " #{node_index} Load(#{route_load}) -> "
    previous_index = index
    index = assignment.value(routing.next_var(index))
    route_distance += routing.arc_cost_for_vehicle(previous_index, index, vehicle_id)
  end
  plan_output += " #{manager.index_to_node(index)} Load(#{route_load})\n"
  plan_output += "Distance of the route: #{route_distance}m\n"
  plan_output += "Load of the route: #{route_load}\n\n"
  puts plan_output
  total_distance += route_distance
  total_load += route_load
end
puts "Total Distance of all routes: #{total_distance}m"
puts "Total Load of all routes: #{total_load}"

Routing Options

Guide

routing.solve(
  solution_limit: 10,
  time_limit: 10, # seconds,
  lns_time_limit: 10, # seconds
  first_solution_strategy: :path_cheapest_arc,
  local_search_metaheuristic: :guided_local_search,
  log_search: true
)

Bin Packing

The Knapsack Problem

Guide

# create the data
values = [
  360, 83, 59, 130, 431, 67, 230, 52, 93, 125, 670, 892, 600, 38, 48, 147,
  78, 256, 63, 17, 120, 164, 432, 35, 92, 110, 22, 42, 50, 323, 514, 28,
  87, 73, 78, 15, 26, 78, 210, 36, 85, 189, 274, 43, 33, 10, 19, 389, 276,
  312
]
weights = [[
  7, 0, 30, 22, 80, 94, 11, 81, 70, 64, 59, 18, 0, 36, 3, 8, 15, 42, 9, 0,
  42, 47, 52, 32, 26, 48, 55, 6, 29, 84, 2, 4, 18, 56, 7, 29, 93, 44, 71,
  3, 86, 66, 31, 65, 0, 79, 20, 65, 52, 13
]]
capacities = [850]

# declare the solver
solver = ORTools::KnapsackSolver.new(:branch_and_bound, "KnapsackExample")

# call the solver
solver.init(values, weights, capacities)
computed_value = solver.solve

packed_items = []
packed_weights = []
total_weight = 0
puts "Total value = #{computed_value}"
values.length.times do |i|
  if solver.best_solution_contains?(i)
    packed_items << i
    packed_weights << weights[0][i]
    total_weight += weights[0][i]
  end
end
puts "Total weight: #{total_weight}"
puts "Packed items: #{packed_items}"
puts "Packed weights: #{packed_weights}"

Multiple Knapsacks

Guide

# create the data
data = {}
data[:weights] = [48, 30, 42, 36, 36, 48, 42, 42, 36, 24, 30, 30, 42, 36, 36]
data[:values] = [10, 30, 25, 50, 35, 30, 15, 40, 30, 35, 45, 10, 20, 30, 25]
data[:num_items] = data[:weights].length
data[:all_items] = data[:num_items].times.to_a
data[:bin_capacities] = [100, 100, 100, 100, 100]
data[:num_bins] = data[:bin_capacities].length
data[:all_bins] = data[:num_bins].times.to_a

# declare the solver
solver = ORTools::Solver.new("CBC")

# create the variables
x = {}
data[:all_items].each do |i|
  data[:all_bins].each do |b|
    x[[i, b]] = solver.bool_var("x_#{i}_#{b}")
  end
end

# each item is assigned to at most one bin
data[:all_items].each do |i|
  solver.add(data[:all_bins].sum { |b| x[[i, b]] } <= 1)
end

# the amount packed in each bin cannot exceed its capacity
data[:all_bins].each do |b|
  solver.add(data[:all_items].sum { |i| x[[i, b]] * data[:weights][i] } <= data[:bin_capacities][b])
end

# maximize total value of packed items
objective = solver.objective
data[:all_items].each do |i|
  data[:all_bins].each do |b|
    objective.set_coefficient(x[[i, b]], data[:values][i])
  end
end
objective.set_maximization

# call the solver and print the solution
status = solver.solve

if status == :optimal
  puts "Total packed value: #{objective.value}"
  total_weight = 0
  data[:all_bins].each do |b|
    bin_weight = 0
    bin_value = 0
    puts "Bin #{b}\n\n"
    data[:all_items].each do |i|
      if x[[i, b]].solution_value > 0
        puts "Item #{i} - weight: #{data[:weights][i]}  value: #{data[:values][i]}"
        bin_weight += data[:weights][i]
        bin_value += data[:values][i]
      end
    end
    puts "Packed bin weight: #{bin_weight}"
    puts "Packed bin value: #{bin_value}"
    puts
    total_weight += bin_weight
  end
  puts "Total packed weight: #{total_weight}"
else
  puts "The problem does not have an optimal solution."
end

Bin Packing Problem

Guide

# create the data
data = {}
weights = [48, 30, 19, 36, 36, 27, 42, 42, 36, 24, 30]
data[:weights] = weights
data[:items] = (0...weights.length).to_a
data[:bins] = data[:items]
data[:bin_capacity] = 100

# create the mip solver with the CBC backend
solver = ORTools::Solver.new("CBC")

# variables
# x[i, j] = 1 if item i is packed in bin j
x = {}
data[:items].each do |i|
  data[:bins].each do |j|
    x[[i, j]] = solver.int_var(0, 1, "x_%i_%i" % [i, j])
  end
end

# y[j] = 1 if bin j is used
y = {}
data[:bins].each do |j|
  y[j] = solver.int_var(0, 1, "y[%i]" % j)
end

# constraints
# each item must be in exactly one bin
data[:items].each do |i|
  solver.add(data[:bins].sum { |j| x[[i, j]] } == 1)
end

# the amount packed in each bin cannot exceed its capacity
data[:bins].each do |j|
  sum = data[:items].sum { |i| x[[i, j]] * data[:weights][i] }
  solver.add(sum <= y[j] * data[:bin_capacity])
end

# objective: minimize the number of bins used
solver.minimize(data[:bins].sum { |j| y[j] })

# call the solver and print the solution
status = solver.solve

if status == :optimal
  num_bins = 0
  data[:bins].each do |j|
    if y[j].solution_value == 1
      bin_items = []
      bin_weight = 0
      data[:items].each do |i|
        if x[[i, j]].solution_value > 0
          bin_items << i
          bin_weight += data[:weights][i]
        end
      end
      if bin_weight > 0
        num_bins += 1
        puts "Bin number #{j}"
        puts "  Items packed: #{bin_items}"
        puts "  Total weight: #{bin_weight}"
        puts
      end
    end
  end
  puts
  puts "Number of bins used: #{num_bins}"
  puts "Time = #{solver.wall_time} milliseconds"
else
  puts "The problem does not have an optimal solution."
end

Network Flows

Maximum Flows

Guide

# define the data
start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3]
end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4]
capacities = [20, 30, 10, 40, 30, 10, 20, 5, 20]

# declare the solver and add the arcs
max_flow = ORTools::SimpleMaxFlow.new

start_nodes.length.times do |i|
  max_flow.add_arc_with_capacity(start_nodes[i], end_nodes[i], capacities[i])
end

# invoke the solver and display the results
if max_flow.solve(0, 4) == :optimal
  puts "Max flow: #{max_flow.optimal_flow}"
  puts
  puts "  Arc    Flow / Capacity"
  max_flow.num_arcs.times do |i|
    puts "%1s -> %1s   %3s  / %3s" % [
      max_flow.tail(i),
      max_flow.head(i),
      max_flow.flow(i),
      max_flow.capacity(i)
    ]
  end
  puts "Source side min-cut: #{max_flow.source_side_min_cut}"
  puts "Sink side min-cut: #{max_flow.sink_side_min_cut}"
else
  puts "There was an issue with the max flow input."
end

Minimum Cost Flows

Guide

# define the data
start_nodes = [ 0, 0,  1, 1,  1,  2, 2,  3, 4]
end_nodes   = [ 1, 2,  2, 3,  4,  3, 4,  4, 2]
capacities  = [15, 8, 20, 4, 10, 15, 4, 20, 5]
unit_costs  = [ 4, 4,  2, 2,  6,  1, 3,  2, 3]
supplies = [20, 0, 0, -5, -15]

# declare the solver and add the arcs
min_cost_flow = ORTools::SimpleMinCostFlow.new

start_nodes.length.times do |i|
  min_cost_flow.add_arc_with_capacity_and_unit_cost(
    start_nodes[i], end_nodes[i], capacities[i], unit_costs[i]
  )
end

supplies.length.times do |i|
  min_cost_flow.set_node_supply(i, supplies[i])
end

# invoke the solver and display the results
if min_cost_flow.solve == :optimal
  puts "Minimum cost #{min_cost_flow.optimal_cost}"
  puts
  puts "  Arc    Flow / Capacity  Cost"
  min_cost_flow.num_arcs.times do |i|
    cost = min_cost_flow.flow(i) * min_cost_flow.unit_cost(i)
    puts "%1s -> %1s   %3s  / %3s       %3s" % [
      min_cost_flow.tail(i),
      min_cost_flow.head(i),
      min_cost_flow.flow(i),
      min_cost_flow.capacity(i),
      cost
    ]
  end
else
  puts "There was an issue with the min cost flow input."
end

Assignment as a Min Cost Flow Problem

Guide

# create the solver
min_cost_flow = ORTools::SimpleMinCostFlow.new

# create the data
start_nodes = [0, 0, 0, 0] + [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4] + [5, 6, 7, 8]
end_nodes = [1, 2, 3, 4] + [5, 6, 7, 8, 5, 6, 7, 8, 5, 6, 7, 8, 5, 6, 7, 8] + [9, 9, 9, 9]
capacities = [1, 1, 1, 1] + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + [1, 1, 1, 1]
costs = [0, 0, 0, 0] + [90, 76, 75, 70, 35, 85, 55, 65, 125, 95, 90, 105, 45, 110, 95, 115] + [0, 0, 0, 0]
supplies = [4, 0, 0, 0, 0, 0, 0, 0, 0, -4]
source = 0
sink = 9
tasks = 4

# create the graph and constraints
start_nodes.length.times do |i|
  min_cost_flow.add_arc_with_capacity_and_unit_cost(
    start_nodes[i], end_nodes[i], capacities[i], costs[i]
  )
end

supplies.length.times do |i|
  min_cost_flow.set_node_supply(i, supplies[i])
end

# invoke the solver
if min_cost_flow.solve == :optimal
  puts "Total cost = #{min_cost_flow.optimal_cost}"
  puts
  min_cost_flow.num_arcs.times do |arc|
    if min_cost_flow.tail(arc) != source && min_cost_flow.head(arc) != sink
      if min_cost_flow.flow(arc) > 0
        puts "Worker %d assigned to task %d.  Cost = %d" % [
          min_cost_flow.tail(arc),
          min_cost_flow.head(arc),
          min_cost_flow.unit_cost(arc)
        ]
      end
    end
  end
else
  puts "There was an issue with the min cost flow input."
end

Scheduling

Employee Scheduling

Guide

# define the data
num_nurses = 4
num_shifts = 3
num_days = 3
all_nurses = num_nurses.times.to_a
all_shifts = num_shifts.times.to_a
all_days = num_days.times.to_a

# create the variables
model = ORTools::CpModel.new

shifts = {}
all_nurses.each do |n|
  all_days.each do |d|
    all_shifts.each do |s|
      shifts[[n, d, s]] = model.new_bool_var("shift_n%id%is%i" % [n, d, s])
    end
  end
end

# assign nurses to shifts
all_days.each do |d|
  all_shifts.each do |s|
    model.add(model.sum(all_nurses.map { |n| shifts[[n, d, s]] }) == 1)
  end
end

all_nurses.each do |n|
  all_days.each do |d|
    model.add(model.sum(all_shifts.map { |s| shifts[[n, d, s]] }) <= 1)
  end
end

# assign shifts evenly
min_shifts_per_nurse = (num_shifts * num_days) / num_nurses
max_shifts_per_nurse = min_shifts_per_nurse + 1
all_nurses.each do |n|
  num_shifts_worked = model.sum(all_days.flat_map { |d| all_shifts.map { |s| shifts[[n, d, s]] } })
  model.add(num_shifts_worked >= min_shifts_per_nurse)
  model.add(num_shifts_worked <= max_shifts_per_nurse)
end

# create a printer
class NursesPartialSolutionPrinter < ORTools::CpSolverSolutionCallback
  attr_reader :solution_count

  def initialize(shifts, num_nurses, num_days, num_shifts, sols)
    super()
    @shifts = shifts
    @num_nurses = num_nurses
    @num_days = num_days
    @num_shifts = num_shifts
    @solutions = sols
    @solution_count = 0
  end

  def on_solution_callback
    if @solutions.include?(@solution_count)
      puts "Solution #{@solution_count}"
      @num_days.times do |d|
        puts "Day #{d}"
        @num_nurses.times do |n|
          working = false
          @num_shifts.times do |s|
            if value(@shifts[[n, d, s]])
              working = true
              puts "  Nurse %i works shift %i" % [n, s]
            end
          end
          unless working
            puts "  Nurse #{n} does not work"
          end
        end
      end
      puts
    end
    @solution_count += 1
  end
end

# call the solver and display the results
solver = ORTools::CpSolver.new
a_few_solutions = 5.times.to_a
solution_printer = NursesPartialSolutionPrinter.new(
  shifts, num_nurses, num_days, num_shifts, a_few_solutions
)
solver.search_for_all_solutions(model, solution_printer)

puts
puts "Statistics"
puts "  - conflicts       : %i" % solver.num_conflicts
puts "  - branches        : %i" % solver.num_branches
puts "  - wall time       : %f s" % solver.wall_time
puts "  - solutions found : %i" % solution_printer.solution_count

The Job Shop Problem

Guide

# create the model
model = ORTools::CpModel.new

jobs_data = [
  [[0, 3], [1, 2], [2, 2]],
  [[0, 2], [2, 1], [1, 4]],
  [[1, 4], [2, 3]]
]

machines_count = 1 + jobs_data.flat_map { |job| job.map { |task| task[0] }  }.max
all_machines = machines_count.times.to_a

# computes horizon dynamically as the sum of all durations
horizon = jobs_data.flat_map { |job| job.map { |task| task[1] }  }.sum

# creates job intervals and add to the corresponding machine lists
all_tasks = {}
machine_to_intervals = Hash.new { |hash, key| hash[key] = [] }

jobs_data.each_with_index do |job, job_id|
  job.each_with_index do |task, task_id|
    machine = task[0]
    duration = task[1]
    suffix = "_%i_%i" % [job_id, task_id]
    start_var = model.new_int_var(0, horizon, "start" + suffix)
    duration_var = model.new_int_var(duration, duration, "duration" + suffix)
    end_var = model.new_int_var(0, horizon, "end" + suffix)
    interval_var = model.new_interval_var(start_var, duration_var, end_var, "interval" + suffix)
    all_tasks[[job_id, task_id]] = {start: start_var, end: end_var, interval: interval_var}
    machine_to_intervals[machine] << interval_var
  end
end

# create and add disjunctive constraints
all_machines.each do |machine|
  model.add_no_overlap(machine_to_intervals[machine])
end

# precedences inside a job
jobs_data.each_with_index do |job, job_id|
  (job.size - 1).times do |task_id|
    model.add(all_tasks[[job_id, task_id + 1]][:start] >= all_tasks[[job_id, task_id]][:end])
  end
end

# makespan objective
obj_var = model.new_int_var(0, horizon, "makespan")
model.add_max_equality(obj_var, jobs_data.map.with_index { |job, job_id| all_tasks[[job_id, job.size - 1]][:end] })
model.minimize(obj_var)

# solve model
solver = ORTools::CpSolver.new
status = solver.solve(model)

# create one list of assigned tasks per machine
assigned_jobs = Hash.new { |hash, key| hash[key] = [] }
jobs_data.each_with_index do |job, job_id|
  job.each_with_index do |task, task_id|
    machine = task[0]
    assigned_jobs[machine] << {
      start: solver.value(all_tasks[[job_id, task_id]][:start]),
      job: job_id,
      index: task_id,
      duration: task[1]
    }
  end
end

# create per machine output lines
output = String.new("")
all_machines.each do |machine|
  # sort by starting time
  assigned_jobs[machine].sort_by! { |v| v[:start] }
  sol_line_tasks = "Machine #{machine}: "
  sol_line = "           "

  assigned_jobs[machine].each do |assigned_task|
    name = "job_%i_%i" % [assigned_task[:job], assigned_task[:index]]
    # add spaces to output to align columns
    sol_line_tasks += "%-10s" % name
    start = assigned_task[:start]
    duration = assigned_task[:duration]
    sol_tmp = "[%i,%i]" % [start, start + duration]
    # add spaces to output to align columns
    sol_line += "%-10s" % sol_tmp
  end

  sol_line += "\n"
  sol_line_tasks += "\n"
  output += sol_line_tasks
  output += sol_line
end

# finally print the solution found
puts "Optimal Schedule Length: %i" % solver.objective_value
puts output

Other Examples

Sudoku

Example

# create the model
model = ORTools::CpModel.new

cell_size = 3
line_size = cell_size**2
line = (0...line_size).to_a
cell = (0...cell_size).to_a

initial_grid = [
  [0, 6, 0, 0, 5, 0, 0, 2, 0],
  [0, 0, 0, 3, 0, 0, 0, 9, 0],
  [7, 0, 0, 6, 0, 0, 0, 1, 0],
  [0, 0, 6, 0, 3, 0, 4, 0, 0],
  [0, 0, 4, 0, 7, 0, 1, 0, 0],
  [0, 0, 5, 0, 9, 0, 8, 0, 0],
  [0, 4, 0, 0, 0, 1, 0, 0, 6],
  [0, 3, 0, 0, 0, 8, 0, 0, 0],
  [0, 2, 0, 0, 4, 0, 0, 5, 0]
]

grid = {}
line.each do |i|
  line.each do |j|
    grid[[i, j]] = model.new_int_var(1, line_size, "grid %i %i" % [i, j])
  end
end

# all different on rows
line.each do |i|
  model.add_all_different(line.map { |j| grid[[i, j]] })
end

# all different on columns
line.each do |j|
  model.add_all_different(line.map { |i| grid[[i, j]] })
end

# all different on cells
cell.each do |i|
  cell.each do |j|
    one_cell = []
    cell.each do |di|
      cell.each do |dj|
        one_cell << grid[[i * cell_size + di, j * cell_size + dj]]
      end
    end
    model.add_all_different(one_cell)
  end
end

# initial values
line.each do |i|
  line.each do |j|
    if initial_grid[i][j] != 0
      model.add(grid[[i, j]] == initial_grid[i][j])
    end
  end
end

# solve and print solution
solver = ORTools::CpSolver.new
status = solver.solve(model)
if status == :optimal
  line.each do |i|
    p line.map { |j| solver.value(grid[[i, j]]) }
  end
end

Wedding Seating Chart

Example

# From
# Meghan L. Bellows and J. D. Luc Peterson
# "Finding an optimal seating chart for a wedding"
# https://www.improbable.com/news/2012/Optimal-seating-chart.pdf
# https://www.improbable.com/2012/02/12/finding-an-optimal-seating-chart-for-a-wedding
#
# Every year, millions of brides (not to mention their mothers, future
# mothers-in-law, and occasionally grooms) struggle with one of the
# most daunting tasks during the wedding-planning process: the
# seating chart. The guest responses are in, banquet hall is booked,
# menu choices have been made. You think the hard parts are over,
# but you have yet to embark upon the biggest headache of them all.
# In order to make this process easier, we present a mathematical
# formulation that models the seating chart problem. This model can
# be solved to find the optimal arrangement of guests at tables.
# At the very least, it can provide a starting point and hopefully
# minimize stress and arguments.
#
# Adapted from
# https://github.com/google/or-tools/blob/stable/examples/python/wedding_optimal_chart_sat.py

# Easy problem (from the paper)
# num_tables = 2
# table_capacity = 10
# min_known_neighbors = 1

# Slightly harder problem (also from the paper)
num_tables = 5
table_capacity = 4
min_known_neighbors = 1

# Connection matrix: who knows who, and how strong
# is the relation
c = [
  [1, 50, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
  [50, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
  [1, 1, 1, 50, 1, 1, 1, 1, 10, 0, 0, 0, 0, 0, 0, 0, 0],
  [1, 1, 50, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
  [1, 1, 1, 1, 1, 50, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
  [1, 1, 1, 1, 50, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
  [1, 1, 1, 1, 1, 1, 1, 50, 1, 0, 0, 0, 0, 0, 0, 0, 0],
  [1, 1, 1, 1, 1, 1, 50, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
  [1, 1, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 50, 1, 1, 1, 1, 1, 1],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 1, 1, 1, 1, 1, 1, 1],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1]
]

# Names of the guests. B: Bride side, G: Groom side
names = [
  "Deb (B)", "John (B)", "Martha (B)", "Travis (B)", "Allan (B)",
  "Lois (B)", "Jayne (B)", "Brad (B)", "Abby (B)", "Mary Helen (G)",
  "Lee (G)", "Annika (G)", "Carl (G)", "Colin (G)", "Shirley (G)",
  "DeAnn (G)", "Lori (G)"
]

num_guests = c.size

all_tables = num_tables.times.to_a
all_guests = num_guests.times.to_a

# create the cp model
model = ORTools::CpModel.new

# decision variables
seats = {}
all_tables.each do |t|
  all_guests.each do |g|
    seats[[t, g]] = model.new_bool_var("guest %i seats on table %i" % [g, t])
  end
end

pairs = all_guests.combination(2)

colocated = {}
pairs.each do |g1, g2|
  colocated[[g1, g2]] = model.new_bool_var("guest %i seats with guest %i" % [g1, g2])
end

same_table = {}
pairs.each do |g1, g2|
  all_tables.each do |t|
    same_table[[g1, g2, t]] = model.new_bool_var("guest %i seats with guest %i on table %i" % [g1, g2, t])
  end
end

# Objective
model.maximize(model.sum((num_guests - 1).times.flat_map { |g1| (g1 + 1).upto(num_guests - 1).select { |g2| c[g1][g2] > 0 }.map { |g2| colocated[[g1, g2]] * c[g1][g2] } }))

#
# Constraints
#

# Everybody seats at one table.
all_guests.each do |g|
  model.add(model.sum(all_tables.map { |t| seats[[t, g]] }) == 1)
end

# Tables have a max capacity.
all_tables.each do |t|
  model.add(model.sum(all_guests.map { |g| seats[[t, g]] }) <= table_capacity)
end

# Link colocated with seats
pairs.each do |g1, g2|
  all_tables.each do |t|
    # Link same_table and seats.
    model.add_bool_or([seats[[t, g1]].not, seats[[t, g2]].not, same_table[[g1, g2, t]]])
    model.add_implication(same_table[[g1, g2, t]], seats[[t, g1]])
    model.add_implication(same_table[[g1, g2, t]], seats[[t, g2]])
  end

  # Link colocated and same_table.
  model.add(model.sum(all_tables.map { |t| same_table[[g1, g2, t]] }) == colocated[[g1, g2]])
end

# Min known neighbors rule.
all_guests.each do |g|
  model.add(
    model.sum(
      (g + 1).upto(num_guests - 1).
      select { |g2| c[g][g2] > 0 }.
      product(all_tables).
      map { |g2, t| same_table[[g, g2, t]] }
    ) +
    model.sum(
      g.times.
      select { |g1| c[g1][g] > 0 }.
      product(all_tables).
      map { |g1, t| same_table[[g1, g, t]] }
    ) >= min_known_neighbors
  )
end

# Symmetry breaking. First guest seats on the first table.
model.add(seats[[0, 0]] == 1)

# Solve model
solver = ORTools::CpSolver.new
solution_printer = WeddingChartPrinter.new(seats, names, num_tables, num_guests)
solver.solve(model, solution_printer)

puts "Statistics"
puts "  - conflicts    : %i" % solver.num_conflicts
puts "  - branches     : %i" % solver.num_branches
puts "  - wall time    : %f s" % solver.wall_time
puts "  - num solutions: %i" % solution_printer.num_solutions

Set Partitioning

Example

# A set partitioning model of a wedding seating problem
# Authors: Stuart Mitchell 2009

max_tables = 5
max_table_size = 4
guests = %w(A B C D E F G I J K L M N O P Q R)

# Find the happiness of the table
# by calculating the maximum distance between the letters
def happiness(table)
  (table[0].ord - table[-1].ord).abs
end

# create list of all possible tables
possible_tables = []
(1..max_table_size).each do |i|
  possible_tables += guests.combination(i).to_a
end

solver = ORTools::Solver.new("CBC")

# create a binary variable to state that a table setting is used
x = {}
possible_tables.each do |table|
  x[table] = solver.int_var(0, 1, "table #{table.join(", ")}")
end

solver.minimize(possible_tables.sum { |table| x[table] * happiness(table) })

# specify the maximum number of tables
solver.add(x.values.sum <= max_tables)

# a guest must seated at one and only one table
guests.each do |guest|
  tables_with_guest = possible_tables.select { |table| table.include?(guest) }
  solver.add(tables_with_guest.sum { |table| x[table] } == 1)
end

status = solver.solve

puts "The chosen tables are out of a total of %s:" % possible_tables.size
possible_tables.each do |table|
  if x[table].solution_value == 1
    p table
  end
end

History

View the changelog

Contributing

Everyone is encouraged to help improve this project. Here are a few ways you can help:

To get started with development:

git clone https://github.com/ankane/or-tools-ruby.git
cd or-tools-ruby
bundle install
bundle exec rake compile
bundle exec rake test

Resources

or-tools-ruby's People

Contributors

ankane avatar braindeaf avatar elliot-laster-ezc avatar johnnymo87 avatar mtsmfm avatar sagotsky avatar starchow avatar thomasklemm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

or-tools-ruby's Issues

adding support for SatParameters.random_seed?

Thank you for this delightful library. It has been a joy to use the CP model and solver.

I am trying to set random_seed as solver.parameters.random_seed, but parameters.methods indicates that random_seed= is not present.

Am I missing something? Or perhaps would it be possible to add it?

For reference, here is the field on the SatParameters proto definition.

Not compatible with or-tools v9.5?

Hi @ankane thanks for all your support on this gem.

The google or-tools team released version 9.5, and homebrew picked it up, and since homebrew only has the latest version of or-tools, there's no way to get prior version from it. And I think people need a prior version to use this library? (This may be only be true for people using Apple Silicon computers, not sure.)

Here's the error I see when my colleague tries to use the latest version (0.9.0) of this gem with or-tools v9.5.

Installing or-tools 0.9.0 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/or-tools-0.9.0/ext/or-tools
/Users/tapesh.nagarwal/.rbenv/versions/2.7.5/bin/ruby -I /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/site_ruby/2.7.0 extconf.rb
--with-or-tools-dir\=/opt/homebrew
checking for rice/rice.hpp in /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/rice-4.0.4/include... yes
checking for -lc++... yes
checking for -lortools... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/Users/tapesh.nagarwal/.rbenv/versions/2.7.5/bin/$(RUBY_BASE_NAME)
	--with-c++-dir
	--without-c++-dir
	--with-c++-include
	--without-c++-include=${c++-dir}/include
	--with-c++-lib
	--without-c++-lib=${c++-dir}/lib
	--with-c++lib
	--without-c++lib
	--with-or-tools-dir
	--with-or-tools-include
	--without-or-tools-include=${or-tools-dir}/include
	--with-or-tools-lib
	--without-or-tools-lib=${or-tools-dir}/lib
	--with-ortools-dir
	--without-ortools-dir
	--with-ortools-include
	--without-ortools-include=${ortools-dir}/include
	--with-ortools-lib
	--without-ortools-lib=${ortools-dir}/lib
	--with-ortoolslib
	--without-ortoolslib
extconf.rb:30:in `<main>': OR-Tools not found (RuntimeError)

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/extensions/arm64-darwin-21/2.7.0/or-tools-0.9.0/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/or-tools-0.9.0 for inspection.
Results logged to /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/extensions/arm64-darwin-21/2.7.0/or-tools-0.9.0/gem_make.out

  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/site_ruby/2.7.0/rubygems/ext/builder.rb:102:in `run'
  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/site_ruby/2.7.0/rubygems/ext/ext_conf_builder.rb:28:in `build'
  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/site_ruby/2.7.0/rubygems/ext/builder.rb:171:in `build_extension'
  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/site_ruby/2.7.0/rubygems/ext/builder.rb:205:in `block in build_extensions'
  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/site_ruby/2.7.0/rubygems/ext/builder.rb:202:in `each'
  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/site_ruby/2.7.0/rubygems/ext/builder.rb:202:in `build_extensions'
  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/site_ruby/2.7.0/rubygems/installer.rb:843:in `build_extensions'
  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.7/lib/bundler/rubygems_gem_installer.rb:71:in `build_extensions'
  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.7/lib/bundler/rubygems_gem_installer.rb:28:in `install'
  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.7/lib/bundler/source/rubygems.rb:204:in `install'
  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.7/lib/bundler/installer/gem_installer.rb:54:in `install'
  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.7/lib/bundler/installer/gem_installer.rb:16:in `install_from_spec'
  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.7/lib/bundler/installer/parallel_installer.rb:186:in `do_install'
/Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.7/lib/bundler/installer/parallel_installer.rb:177:in `block in
worker_pool'
  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.7/lib/bundler/worker.rb:62:in `apply_func'
  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.7/lib/bundler/worker.rb:57:in `block in process_queue'
  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.7/lib/bundler/worker.rb:54:in `loop'
  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.7/lib/bundler/worker.rb:54:in `process_queue'
  /Users/tapesh.nagarwal/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.3.7/lib/bundler/worker.rb:91:in `block (2 levels) in create_threads'

An error occurred while installing or-tools (0.9.0), and Bundler cannot continue.

In Gemfile:
  or-tools

We're working around this by building or-tools 9.4 from source, which we have no problems with when using this gem.

Service times for VRP PD/TW problem.

I'm trying to figure out how to add service times to a VRP problem with PD/TW constraints.

I can simply add service time to the transit time in my transit cost callback. But that's tacky.

Is there a way to register a unary callback in addition to the regular transit callback? They should increment the time for that vehicle so eg: Vehicle leaves an hour later from that location after servicing for 60 minutes.

In ideal circumstances I'd like to add multiple callbacks - One for pickup labour, one for delivery labour, one for service time. Is there a way to do this with OR-tools? Am I missing something?

Plan

Ideas

  • Add support for DoubleLinearExpr
  • Move SAT linear expression building to Ruby (see cp_model.py)

More higher level interfaces

  • Hourly scheduler - people needed per hour as input - output could be shifts or assignments (if availability is given)
  • Vehicle routing
  • Planting schedule

Print model?

In the or-tools c++ interface there is solver.ExportModelAsLpFormat to print out model details. This would be useful for debug purposes if it were exposed on ruby land. BTW thanks for the good work on this project.

Fails to build with Manjaro Linux 24.0.6

When installing this gem into a Manjaro Linux, I get an ERROR: Failed to build gem native extension.

Specs

  • Command: gem install or-tools
  • Ruby: ruby 3.3.4 (2024-07-09 revision be1089c8ec) [x86_64-linux]
  • OR Tools: v0.12.0
  • OS: Manjaro Linux 24.0.6

Specific Error

/home/dev/.rvm/gems/ruby-3.3.4@guard/gems/or-tools-0.12.0/ext/or-tools/vendor.rb:58:in `<top (required)>': Binary installation not available for this platform: manjaro  x86_64 (RuntimeError)

Full Error

> gem install or-tools
Building native extensions. This could take a while...
ERROR:  Error installing or-tools:
        ERROR: Failed to build gem native extension.

    current directory: /home/dev/.rvm/gems/ruby-3.3.4@guard/gems/or-tools-0.12.0/ext/or-tools
/home/dev/.rvm/rubies/ruby-3.3.4/bin/ruby extconf.rb
checking for rice/rice.hpp in /home/dev/.rvm/gems/ruby-3.3.4@guard/gems/rice-4.3.1/include... yes
checking for -lstdc++fs... yes
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
        --with-opt-dir
        --without-opt-dir
        --with-opt-include=${opt-dir}/include
        --without-opt-include
        --with-opt-lib=${opt-dir}/lib
        --without-opt-lib
        --with-make-prog
        --without-make-prog
        --srcdir=.
        --curdir
        --ruby=/home/rodrigo/.rvm/rubies/ruby-3.3.4/bin/$(RUBY_BASE_NAME)
        --with-stdc++fs-dir
        --without-stdc++fs-dir
        --with-stdc++fs-include=${stdc++fs-dir}/include
        --without-stdc++fs-include
        --with-stdc++fs-lib=${stdc++fs-dir}/lib
        --without-stdc++fs-lib
        --with-stdc++fslib
        --without-stdc++fslib
        --with-or-tools-dir
        --without-or-tools-dir
        --with-or-tools-include=${or-tools-dir}/include
        --without-or-tools-include
        --with-or-tools-lib=${or-tools-dir}/lib
        --without-or-tools-lib
/home/dev/.rvm/gems/ruby-3.3.4@guard/gems/or-tools-0.12.0/ext/or-tools/vendor.rb:58:in `<top (required)>': Binary installation not available for this platform: manjaro  x86_64 (RuntimeError)

Build the OR-Tools C++ library from source, then run:
bundle config build.or-tools --with-or-tools-dir=/path/to/or-tools

        from extconf.rb:15:in `require_relative'
        from extconf.rb:15:in `<main>'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /home/dev/.rvm/gems/ruby-3.3.4@guard/extensions/x86_64-linux/3.3.0/or-tools-0.12.0/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /home/dev/.rvm/gems/ruby-3.3.4@guard/gems/or-tools-0.12.0 for inspection.
Results logged to /home/dev/.rvm/gems/ruby-3.3.4@guard/extensions/x86_64-linux/3.3.0/or-tools-0.12.0/gem_make.out

Fails to compile on Ubuntu 20.04

ruby-or-tools v. 0.8.1
Ubuntu 20.04

Based on https://github.com/ankane/or-tools-ruby/blob/master/ext/or-tools/vendor.rb#L31 I took it that a binary distribution for Ubuntu 20.04 was available and that this would be downloaded.

The output from install is (for me) not very clear - not sure what the problem is:

# gem install or-tools
Building native extensions. This could take a while...
ERROR:  Error installing or-tools:
	ERROR: Failed to build gem native extension.

    current directory: /root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/or-tools-0.8.1/ext/or-tools
/root/.rbenv/versions/3.1.2/bin/ruby -I /root/.rbenv/versions/3.1.2/lib/ruby/3.1.0 -r ./siteconf20220829-20055-lxg97w.rb extconf.rb
checking for rice/rice.hpp in /root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include... yes
checking for -lstdc++... yes
checking for -lortools... yes
creating Makefile

current directory: /root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/or-tools-0.8.1/ext/or-tools
make DESTDIR\= clean

current directory: /root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/or-tools-0.8.1/ext/or-tools
make DESTDIR\=
compiling assignment.cpp
compiling bin_packing.cpp
In file included from ext.h:3,
                 from bin_packing.cpp:3:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<long int, std::allocator<long int> >::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = Rice::stl::VectorHelper<T>::define_copyable_methods() [with T = std::vector<long int, std::allocator<long int> >]::<lambda(std::vector<long int, std::allocator<long int> >&)>; bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
At global scope:
cc1plus: warning: unrecognized command line option ‘-Wno-shorten-64-to-32’
compiling constraint.cpp
In file included from ext.h:3,
                 from constraint.cpp:4:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<operations_research::sat::IntVar>::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = Rice::stl::VectorHelper<T>::define_copyable_methods() [with T = std::vector<operations_research::sat::IntVar>]::<lambda(std::vector<operations_research::sat::IntVar>&)>; bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<operations_research::sat::LinearExpr>::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = Rice::stl::VectorHelper<T>::define_copyable_methods() [with T = std::vector<operations_research::sat::LinearExpr>]::<lambda(std::vector<operations_research::sat::LinearExpr>&)>; bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<operations_research::sat::IntervalVar>::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = Rice::stl::VectorHelper<T>::define_copyable_methods() [with T = std::vector<operations_research::sat::IntervalVar>]::<lambda(std::vector<operations_research::sat::IntervalVar>&)>; bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<operations_research::sat::BoolVar>::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = Rice::stl::VectorHelper<T>::define_copyable_methods() [with T = std::vector<operations_research::sat::BoolVar>]::<lambda(std::vector<operations_research::sat::BoolVar>&)>; bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
At global scope:
cc1plus: warning: unrecognized command line option ‘-Wno-shorten-64-to-32’
compiling ext.cpp
compiling linear.cpp
compiling network_flows.cpp
compiling routing.cpp
In file included from ext.h:3,
                 from routing.cpp:4:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<gtl::IntType<operations_research::RoutingNodeIndex_tag_, int> >::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = Rice::stl::VectorHelper<T>::define_copyable_methods() [with T = std::vector<gtl::IntType<operations_research::RoutingNodeIndex_tag_, int> >]::<lambda(std::vector<gtl::IntType<operations_research::RoutingNodeIndex_tag_, int> >&)>; bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<long int>::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<std::vector<long int> >::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<int>::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = Rice::stl::VectorHelper<T>::define_copyable_methods() [with T = std::vector<std::__cxx11::basic_string<char> >]::<lambda(std::vector<std::__cxx11::basic_string<char> >&)>; bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<std::__cxx11::basic_string<char> >::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<gtl::IntType<operations_research::RoutingDisjunctionIndex_tag_, int> >::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = Rice::stl::VectorHelper<T>::define_copyable_methods() [with T = std::vector<gtl::IntType<operations_research::RoutingDisjunctionIndex_tag_, int> >]::<lambda(std::vector<gtl::IntType<operations_research::RoutingDisjunctionIndex_tag_, int> >&)>; bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
g++: fatal error: Killed signal terminated program cc1plus
compilation terminated.
make: *** [Makefile:238: routing.o] Error 1

make failed, exit code 2

Gem files will remain installed in /root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/or-tools-0.8.1 for inspection.
Results logged to /root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/extensions/x86_64-linux/3.1.0/or-tools-0.8.1/gem_make.out
s01om01# cat /root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/extensions/x86_64-linux/3.1.0/or-tools-0.8.1/gem_make.out
current directory: /root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/or-tools-0.8.1/ext/or-tools
/root/.rbenv/versions/3.1.2/bin/ruby -I /root/.rbenv/versions/3.1.2/lib/ruby/3.1.0 -r ./siteconf20220829-20055-lxg97w.rb extconf.rb
checking for rice/rice.hpp in /root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include... yes
checking for -lstdc++... yes
checking for -lortools... yes
creating Makefile

current directory: /root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/or-tools-0.8.1/ext/or-tools
make DESTDIR\= clean

current directory: /root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/or-tools-0.8.1/ext/or-tools
make DESTDIR\=
compiling assignment.cpp
compiling bin_packing.cpp
In file included from ext.h:3,
                 from bin_packing.cpp:3:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<long int, std::allocator<long int> >::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = Rice::stl::VectorHelper<T>::define_copyable_methods() [with T = std::vector<long int, std::allocator<long int> >]::<lambda(std::vector<long int, std::allocator<long int> >&)>; bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
At global scope:
cc1plus: warning: unrecognized command line option ‘-Wno-shorten-64-to-32’
compiling constraint.cpp
In file included from ext.h:3,
                 from constraint.cpp:4:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<operations_research::sat::IntVar>::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = Rice::stl::VectorHelper<T>::define_copyable_methods() [with T = std::vector<operations_research::sat::IntVar>]::<lambda(std::vector<operations_research::sat::IntVar>&)>; bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<operations_research::sat::LinearExpr>::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = Rice::stl::VectorHelper<T>::define_copyable_methods() [with T = std::vector<operations_research::sat::LinearExpr>]::<lambda(std::vector<operations_research::sat::LinearExpr>&)>; bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<operations_research::sat::IntervalVar>::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = Rice::stl::VectorHelper<T>::define_copyable_methods() [with T = std::vector<operations_research::sat::IntervalVar>]::<lambda(std::vector<operations_research::sat::IntervalVar>&)>; bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<operations_research::sat::BoolVar>::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = Rice::stl::VectorHelper<T>::define_copyable_methods() [with T = std::vector<operations_research::sat::BoolVar>]::<lambda(std::vector<operations_research::sat::BoolVar>&)>; bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
At global scope:
cc1plus: warning: unrecognized command line option ‘-Wno-shorten-64-to-32’
compiling ext.cpp
compiling linear.cpp
compiling network_flows.cpp
compiling routing.cpp
In file included from ext.h:3,
                 from routing.cpp:4:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<gtl::IntType<operations_research::RoutingNodeIndex_tag_, int> >::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = Rice::stl::VectorHelper<T>::define_copyable_methods() [with T = std::vector<gtl::IntType<operations_research::RoutingNodeIndex_tag_, int> >]::<lambda(std::vector<gtl::IntType<operations_research::RoutingNodeIndex_tag_, int> >&)>; bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<long int>::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<std::vector<long int> >::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<int>::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = Rice::stl::VectorHelper<T>::define_copyable_methods() [with T = std::vector<std::__cxx11::basic_string<char> >]::<lambda(std::vector<std::__cxx11::basic_string<char> >&)>; bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<std::__cxx11::basic_string<char> >::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = void (std::vector<gtl::IntType<operations_research::RoutingDisjunctionIndex_tag_, int> >::*)(long unsigned int); bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp: In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with Function_T = Rice::stl::VectorHelper<T>::define_copyable_methods() [with T = std::vector<gtl::IntType<operations_research::RoutingDisjunctionIndex_tag_, int> >]::<lambda(std::vector<gtl::IntType<operations_research::RoutingDisjunctionIndex_tag_, int> >&)>; bool IsMethod = true]’:
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:46: warning: function may return address of local variable [-Wreturn-local-addr]
 3565 |       return From_Ruby<Self_T>().convert(self);
      |                                              ^
/root/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include/rice/rice.hpp:3565:14: note: declared here
 3565 |       return From_Ruby<Self_T>().convert(self);
      |              ^~~~~~~~~~~~~~~~~~~
g++: fatal error: Killed signal terminated program cc1plus
compilation terminated.
make: *** [Makefile:238: routing.o] Error 1

Solver.solve throws stack level too deep error when run in a web server on a mac

Hi @ankane, first of all, thanks for the great work you're doing here and elsewhere to improve the machine learning ecosystem for ruby.

I'm having a problem where my code using this gem throws a stack level too deep error on solver.solve when I run it in a web server on a Mac. I've set up a GitHub repo to demonstrate.

$ ruby run_in_web_server.rb

... server starts ...
... I visit localhost:4567 ...

2022-02-07 12:26:26 - SystemStackError - stack level too deep:
        /Users/jonathan.mohrbacher/Code/stack-overflow/lib/demo/solver.rb:142:in `solve'
        /Users/jonathan.mohrbacher/Code/stack-overflow/lib/demo/solver.rb:142:in `run_solver'
        /Users/jonathan.mohrbacher/Code/stack-overflow/lib/demo/solver.rb:43:in `solve'
        /Users/jonathan.mohrbacher/Code/stack-overflow/lib/demo/solver.rb:23:in `solve'
        /Users/jonathan.mohrbacher/Code/stack-overflow/lib/demo.rb:18:in `run'
        run_in_web_server.rb:10:in `block in <main>'
        ... sinatra-specific stack trace ...

I've tried the following experiments:

  • I ran it on a Mac (M1), didn't work ❌
  • I ran it on a Mac (M1) with ruby 2.7 rather than ruby 3.1, didn't work ❌
  • I ran it on a Mac (M1) with thin instead of puma, and then with webrick instead of puma, didn't work ❌
  • I ran it on a Mac (Intel), didn't work ❌
  • I ran it on a Mac (M1) in a linux/arm64 docker container, did work ✅
  • I ran it on Ubuntu (Intel), did work ✅
  • I ran it on Ubuntu (Intel) in a linux/x86_64 docker container, did work ✅
  • I ran it without a web server (ruby run_in_terminal.rb) on all three of these computers, did work ✅

So I can only reproduce this problem when running outside of docker on a Mac, and only when running it with a web server. On these Macs, I installed or-tools with Homebrew.

When I hit the error on the Mac with the Intel chip, it seems like ruby crashed because it gave me a large crash report, attached below.

crash.txt
ruby-2022-02-08-000648.txt

Cannot deploy to Ubuntu 18 with latest OR-Tools and 0.6.3 gem

Our latest deploy appears to have blown up.

gcc 8
OR-Tools 0.9.3
or-tools-ruby 0.6.3

Can you give us any hints? Many thanks :)

make "DESTDIR="
compiling assignment.cpp
cc1plus: warning: command line option ‘-Wdeclaration-after-statement’ is valid
for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wimplicit-function-declaration’ is valid
for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wimplicit-int’ is valid for C/ObjC but
not for C++
cc1plus: warning: unrecognized command line option ‘-Wno-shorten-64-to-32’
cc1plus: warning: unrecognized command line option ‘-Wno-self-assign’
cc1plus: warning: unrecognized command line option ‘-Wno-parentheses-equality’
cc1plus: warning: unrecognized command line option
‘-Wno-constant-logical-operand’
compiling bin_packing.cpp
cc1plus: warning: command line option ‘-Wdeclaration-after-statement’ is valid
for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wimplicit-function-declaration’ is valid
for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wimplicit-int’ is valid for C/ObjC but
not for C++
In file included from ext.h:3,
                 from bin_packing.cpp:3:
/home/deploy/rostering/shared/bundle/ruby/2.6.0/gems/rice-4.0.3/include/rice/rice.hpp:
In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T
Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with
Function_T = void (std::vector<long int, std::allocator<long int> >::*)(long
unsigned int); bool IsMethod = true]’:
/home/deploy/rostering/shared/bundle/ruby/2.6.0/gems/rice-4.0.3/include/rice/rice.hpp:3564:46:
warning: function may return address of local variable [-Wreturn-local-addr]
       return From_Ruby<Self_T>().convert(self);
                                              ^
/home/deploy/rostering/shared/bundle/ruby/2.6.0/gems/rice-4.0.3/include/rice/rice.hpp:3564:14:
note: declared here
       return From_Ruby<Self_T>().convert(self);
              ^~~~~~~~~~~~~~~~~~~
/home/deploy/rostering/shared/bundle/ruby/2.6.0/gems/rice-4.0.3/include/rice/rice.hpp:
In function ‘Rice::detail::NativeFunction<Function_T, IsMethod>::Self_T
Rice::detail::NativeFunction<Function_T, IsMethod>::getSelf(VALUE) [with
Function_T = Rice::stl::VectorHelper<T>::define_copyable_methods() [with T =
std::vector<long int, std::allocator<long int> >]::<lambda(std::vector<long int,
std::allocator<long int> >&)>; bool IsMethod = true]’:
/home/deploy/rostering/shared/bundle/ruby/2.6.0/gems/rice-4.0.3/include/rice/rice.hpp:3564:46:
warning: function may return address of local variable [-Wreturn-local-addr]
       return From_Ruby<Self_T>().convert(self);
                                              ^
/home/deploy/rostering/shared/bundle/ruby/2.6.0/gems/rice-4.0.3/include/rice/rice.hpp:3564:14:
note: declared here
       return From_Ruby<Self_T>().convert(self);
              ^~~~~~~~~~~~~~~~~~~
At global scope:
cc1plus: warning: unrecognized command line option ‘-Wno-shorten-64-to-32’
cc1plus: warning: unrecognized command line option ‘-Wno-self-assign’
cc1plus: warning: unrecognized command line option ‘-Wno-parentheses-equality’
cc1plus: warning: unrecognized command line option
‘-Wno-constant-logical-operand’
compiling constraint.cpp
cc1plus: warning: command line option ‘-Wdeclaration-after-statement’ is valid
for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wimplicit-function-declaration’ is valid
for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wimplicit-int’ is valid for C/ObjC but
not for C++
constraint.cpp: In member function ‘operations_research::sat::LinearExpr
Rice::detail::From_Ruby<operations_research::sat::LinearExpr>::convert(VALUE)’:
constraint.cpp:60:18: error: ‘class operations_research::sat::LinearExpr’ has no
member named ‘AddTerm’; did you mean ‘Term’?
             expr.AddTerm(From_Ruby<BoolVar>().convert(var.value()), coeff);
                  ^~~~~~~
                  Term
constraint.cpp:62:18: error: ‘class operations_research::sat::LinearExpr’ has no
member named ‘AddConstant’; did you mean ‘IsConstant’?
expr.AddConstant(From_Ruby<int64_t>().convert(var.value()) *
coeff);
                  ^~~~~~~~~~~
                  IsConstant
constraint.cpp:64:18: error: ‘class operations_research::sat::LinearExpr’ has no
member named ‘AddTerm’; did you mean ‘Term’?
             expr.AddTerm(From_Ruby<IntVar>().convert(var.value()), coeff);
                  ^~~~~~~
                  Term
constraint.cpp: In lambda function:
constraint.cpp:262:21: error: ‘class operations_research::sat::CpModelBuilder’
has no member named ‘AddLinMinEquality’; did you mean ‘AddMinEquality’?
         return self.AddLinMinEquality(target, exprs);
                     ^~~~~~~~~~~~~~~~~
                     AddMinEquality
constraint.cpp: In lambda function:
constraint.cpp:272:21: error: ‘class operations_research::sat::CpModelBuilder’
has no member named ‘AddLinMaxEquality’; did you mean ‘AddMaxEquality’?
         return self.AddLinMaxEquality(target, exprs);
                     ^~~~~~~~~~~~~~~~~
                     AddMaxEquality
At global scope:
cc1plus: warning: unrecognized command line option ‘-Wno-shorten-64-to-32’
cc1plus: warning: unrecognized command line option ‘-Wno-self-assign’
cc1plus: warning: unrecognized command line option ‘-Wno-parentheses-equality’
cc1plus: warning: unrecognized command line option
‘-Wno-constant-logical-operand’
Makefile:236: recipe for target 'constraint.o' failed
make: *** [constraint.o] Error 1

make failed, exit code 2

Gem files will remain installed in
/home/deploy/rostering/shared/bundle/ruby/2.6.0/gems/or-tools-0.6.3 for
inspection.
Results logged to
/home/deploy/rostering/shared/bundle/ruby/2.6.0/extensions/x86_64-linux/2.6.0/or-tools-0.6.3/gem_make.out

/home/deploy/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/builder.rb:99:in
`run'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/builder.rb:51:in
`block in make'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/builder.rb:43:in
`each'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/builder.rb:43:in
`make'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/ext_conf_builder.rb:62:in
`block in build'
  /home/deploy/.rbenv/versions/2.6.6/lib/ruby/2.6.0/tempfile.rb:295:in `open'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/ext_conf_builder.rb:29:in
`build'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/builder.rb:185:in
`block in build_extension'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/2.6.0/monitor.rb:235:in
`mon_synchronize'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/builder.rb:181:in
`build_extension'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/builder.rb:229:in
`block in build_extensions'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/builder.rb:226:in
`each'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/builder.rb:226:in
`build_extensions'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/installer.rb:830:in
`build_extensions'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.3.8/lib/bundler/rubygems_gem_installer.rb:71:in
`build_extensions'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.3.8/lib/bundler/rubygems_gem_installer.rb:28:in
`install'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.3.8/lib/bundler/source/rubygems.rb:204:in
`install'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.3.8/lib/bundler/installer/gem_installer.rb:54:in
`install'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.3.8/lib/bundler/installer/gem_installer.rb:16:in
`install_from_spec'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.3.8/lib/bundler/installer/parallel_installer.rb:186:in
`do_install'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.3.8/lib/bundler/installer/parallel_installer.rb:177:in
`block in worker_pool'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.3.8/lib/bundler/worker.rb:62:in
`apply_func'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.3.8/lib/bundler/worker.rb:57:in
`block in process_queue'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.3.8/lib/bundler/worker.rb:54:in
`loop'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.3.8/lib/bundler/worker.rb:54:in
`process_queue'
/home/deploy/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.3.8/lib/bundler/worker.rb:91:in
`block (2 levels) in create_threads'

An error occurred while installing or-tools (0.6.3), and Bundler cannot

Add Hint doesn't support Boolean vars.

I have a simple model, with boolean vars for assignment, but it appears that the hint interface only accepts int vars.

Minitest::UnexpectedError: TypeError: Wrong argument type. Expected: ORTools::SatIntVar. Received: ORTools::BoolVar.

Trouble installing on Ubuntu 18.04LTS

Hello,

Not sure what the right way to do this is, but landed here after wrestling with this for a week.

I've used this library before, but don't remember having this problem.

Are there prereqs I need to have installed before this works. When I try to install just by adding the gem, I get this error:

find_header: checking for rice/rice.hpp in /home/ubuntu/.rvm/gems/ruby-3.2.0/gems/rice-4.1.0/include... -------------------- no

LD_LIBRARY_PATH=.:/home/ubuntu/.rvm/rubies/ruby-3.2.0/lib "g++ -o conftest -I/home/ubuntu/.rvm/rubies/ruby-3.2.0/include/ruby-3.2.0/x86_64-linux -I/home/ubuntu/.rvm/rubies/ruby-3.2.0/include/ruby-3.2.0/ruby/backward -I/home/ubuntu/.rvm/rubies/ruby-3.2.0/include/ruby-3.2.0 -I.     conftest.cc  -L. -L/home/ubuntu/.rvm/rubies/ruby-3.2.0/lib -Wl,-rpath,/home/ubuntu/.rvm/rubies/ruby-3.2.0/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed     -Wl,-rpath,'/../lib' -Wl,-rpath,'/../lib' -lruby  -lm -lpthread  -lc"
checked program was:
/* begin */
1: #include "ruby.h"
2: 
3: int main(int argc, char **argv)
4: {
5:   return !!argv[argc];
6: }
/* end */

LD_LIBRARY_PATH=.:/home/ubuntu/.rvm/rubies/ruby-3.2.0/lib "g++ -I/home/ubuntu/.rvm/rubies/ruby-3.2.0/include/ruby-3.2.0/x86_64-linux -I/home/ubuntu/.rvm/rubies/ruby-3.2.0/include/ruby-3.2.0/ruby/backward -I/home/ubuntu/.rvm/rubies/ruby-3.2.0/include/ruby-3.2.0 -I.     -std=c++17   -c conftest.cc"
conftest.cc:3:10: fatal error: rice/rice.hpp: No such file or directory
 #include <rice/rice.hpp>
          ^~~~~~~~~~~~~~~
compilation terminated.
checked program was:
/* begin */
1: #include "ruby.h"
2: 
3: #include <rice/rice.hpp>
/* end */

LD_LIBRARY_PATH=.:/home/ubuntu/.rvm/rubies/ruby-3.2.0/lib "g++ -I/home/ubuntu/.rvm/rubies/ruby-3.2.0/include/ruby-3.2.0/x86_64-linux -I/home/ubuntu/.rvm/rubies/ruby-3.2.0/include/ruby-3.2.0/ruby/backward -I/home/ubuntu/.rvm/rubies/ruby-3.2.0/include/ruby-3.2.0 -I.     -std=c++17  -I/home/ubuntu/.rvm/gems/ruby-3.2.0/gems/rice-4.1.0/include -c conftest.cc"
In file included from conftest.cc:3:0:
/home/ubuntu/.rvm/gems/ruby-3.2.0/gems/rice-4.1.0/include/rice/rice.hpp:1208:10: fatal error: filesystem: No such file or directory
 #include <filesystem>
          ^~~~~~~~~~~~
compilation terminated.
checked program was:
/* begin */
1: #include "ruby.h"
2: 
3: #include <rice/rice.hpp>
/* end */

--------------------

I've tried adding rice "manually" by gem installing and adding to the Gemfile, but nothing seems to work.

Any ideas?

Bob

[VRP] Add add_constant_dimension and set_cumul_var_soft_lower/upper_bound APIs?

The VRP solver is working great. I am respectfully reaching out to request additional API coverage...

  1. I would like to add soft bounds on time dimension of the locations. This API is available in python, where the implementation may look a bit like:
routing.AddDimension(transit_callback_index, 1000, 1000, false, 'Time')
time_dimension = routing.GetDimensionOrDie('Time')
time_dimension.SetCumulVarSoftLowerBound(index, time_window[0], TIME_WINDOW_BOUND_PENALTY)
time_dimension.SetCumulVarSoftUpperBound(index, time_window[1], TIME_WINDOW_BOUND_PENALTY)

ASK: Would it be possible to add set_cumul_var_soft_lower/upper_bound on a mutable_dimension?

  1. I would like to use a constant dimension to count each stop and balance the number of stops between vehicles. While the constant dimension can handle this directly, I've found it beneficial to use soft bounds on the constant dimension. The API is available in python, where the implementation may look a bit like:
    routing.AddConstantDimension(
        1, 
        len(data['time_matrix']) // data['num_vehicles'] + 1,
        True,
        'stop_count')
    count_dimension = routing.GetDimensionOrDie('stop_count')
    num_visit = manager.GetNumberOfNodes() // manager.GetNumberOfVehicles()

    # From https://github.com/google/or-tools/discussions/2430
    for vehicle_id in range(manager.GetNumberOfVehicles()):
        index = routing.End(vehicle_id)
        count_dimension.SetCumulVarSoftLowerBound(index, num_visit, EVEN_WORKLOAD_PENALTY)
        count_dimension.SetCumulVarSoftUpperBound(index, num_visit + 1, EVEN_WORKLOAD_PENALTY)

ASK: Would it be possible to add add_constant_dimension to the routing model? And then, would it be possible to add set_cumul_var_soft_lower/upper_bound on a constant_dimension?

--

PS: FWIW, I tried to fork the repo and update the .cpp header myself. I did not succeed. My C skills have atrophied considerably... :-/. Your help with this is greatly appreciated!

PPS: My apologies for all the python -- I've more experience in Ruby -- but the python wrapper seems to have more comprehensive documentation and API coverage of the C libs.

Process crashing through webserver/sidekiq

Hello @ankane thanks for the gem.

I started using the gem a month ago while trying to solve some heavy optimization processes we needed. Our current code can take up to 30+ minutes to optimize our problem, and using this we reduced that to seconds.

I worked to implement the new solution and everything works perfectly fine, I have specs with rspec, all was great until today.
Today I tried to get all the env running and testing everything end to end.

Our code runs through a REST api, and I started getting stack level too deep errors, and some fatal crashes.
The same exact code works perfectly through console, but it fails through the server, and I also tried sidekiq and had the same crash.

I couldn't think a better way to demostrate this than showing you an actual example. Here's a complete rails app, with the gem. https://share.getcloudapp.com/7Kuov9dv
I also included a zip file with the fatal crashes I got at some point.

If you bundle the app and then open console, running:
Test.run will yield you an array of results or Test.simple will yield :optimal

However, if you run the rails server and open it http://localhost:3000 you will get the stack level too deep error.
As you can see, the TestController is running exactly the same thing Test.run.

If you open http://localhost:3000/simple it will work just fine. By this I am demostrating that I pinpointed exactly what is crashing the code, but it is difficult for me to debug this further as I can't replicate in console, and through the web server (using binding.pry I get super weird issues).

Test.run is basically rerunning the solver several times, but it is resetting the Solver object, as well as my caching hashes.

Another weird behaviour I noticed while debugging is, for instance, in the Test class, if you change Test#combinations and return in the first line return combine of course the server index will work now, as it's doing the same as Test.simple.
However, if you, instead of return, add a byebug there, then open the index, the server will enter byebug and then call from console combine you will get the stack level too deep error.

I apologize if I missed something, or I gave you too much data, this is driving me crazy.

Thanks!

Issues with sums

Not sure this is something that can be fixed just because of the way ruby works. But I've noticed in situations where you might collect a set of vars and sum them to be part of an inequality, if the set is empty the lib fails to create the constraint.

vars = [] # this might not be empty some of the time
model.add(vars.sum <= 2) 

This fails because the sum contains no variables which means that the sum totals to zero, and you end up with a model.add(true).

It does how ever work in the python lib.

Heroku Deployment

Any insight on how to deploy with heroku and not have the slug size get huge?

I suspect some of the native binaries that need to get built are the issue.

Installation/use on Apple M1

Perhaps this is the wrong place but I can't get or-tools the run on new hardware.

I've installed or-tools using homebrew:
brew install or-tools

Then in a test folder, I've done:

bundle init
bundle add or-tools
bundle

This all runs fine, but when I try and run a test ruby file:

require 'or-tools'

locations = [
  {name: "Tokyo", latitude: 35.6762, longitude: 139.6503},
  {name: "Delhi", latitude: 28.7041, longitude: 77.1025}
]

tsp = ORTools::TSP.new(locations)
tsp.route

bundle exec ruby test.rb
Traceback (most recent call last):
3: from test.rb:1:in <main>' 2: from test.rb:1:in require'
1: from /Users/tdegrunt/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/or-tools-0.5.4/lib/or-tools.rb:2:in <top (required)>' /Users/tdegrunt/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/or-tools-0.5.4/lib/or-tools.rb:2:in require': dlopen(/Users/tdegrunt/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/or-tools-0.5.4/lib/or_tools/ext.bundle, 0x0009): symbol not found in flat namespace '__ZN19operations_research10LinearExprC1EPKNS_10MPVariableE' - /Users/tdegrunt/.rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/or-tools-0.5.4/lib/or_tools/ext.bundle (LoadError)

Any thoughts or pointers?

My arch:

arch
arm64

My ruby version:
❯ ruby -v
ruby 2.7.5p203 (2021-11-24 revision f69aeb8314) [arm64-darwin21]

My /opt/homebrew/opt/or-tools:

❯ find .
.
./LICENSE-2.0.txt
./INSTALL_RECEIPT.json
./bin
./bin/fz
./.brew
./.brew/or-tools.rb
./include
./include/ortools_export.h
./include/ortools
./include/ortools/init
./include/ortools/init/init.h
./include/ortools/bop
./include/ortools/bop/bop_parameters.pb.h
./include/ortools/bop/bop_util.h
./include/ortools/bop/integral_solver.h
./include/ortools/bop/bop_base.h
./include/ortools/bop/bop_lns.h
./include/ortools/bop/bop_solution.h
./include/ortools/bop/bop_types.h
./include/ortools/bop/bop_fs.h
./include/ortools/bop/complete_optimizer.h
./include/ortools/bop/bop_portfolio.h
./include/ortools/bop/bop_solver.h
./include/ortools/bop/bop_ls.h
./include/ortools/util
./include/ortools/util/running_stat.h
./include/ortools/util/bitset.h
./include/ortools/util/integer_pq.h
./include/ortools/util/vector_or_function.h
./include/ortools/util/fp_utils.h
./include/ortools/util/rational_approximation.h
./include/ortools/util/tuple_set.h
./include/ortools/util/sigint.h
./include/ortools/util/time_limit.h
./include/ortools/util/permutation.h
./include/ortools/util/file_util.h
./include/ortools/util/monoid_operation_tree.h
./include/ortools/util/logging.h
./include/ortools/util/optional_boolean.pb.h
./include/ortools/util/range_query_function.h
./include/ortools/util/rev.h
./include/ortools/util/sorted_interval_list.h
./include/ortools/util/proto_tools.h
./include/ortools/util/functions_swig_helpers.h
./include/ortools/util/string_array.h
./include/ortools/util/cached_log.h
./include/ortools/util/affine_relation.h
./include/ortools/util/random_engine.h
./include/ortools/util/vector_map.h
./include/ortools/util/zvector.h
./include/ortools/util/sort.h
./include/ortools/util/saturated_arithmetic.h
./include/ortools/util/testing_utils.h
./include/ortools/util/lazy_mutable_copy.h
./include/ortools/util/functions_swig_test_helpers.h
./include/ortools/util/graph_export.h
./include/ortools/util/range_minimum_query.h
./include/ortools/util/return_macros.h
./include/ortools/util/stats.h
./include/ortools/util/piecewise_linear_function.h
./include/ortools/util/adaptative_parameter_value.h
./include/ortools/scheduling
./include/ortools/scheduling/jobshop_scheduling_parser.h
./include/ortools/scheduling/rcpsp.pb.h
./include/ortools/scheduling/rcpsp_parser.h
./include/ortools/scheduling/jobshop_scheduling.pb.h
./include/ortools/graph
./include/ortools/graph/assignment.h
./include/ortools/graph/graphs.h
./include/ortools/graph/max_flow.h
./include/ortools/graph/minimum_spanning_tree.h
./include/ortools/graph/eulerian_path.h
./include/ortools/graph/cliques.h
./include/ortools/graph/strongly_connected_components.h
./include/ortools/graph/graph.h
./include/ortools/graph/topologicalsorter.h
./include/ortools/graph/connected_components.h
./include/ortools/graph/io.h
./include/ortools/graph/perfect_matching.h
./include/ortools/graph/flow_problem.pb.h
./include/ortools/graph/ebert_graph.h
./include/ortools/graph/util.h
./include/ortools/graph/hamiltonian_path.h
./include/ortools/graph/iterators.h
./include/ortools/graph/linear_assignment.h
./include/ortools/graph/min_cost_flow.h
./include/ortools/graph/christofides.h
./include/ortools/graph/shortestpaths.h
./include/ortools/graph/one_tree_lower_bound.h
./include/ortools/algorithms
./include/ortools/algorithms/knapsack_solver_for_cuts.h
./include/ortools/algorithms/dense_doubly_linked_list.h
./include/ortools/algorithms/sparse_permutation.h
./include/ortools/algorithms/dynamic_partition.h
./include/ortools/algorithms/find_graph_symmetries.h
./include/ortools/algorithms/hungarian.h
./include/ortools/algorithms/knapsack_solver.h
./include/ortools/algorithms/dynamic_permutation.h
./include/ortools/flatzinc
./include/ortools/flatzinc/parser.h
./include/ortools/flatzinc/checker.h
./include/ortools/flatzinc/parser_util.h
./include/ortools/flatzinc/cp_model_fz_solver.h
./include/ortools/flatzinc/model.h
./include/ortools/flatzinc/presolve.h
./include/ortools/sat
./include/ortools/sat/timetable_edgefinding.h
./include/ortools/sat/diffn.h
./include/ortools/sat/swig_helper.h
./include/ortools/sat/parameters_validation.h
./include/ortools/sat/linear_constraint_manager.h
./include/ortools/sat/cuts.h
./include/ortools/sat/symmetry_util.h
./include/ortools/sat/linear_relaxation.h
./include/ortools/sat/cp_model_objective.h
./include/ortools/sat/cp_model_loader.h
./include/ortools/sat/circuit.h
./include/ortools/sat/theta_tree.h
./include/ortools/sat/lp_utils.h
./include/ortools/sat/cp_model.h
./include/ortools/sat/drat_proof_handler.h
./include/ortools/sat/cp_constraints.h
./include/ortools/sat/sat_base.h
./include/ortools/sat/scheduling_constraints.h
./include/ortools/sat/presolve_util.h
./include/ortools/sat/cp_model_postsolve.h
./include/ortools/sat/cp_model_search.h
./include/ortools/sat/cp_model_mapping.h
./include/ortools/sat/synchronization.h
./include/ortools/sat/sat_inprocessing.h
./include/ortools/sat/encoding.h
./include/ortools/sat/cp_model_utils.h
./include/ortools/sat/cp_model_service.pb.h
./include/ortools/sat/cumulative_energy.h
./include/ortools/sat/integer_search.h
./include/ortools/sat/sat_parameters.pb.h
./include/ortools/sat/presolve_context.h
./include/ortools/sat/simplification.h
./include/ortools/sat/linear_constraint.h
./include/ortools/sat/intervals.h
./include/ortools/sat/rins.h
./include/ortools/sat/cp_model_checker.h
./include/ortools/sat/drat_writer.h
./include/ortools/sat/pb_constraint.h
./include/ortools/sat/drat_checker.h
./include/ortools/sat/restart.h
./include/ortools/sat/scheduling_cuts.h
./include/ortools/sat/pseudo_costs.h
./include/ortools/sat/cp_model_presolve.h
./include/ortools/sat/linear_programming_constraint.h
./include/ortools/sat/cp_model_symmetries.h
./include/ortools/sat/sat_solver.h
./include/ortools/sat/util.h
./include/ortools/sat/precedences.h
./include/ortools/sat/cp_model_lns.h
./include/ortools/sat/model.h
./include/ortools/sat/cumulative.h
./include/ortools/sat/implied_bounds.h
./include/ortools/sat/optimization.h
./include/ortools/sat/table.h
./include/ortools/sat/disjunctive.h
./include/ortools/sat/subsolver.h
./include/ortools/sat/cp_model_expand.h
./include/ortools/sat/timetable.h
./include/ortools/sat/var_domination.h
./include/ortools/sat/diffn_util.h
./include/ortools/sat/all_different.h
./include/ortools/sat/integer.h
./include/ortools/sat/probing.h
./include/ortools/sat/boolean_problem.h
./include/ortools/sat/sat_decision.h
./include/ortools/sat/lb_tree_search.h
./include/ortools/sat/zero_half_cuts.h
./include/ortools/sat/integer_expr.h
./include/ortools/sat/boolean_problem.pb.h
./include/ortools/sat/clause.h
./include/ortools/sat/cp_model_solver.h
./include/ortools/sat/feasibility_pump.h
./include/ortools/sat/cp_model.pb.h
./include/ortools/sat/symmetry.h
./include/ortools/gscip
./include/ortools/gscip/gscip_message_handler.h
./include/ortools/gscip/gscip_event_handler.h
./include/ortools/gscip/legacy_scip_params.h
./include/ortools/gscip/gscip.h
./include/ortools/gscip/gscip_parameters.h
./include/ortools/gscip/gscip_ext.h
./include/ortools/math_opt
./include/ortools/math_opt/core
./include/ortools/math_opt/core/sparse_vector_view.h
./include/ortools/math_opt/core/model_update_merge.h
./include/ortools/math_opt/core/solver_interface.h
./include/ortools/math_opt/core/solver.h
./include/ortools/math_opt/core/sparse_collection_matchers.h
./include/ortools/math_opt/core/indexed_model.h
./include/ortools/math_opt/core/math_opt_proto_utils.h
./include/ortools/math_opt/core/model_summary.h
./include/ortools/math_opt/io
./include/ortools/math_opt/io/proto_converter.h
./include/ortools/math_opt/solvers
./include/ortools/math_opt/solvers/glop_solver.h
./include/ortools/math_opt/solvers/cp_sat_solver.h
./include/ortools/math_opt/solvers/message_callback_data.h
./include/ortools/math_opt/solvers/gscip_solver.h
./include/ortools/math_opt/solvers/gscip_solver_callback.h
./include/ortools/math_opt/solvers/gurobi_callback.h
./include/ortools/math_opt/solvers/gurobi_solver.h
./include/ortools/math_opt/cpp
./include/ortools/math_opt/cpp/id_map.h
./include/ortools/math_opt/cpp/arrow_operator_proxy.h
./include/ortools/math_opt/cpp/key_types.h
./include/ortools/math_opt/cpp/result.h
./include/ortools/math_opt/cpp/objective.h
./include/ortools/math_opt/cpp/linear_constraint.h
./include/ortools/math_opt/cpp/model_solve_parameters.h
./include/ortools/math_opt/cpp/math_opt.h
./include/ortools/math_opt/cpp/variable_and_expressions.h
./include/ortools/math_opt/cpp/map_filter.h
./include/ortools/math_opt/cpp/callback.h
./include/ortools/math_opt/cpp/id_set.h
./include/ortools/math_opt/validators
./include/ortools/math_opt/validators/name_validator.h
./include/ortools/math_opt/validators/solver_parameters_validator.h
./include/ortools/math_opt/validators/solution_validator.h
./include/ortools/math_opt/validators/scalar_validator.h
./include/ortools/math_opt/validators/ids_validator.h
./include/ortools/math_opt/validators/sparse_vector_validator.h
./include/ortools/math_opt/validators/callback_validator.h
./include/ortools/math_opt/validators/model_validator.h
./include/ortools/math_opt/validators/model_parameters_validator.h
./include/ortools/lp_data
./include/ortools/lp_data/lp_types.h
./include/ortools/lp_data/sparse_column.h
./include/ortools/lp_data/lp_data_utils.h
./include/ortools/lp_data/mps_reader.h
./include/ortools/lp_data/lp_utils.h
./include/ortools/lp_data/scattered_vector.h
./include/ortools/lp_data/matrix_utils.h
./include/ortools/lp_data/permutation.h
./include/ortools/lp_data/sparse_vector.h
./include/ortools/lp_data/lp_data.h
./include/ortools/lp_data/lp_print_utils.h
./include/ortools/lp_data/model_reader.h
./include/ortools/lp_data/lp_decomposer.h
./include/ortools/lp_data/matrix_scaler.h
./include/ortools/lp_data/sparse_row.h
./include/ortools/lp_data/sparse.h
./include/ortools/lp_data/proto_utils.h
./include/ortools/glop
./include/ortools/glop/dual_edge_norms.h
./include/ortools/glop/markowitz.h
./include/ortools/glop/rank_one_update.h
./include/ortools/glop/status.h
./include/ortools/glop/revised_simplex.h
./include/ortools/glop/primal_edge_norms.h
./include/ortools/glop/parameters.pb.h
./include/ortools/glop/entering_variable.h
./include/ortools/glop/initial_basis.h
./include/ortools/glop/update_row.h
./include/ortools/glop/lu_factorization.h
./include/ortools/glop/basis_representation.h
./include/ortools/glop/reduced_costs.h
./include/ortools/glop/lp_solver.h
./include/ortools/glop/variables_info.h
./include/ortools/glop/preprocessor.h
./include/ortools/glop/pricing.h
./include/ortools/glop/variable_values.h
./include/ortools/port
./include/ortools/port/sysinfo.h
./include/ortools/port/file.h
./include/ortools/port/proto_utils.h
./include/ortools/port/utf8.h
./include/ortools/constraint_solver
./include/ortools/constraint_solver/routing_types.h
./include/ortools/constraint_solver/demon_profiler.pb.h
./include/ortools/constraint_solver/assignment.pb.h
./include/ortools/constraint_solver/solver_parameters.pb.h
./include/ortools/constraint_solver/routing_filters.h
./include/ortools/constraint_solver/search_stats.pb.h
./include/ortools/constraint_solver/python
./include/ortools/constraint_solver/python/pywrapcp_util.h
./include/ortools/constraint_solver/routing_search.h
./include/ortools/constraint_solver/routing_lp_scheduling.h
./include/ortools/constraint_solver/routing_neighborhoods.h
./include/ortools/constraint_solver/java
./include/ortools/constraint_solver/java/javawrapcp_util.h
./include/ortools/constraint_solver/routing_flags.h
./include/ortools/constraint_solver/search_limit.pb.h
./include/ortools/constraint_solver/routing_index_manager.h
./include/ortools/constraint_solver/constraint_solveri.h
./include/ortools/constraint_solver/routing_parameters.h
./include/ortools/constraint_solver/routing_enums.pb.h
./include/ortools/constraint_solver/routing.h
./include/ortools/constraint_solver/routing_parameters.pb.h
./include/ortools/constraint_solver/constraint_solver.h
./include/ortools/base
./include/ortools/base/cleanup.h
./include/ortools/base/stl_logging.h
./include/ortools/base/stl_util.h
./include/ortools/base/strong_vector.h
./include/ortools/base/typeid.h
./include/ortools/base/version.h
./include/ortools/base/small_ordered_set.h
./include/ortools/base/iterator_adaptors.h
./include/ortools/base/threadpool.h
./include/ortools/base/thorough_hash.h
./include/ortools/base/logging_utilities.h
./include/ortools/base/jniutil.h
./include/ortools/base/protoutil.h
./include/ortools/base/logging_export.h
./include/ortools/base/sysinfo.h
./include/ortools/base/file.h
./include/ortools/base/murmur.h
./include/ortools/base/map_util.h
./include/ortools/base/adjustable_priority_queue.h
./include/ortools/base/gzipstring.h
./include/ortools/base/commandlineflags.h
./include/ortools/base/linked_hash_map.h
./include/ortools/base/logging.h
./include/ortools/base/container_logging.h
./include/ortools/base/protobuf_util.h
./include/ortools/base/status_macros.h
./include/ortools/base/timer.h
./include/ortools/base/python-swig.h
./include/ortools/base/small_map.h
./include/ortools/base/macros.h
./include/ortools/base/dynamic_library.h
./include/ortools/base/raw_logging.h
./include/ortools/base/vlog_is_on.h
./include/ortools/base/basictypes.h
./include/ortools/base/status_builder.h
./include/ortools/base/integral_types.h
./include/ortools/base/log_severity.h
./include/ortools/base/mathutil.h
./include/ortools/base/filelineiter.h
./include/ortools/base/base_export.h
./include/ortools/base/bitmap.h
./include/ortools/base/int_type.h
./include/ortools/base/encodingutils.h
./include/ortools/base/hash.h
./include/ortools/base/ptr_util.h
./include/ortools/base/random.h
./include/ortools/base/recordio.h
./include/ortools/base/accurate_sum.h
./include/ortools/base/adjustable_priority_queue-inl.h
./include/ortools/linear_solver
./include/ortools/linear_solver/model_exporter_swig_helper.h
./include/ortools/linear_solver/model_exporter.h
./include/ortools/linear_solver/scip_helper_macros.h
./include/ortools/linear_solver/sat_solver_utils.h
./include/ortools/linear_solver/scip_callback.h
./include/ortools/linear_solver/linear_solver.pb.h
./include/ortools/linear_solver/sat_proto_solver.h
./include/ortools/linear_solver/gurobi_proto_solver.h
./include/ortools/linear_solver/linear_solver.h
./include/ortools/linear_solver/scip_proto_solver.h
./include/ortools/linear_solver/linear_solver_callback.h
./include/ortools/linear_solver/glop_utils.h
./include/ortools/linear_solver/model_validator.h
./include/ortools/linear_solver/linear_expr.h
./include/ortools/gurobi
./include/ortools/gurobi/environment.h
./include/ortools/packing
./include/ortools/packing/arc_flow_builder.h
./include/ortools/packing/vector_bin_packing.pb.h
./include/ortools/packing/arc_flow_solver.h
./include/ortools/packing/vector_bin_packing_parser.h
./README.md
./lib
./lib/cmake
./lib/cmake/ortools
./lib/cmake/ortools/ortoolsConfigVersion.cmake
./lib/cmake/ortools/ortoolsTargets.cmake
./lib/cmake/ortools/ortoolsTargets-release.cmake
./lib/cmake/ortools/ortoolsConfig.cmake
./lib/libflatzinc.9.1.dylib
./lib/libortools.dylib
./lib/libortools.9.dylib
./lib/libortools.9.1.dylib
./lib/libflatzinc.dylib
./lib/libflatzinc.9.dylib
./share
./share/minizinc
./share/minizinc/solvers
./share/minizinc/solvers/ortools.msc
./share/minizinc/ortools
./share/minizinc/ortools/fzn_regular.mzn
./share/minizinc/ortools/fzn_all_different_int.mzn
./share/minizinc/ortools/fzn_cumulative.mzn
./share/minizinc/ortools/nostrings.mzn
./share/minizinc/ortools/redefinitions-2.0.mzn
./share/minizinc/ortools/fzn_circuit.mzn
./share/minizinc/ortools/fzn_inverse.mzn
./share/minizinc/ortools/fzn_network_flow_cost.mzn
./share/minizinc/ortools/fzn_network_flow.mzn
./share/minizinc/ortools/fzn_table_int.mzn
./share/minizinc/ortools/fzn_diffn_nonstrict.mzn
./share/minizinc/ortools/fzn_table_bool.mzn
./share/minizinc/ortools/fzn_subcircuit.mzn
./share/minizinc/ortools/fzn_diffn.mzn
./share/or-tools
./share/or-tools/simple_routing_program.cc
./share/or-tools/simple_lp_program.cc
./share/or-tools/simple_sat_program.cc

homebrew/opt/or-tools on  stable 
❯ 

Dependency on lsb-core when installing the gem

First of all, thanks for a great gem.

I’m running into some installation problems in environments where lsb-core package isn’t installed and thus the lsb_release command doesn’t work. For example, we don’t keep lsb-core in our base application images or in our base CI image because it has a lot of dependencies, some quite big (like python3).

I do have other possibilities (install the package despite its dependencies), download the binaries manually and build against that directory, but the convenience of binaries being downloaded automatically is great so I wanted to explore that path further first.

It looks like all the operating systems targeted in vendor.rb should support the /etc/os-release file required by systemd. To my best understanding, this is an actual standard and leveraging this file could potentially remove the dependency on lsb-core; it could be replaced by parsing a text file in pure Ruby.

Would it make sense to make such change?

Problem to install on mac m1

I struggle with install it on mac m1, getting error related to one of dependencies, looks like architecture does not match

ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [gobject_introspection.bundle] Error 1

make failed, exit code 2

Setting a max time for a solver.

I'm trying to find out how to hook into CPModel in order to set in the same way that it does here

https://developers.google.com/optimization/cp/cp_tasks#c++

  // Solving part.
  Model model;

  // Sets a time limit of 10 seconds.
  SatParameters parameters;
  parameters.set_max_time_in_seconds(10.0);
  model.Add(NewSatParameters(parameters));

As far as I can see this isn't available at the moment. Is that right?

Basically, at the moment our solver keeps going and only stops on Ctrl-C and I'd like to see what the result is after 10, or 20 seconds or whatever.

Specify start and end points for vehicle routing

Hello ankane

First of all: I love your ruby bindings, saves me allready a lot time and pain, thanks for that.

I would like to specify start and endpoints for a vehicle routing problem instead of a depot where everthing starts and ends.
The google docs give an example how to do this: https://developers.google.com/optimization/routing/routing_tasks#setting-start-and-end-locations-for-routes

 # Create the routing index manager.
manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), data['num_vehicles'], data['starts'], data['ends'])

I tried something similar in ruby

manager = ORTools::RoutingIndexManager.new(@distance_matrix.count, car_count, @start_points, [@end_point] * car_count)

but it gives me a initialize': no implicit conversion of Array into Integer (TypeError) on that line.

Is that possible with your library?

scheduling_test.rb explodes a bit with latest master

Robs-MacBook-Pro:or-tools rl$ bundle exec rake test TEST=test/scheduling_test.rb
Run options: --seed 50352

Running:

F/Users/rl/repos/or-tools/test/scheduling_test.rb:121: [BUG] Segmentation fault at 0x0000000000000000
ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin20]

-- Crash Report log information --------------------------------------------
See Crash Report log file under the one of following:
* ~/Library/Logs/DiagnosticReports
* /Library/Logs/DiagnosticReports
for more details.
Don't forget to include the above Crash Report log file in bug reports.

-- Control frame information -----------------------------------------------
c:0032 p:---- s:0181 e:000180 CFUNC :new_interval_var
c:0031 p:0095 s:0173 e:000172 BLOCK /Users/rl/repos/or-tools/test/scheduling_test.rb:121 [FINISH]
c:0030 p:---- s:0161 e:000160 IFUNC
c:0029 p:---- s:0158 e:000157 CFUNC :each
c:0028 p:---- s:0155 e:000154 CFUNC :each_with_index
c:0027 p:0006 s:0151 e:000150 BLOCK /Users/rl/repos/or-tools/test/scheduling_test.rb:114 [FINISH]
c:0026 p:---- s:0146 e:000145 IFUNC
c:0025 p:---- s:0143 e:000142 CFUNC :each
c:0024 p:---- s:0140 e:000139 CFUNC :each_with_index
c:0023 p:0098 s:0136 E:0026a0 METHOD /Users/rl/repos/or-tools/test/scheduling_test.rb:113
c:0022 p:0019 s:0120 e:000119 BLOCK /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/test.rb:98
c:0021 p:0002 s:0117 e:000116 METHOD /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/test.rb:195
c:0020 p:0005 s:0112 e:000111 BLOCK /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/test.rb:95
c:0019 p:0015 s:0109 e:000108 METHOD /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:272
c:0018 p:0005 s:0104 e:000103 BLOCK /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/test.rb:94
c:0017 p:0030 s:0101 E:001180 METHOD /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:367
c:0016 p:0045 s:0093 E:0018d8 METHOD /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/test.rb:211
c:0015 p:0004 s:0086 E:001f90 METHOD /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/test.rb:93
c:0014 p:0008 s:0082 e:000081 METHOD /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:1029
c:0013 p:0026 s:0075 e:000073 METHOD /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:341
c:0012 p:0010 s:0067 e:000066 BLOCK /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:328 [FINISH]
c:0011 p:---- s:0063 e:000062 CFUNC :each
c:0010 p:0006 s:0059 e:000058 BLOCK /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:327
c:0009 p:0030 s:0056 E:002380 METHOD /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:367
c:0008 p:0030 s:0048 E:000e68 METHOD /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:354
c:0007 p:0119 s:0041 E:002458 METHOD /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:326
c:0006 p:0009 s:0032 e:000031 BLOCK /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:164 [FINISH]
c:0005 p:---- s:0028 e:000027 CFUNC :map
c:0004 p:0037 s:0024 e:000023 METHOD /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:164
c:0003 p:0142 s:0015 e:000014 METHOD /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:141
c:0002 p:0074 s:0008 E:000140 BLOCK /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:68 [FINISH]
c:0001 p:0000 s:0003 E:001110 (none) [FINISH]

-- Ruby level backtrace information ----------------------------------------
/Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:68:in block in autorun' /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:141:in run'
/Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:164:in __run' /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:164:in map'
/Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:164:in block in __run' /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:326:in run'
/Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:354:in with_info_handler' /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:367:in on_signal'
/Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:327:in block in run' /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:327:in each'
/Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:328:in block (2 levels) in run' /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:341:in run_one_method'
/Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:1029:in run_one_method' /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/test.rb:93:in run'
/Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/test.rb:211:in with_info_handler' /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:367:in on_signal'
/Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/test.rb:94:in block in run' /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb:272:in time_it'
/Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/test.rb:95:in block (2 levels) in run' /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/test.rb:195:in capture_exceptions'
/Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/test.rb:98:in block (3 levels) in run' /Users/rl/repos/or-tools/test/scheduling_test.rb:113:in test_job_shop'
/Users/rl/repos/or-tools/test/scheduling_test.rb:113:in each_with_index' /Users/rl/repos/or-tools/test/scheduling_test.rb:113:in each'
/Users/rl/repos/or-tools/test/scheduling_test.rb:114:in block in test_job_shop' /Users/rl/repos/or-tools/test/scheduling_test.rb:114:in each_with_index'
/Users/rl/repos/or-tools/test/scheduling_test.rb:114:in each' /Users/rl/repos/or-tools/test/scheduling_test.rb:121:in block (2 levels) in test_job_shop'
/Users/rl/repos/or-tools/test/scheduling_test.rb:121:in `new_interval_var'

-- Machine register context ------------------------------------------------
rax: 0x0000000000000000 rbx: 0x011e7fab1d66eef6 rcx: 0x0000000000000000
rdx: 0x0000000000000040 rdi: 0x00007ff205307770 rsi: 0x00007ffee6554040
rbp: 0x00007ffee6554000 rsp: 0x00007ffee6553ff8 r8: 0x0000000000000000
r9: 0x0000000000000000 r10: 0x0000000000000001 r11: 0x000000010b4c5dfa
r12: 0x0000000000000002 r13: 0x000000010b0b6a78 r14: 0x00007ff205307770
r15: 0x0000000000000000 rip: 0x000000010b232d49 rfl: 0x0000000000010246

-- C level backtrace information -------------------------------------------
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_vm_bugreport+0x96) [0x1099251a6]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_bug_for_fatal_signal+0x1d0) [0x10975df20]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(sigsegv+0x5b) [0x10988899b]
/usr/lib/system/libsystem_platform.dylib(_sigtramp+0x1d) [0x7fff20590d7d]
/usr/local/opt/or-tools/lib/libortools.8.dylib(_ZN4absl14lts_2020_09_2318container_internal12raw_hash_setINS1_17FlatHashMapPolicyIPKN19operations_research11IntervalVarEiEENS1_6HashEqIS7_vE4HashENSA_2EqENSt3__19allocatorINSD_4pairIKS7_iEEEEE4findIS7_EENSJ_8iteratorERKT_m+0x39) [0x10b232d49]
/usr/local/opt/or-tools/lib/libortools.8.dylib(0x10b4c4b07) [0x10b4c4b07]
/usr/local/opt/or-tools/lib/libortools.8.dylib(0x10b4c5e1a) [0x10b4c5e1a]
/Users/rl/repos/or-tools/lib/or_tools/ext.bundle(_ZZ15init_constraintRN4Rice6ModuleEEN3$_78__invokeERN19operations_research3sat14CpModelBuilderENS4_6IntVarES7_S7_NSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEE+0x1d) [0x10b023b3d]
/Users/rl/repos/or-tools/lib/or_tools/ext.bundle(_ZN4Rice6detail21Auto_Function_WrapperIPFN19operations_research3sat11IntervalVarERNS3_14CpModelBuilderENS3_6IntVarES7_S7_NSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEES4_S6_S7_S7_S7_SE_vvvvvvvvvvvE4callEiPmm+0x7a3) [0x10b032143]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(vm_call_cfunc+0x16c) [0x10991686c]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(vm_exec_core+0x38e0) [0x1098fcbd0]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_vm_exec+0xa93) [0x1099116f3]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_yield_values2+0x4e) [0x10990a75e]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(each_with_index_i+0x108) [0x1097522b8]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(invoke_block_from_c_bh+0x440) [0x109920840]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_yield+0xa7) [0x10990a487]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_ary_each+0x29) [0x1096c36d9]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(vm_call0_body+0x90c) [0x109907c4c]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_call0+0x534) [0x109920064]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(iterate_method+0x3c) [0x10990af5c]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_iterate0+0xed) [0x10990adad]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_block_call+0x61) [0x10990af01]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(enum_each_with_index+0x4c) [0x10974db4c]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(vm_call_cfunc+0x16c) [0x10991686c]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(vm_exec_core+0x3770) [0x1098fca60]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_vm_exec+0xa93) [0x1099116f3]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_yield_values2+0x4e) [0x10990a75e]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(each_with_index_i+0x108) [0x1097522b8]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(invoke_block_from_c_bh+0x440) [0x109920840]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_yield+0xa7) [0x10990a487]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_ary_each+0x29) [0x1096c36d9]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(vm_call0_body+0x90c) [0x109907c4c]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_call0+0x534) [0x109920064]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(iterate_method+0x3c) [0x10990af5c]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_iterate0+0xed) [0x10990adad]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_block_call+0x61) [0x10990af01]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(enum_each_with_index+0x4c) [0x10974db4c]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(vm_call_cfunc+0x16c) [0x10991686c]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(vm_exec_core+0x3770) [0x1098fca60]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_vm_exec+0xa93) [0x1099116f3]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_yield+0xa7) [0x10990a487]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_ary_each+0x29) [0x1096c36d9]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(vm_call_cfunc+0x16c) [0x10991686c]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(vm_exec_core+0x3770) [0x1098fca60]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_vm_exec+0xa93) [0x1099116f3]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_yield+0xa7) [0x10990a487]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_ary_collect+0x108) [0x1096c9818]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(vm_call_cfunc+0x16c) [0x10991686c]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(vm_exec_core+0x3770) [0x1098fca60]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_vm_exec+0xa93) [0x1099116f3]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_proc_call+0x9f) [0x10982dbef]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_ec_exec_end_proc+0x172) [0x10976c0b2]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_ec_teardown+0xaf) [0x109768cff]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(rb_ec_cleanup+0x17c) [0x109768ecc]
/Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib(ruby_run_node+0x5f) [0x1097691cf]
/Users/rl/.rbenv/versions/2.7.2/bin/ruby(main+0x5d) [0x1096acf0d]

-- Other runtime information -----------------------------------------------

  • Loaded script: /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/rake_test_loader.rb

  • Loaded features:

    0 enumerator.so
    1 thread.rb
    2 rational.so
    3 complex.so
    4 ruby2_keywords.rb
    5 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
    6 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/trans/transdb.bundle
    7 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/rbconfig.rb
    8 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/compatibility.rb
    9 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/defaults.rb
    10 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/deprecate.rb
    11 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/errors.rb
    12 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/version.rb
    13 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/requirement.rb
    14 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/platform.rb
    15 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/basic_specification.rb
    16 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/stub_specification.rb
    17 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/util.rb
    18 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/text.rb
    19 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/user_interaction.rb
    20 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/specification_policy.rb
    21 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/util/list.rb
    22 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/specification.rb
    23 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/exceptions.rb
    24 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/bundler_version_finder.rb
    25 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/dependency.rb
    26 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/core_ext/kernel_gem.rb
    27 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/monitor.bundle
    28 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/monitor.rb
    29 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb
    30 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/core_ext/kernel_warn.rb
    31 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems.rb
    32 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/path_support.rb
    33 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/did_you_mean/version.rb
    34 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/did_you_mean/core_ext/name_error.rb
    35 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/did_you_mean/levenshtein.rb
    36 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/did_you_mean/jaro_winkler.rb
    37 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/did_you_mean/spell_checker.rb
    38 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/did_you_mean/spell_checkers/name_error_checkers/class_name_checker.rb
    39 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb
    40 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/did_you_mean/spell_checkers/name_error_checkers.rb
    41 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/did_you_mean/spell_checkers/method_name_checker.rb
    42 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/did_you_mean/spell_checkers/key_error_checker.rb
    43 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/did_you_mean/spell_checkers/null_checker.rb
    44 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/did_you_mean/formatters/plain_formatter.rb
    45 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/did_you_mean/tree_spell_checker.rb
    46 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/did_you_mean.rb
    47 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/pathname.bundle
    48 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/pathname.rb
    49 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/version.rb
    50 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/constants.rb
    51 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/rubygems_integration.rb
    52 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/current_ruby.rb
    53 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/shared_helpers.rb
    54 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/fileutils/lib/fileutils.rb
    55 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendored_fileutils.rb
    56 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/errors.rb
    57 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/environment_preserver.rb
    58 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/plugin/api.rb
    59 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/plugin.rb
    60 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/source/git.rb
    61 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/source/installed.rb
    62 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/source/specific_file.rb
    63 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/source/local.rb
    64 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/source/lock.rb
    65 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/source/vendor.rb
    66 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/source.rb
    67 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/gem_helpers.rb
    68 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/match_platform.rb
    69 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/rubygems_ext.rb
    70 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/build_metadata.rb
    71 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler.rb
    72 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/ui.rb
    73 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor/command.rb
    74 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb
    75 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor/error.rb
    76 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor/invocation.rb
    77 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor/nested_context.rb
    78 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor/parser/argument.rb
    79 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb
    80 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor/parser/option.rb
    81 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor/parser/options.rb
    82 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor/parser.rb
    83 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor/shell.rb
    84 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb
    85 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb
    86 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor/line_editor.rb
    87 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor/util.rb
    88 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor/base.rb
    89 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor.rb
    90 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendored_thor.rb
    91 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/ui/shell.rb
    92 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor/shell/basic.rb
    93 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/thor/lib/thor/shell/color.rb
    94 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/ext/builder.rb
    95 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/ui/rg_proxy.rb
    96 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/settings.rb
    97 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/yaml_serializer.rb
    98 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/feature_flag.rb
    99 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/source.rb
    100 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/source/path.rb
    101 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/source/git.rb
    102 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/source/rubygems.rb
    103 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/lockfile_parser.rb
    104 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/definition.rb
    105 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/dependency.rb
    106 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/ruby_dsl.rb
    107 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/dsl.rb
    108 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/source_list.rb
    109 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/source/metadata.rb
    110 /Users/rl/repos/or-tools/lib/or_tools/version.rb
    111 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/index.rb
    112 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/source/gemspec.rb
    113 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/uri/lib/uri/version.rb
    114 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb
    115 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb
    116 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/uri/lib/uri/common.rb
    117 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/uri/lib/uri/generic.rb
    118 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/uri/lib/uri/file.rb
    119 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/uri/lib/uri/ftp.rb
    120 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/uri/lib/uri/http.rb
    121 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/uri/lib/uri/https.rb
    122 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/uri/lib/uri/ldap.rb
    123 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/uri/lib/uri/ldaps.rb
    124 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/uri/lib/uri/mailto.rb
    125 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendor/uri/lib/uri.rb
    126 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/vendored_uri.rb
    127 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/lazy_specification.rb
    128 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/tsort.rb
    129 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/spec_set.rb
    130 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/util/licenses.rb
    131 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/uri/version.rb
    132 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/uri/rfc2396_parser.rb
    133 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/uri/rfc3986_parser.rb
    134 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/uri/common.rb
    135 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/uri/generic.rb
    136 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/uri/file.rb
    137 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/uri/ftp.rb
    138 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/uri/http.rb
    139 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/uri/https.rb
    140 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/uri/ldap.rb
    141 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/uri/ldaps.rb
    142 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/uri/mailto.rb
    143 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/uri.rb
    144 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/remote_specification.rb
    145 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/runtime.rb
    146 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/dep_proxy.rb
    147 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/stub_specification.rb
    148 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/ruby_version.rb
    149 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/endpoint_specification.rb
    150 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bundler-2.2.13/lib/bundler/setup.rb
    151 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/version.rb
    152 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/fileutils.rb
    153 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/singleton.rb
    154 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/optparse.rb
    155 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/ostruct/version.rb
    156 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/ostruct.rb
    157 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/ext/core.rb
    158 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/ext/string.rb
    159 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/win32.rb
    160 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/linked_list.rb
    161 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/etc.bundle
    162 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/cpu_counter.rb
    163 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/scope.rb
    164 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/task_argument_error.rb
    165 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/rule_recursion_overflow_error.rb
    166 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/task_manager.rb
    167 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/cloneable.rb
    168 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/file_utils.rb
    169 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/file_utils_ext.rb
    170 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/file_list.rb
    171 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/set.rb
    172 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/promise.rb
    173 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/thread_pool.rb
    174 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/private_reader.rb
    175 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/thread_history_display.rb
    176 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/trace_output.rb
    177 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/application.rb
    178 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/rake_module.rb
    179 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/pseudo_status.rb
    180 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/task_arguments.rb
    181 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/invocation_chain.rb
    182 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/invocation_exception_mixin.rb
    183 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/task.rb
    184 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/early_time.rb
    185 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/file_task.rb
    186 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/file_creation_task.rb
    187 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/multi_task.rb
    188 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/dsl_definition.rb
    189 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/default_loader.rb
    190 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/late_time.rb
    191 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/name_space.rb
    192 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake/backtrace.rb
    193 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/rake-13.0.3/lib/rake.rb
    194 /Users/rl/repos/or-tools/lib/or_tools/ext.bundle
    195 /Users/rl/repos/or-tools/lib/or_tools/comparison.rb
    196 /Users/rl/repos/or-tools/lib/or_tools/comparison_operators.rb
    197 /Users/rl/repos/or-tools/lib/or_tools/bool_var.rb
    198 /Users/rl/repos/or-tools/lib/or_tools/cp_model.rb
    199 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/forwardable/impl.rb
    200 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/forwardable/version.rb
    201 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/forwardable.rb
    202 /Users/rl/repos/or-tools/lib/or_tools/cp_solver.rb
    203 /Users/rl/repos/or-tools/lib/or_tools/cp_solver_solution_callback.rb
    204 /Users/rl/repos/or-tools/lib/or_tools/int_var.rb
    205 /Users/rl/repos/or-tools/lib/or_tools/knapsack_solver.rb
    206 /Users/rl/repos/or-tools/lib/or_tools/linear_expr.rb
    207 /Users/rl/repos/or-tools/lib/or_tools/routing_index_manager.rb
    208 /Users/rl/repos/or-tools/lib/or_tools/routing_model.rb
    209 /Users/rl/repos/or-tools/lib/or_tools/sat_linear_expr.rb
    210 /Users/rl/repos/or-tools/lib/or_tools/sat_int_var.rb
    211 /Users/rl/repos/or-tools/lib/or_tools/solver.rb
    212 /Users/rl/repos/or-tools/lib/or_tools/objective_solution_printer.rb
    213 /Users/rl/repos/or-tools/lib/or_tools/var_array_solution_printer.rb
    214 /Users/rl/repos/or-tools/lib/or_tools/var_array_and_objective_solution_printer.rb
    215 /Users/rl/repos/or-tools/lib/or_tools/basic_scheduler.rb
    216 /Users/rl/repos/or-tools/lib/or_tools/seating.rb
    217 /Users/rl/repos/or-tools/lib/or_tools/sudoku.rb
    218 /Users/rl/repos/or-tools/lib/or_tools/tsp.rb
    219 /Users/rl/repos/or-tools/lib/or-tools.rb
    220 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/mutex_m.rb
    221 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/parallel.rb
    222 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/stringio.bundle
    223 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/delegate.rb
    224 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/tmpdir.rb
    225 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/tempfile.rb
    226 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/assertions.rb
    227 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/unit.rb
    228 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/test.rb
    229 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest.rb
    230 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/expectations.rb
    231 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/spec.rb
    232 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/mock.rb
    233 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/autorun.rb
    234 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/pride_plugin.rb
    235 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/minitest-5.14.4/lib/minitest/pride.rb
    236 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/date_core.bundle
    237 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/date.rb
    238 /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/time.rb
    239 /Users/rl/repos/or-tools/test/test_helper.rb
    240 /Users/rl/repos/or-tools/test/scheduling_test.rb

  • Process memory map:

1096a9000-1096ad000 r-x /Users/rl/.rbenv/versions/2.7.2/bin/ruby
1096ad000-1096b1000 r-- /Users/rl/.rbenv/versions/2.7.2/bin/ruby
1096b1000-1096b5000 rw- /Users/rl/.rbenv/versions/2.7.2/bin/ruby
1096b5000-1096b6000 r-- /Users/rl/.rbenv/versions/2.7.2/bin/ruby
1096b6000-1096b9000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib
1096b9000-1096bb000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib
1096bb000-1096bc000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib
1096bc000-1096bd000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib
1096bd000-1099d5000 r-x /Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib
1099d5000-1099dd000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib
1099dd000-1099e1000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib
1099e1000-1099f9000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib
1099f9000-109ae4000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib
109ae4000-109ae5000 rw- /usr/local/Cellar/gmp/6.2.1/lib/libgmp.10.dylib
109ae5000-109b45000 r-x /usr/local/Cellar/gmp/6.2.1/lib/libgmp.10.dylib
109b45000-109b49000 r-- /usr/local/Cellar/gmp/6.2.1/lib/libgmp.10.dylib
109b49000-109b4d000 rw- /usr/local/Cellar/gmp/6.2.1/lib/libgmp.10.dylib
109b4d000-109b5a000 r-- /usr/local/Cellar/gmp/6.2.1/lib/libgmp.10.dylib
109b5a000-109b5d000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109b5d000-109b5e000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109b5e000-109b62000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109b62000-109b63000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109b63000-109b6c000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109b6c000-109b6d000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109b6d000-109b6e000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109b6e000-109b77000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109b77000-109b78000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109b78000-109b79000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109b79000-109c1a000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109c1a000-109c1b000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109c1b000-109cbc000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109cbc000-109cbd000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109cbd000-109d5e000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109d5e000-109d5f000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109d5f000-109e00000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109e00000-109e01000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109e01000-109ea2000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109ea2000-109ea3000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109ea3000-109f44000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109f44000-109f45000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109f45000-109fe6000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109fe6000-109fe7000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
109fe7000-10a088000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a088000-10a089000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a089000-10a12a000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a12a000-10a12b000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a12b000-10a1cc000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a1cc000-10a1cd000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a1cd000-10a26e000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a26e000-10a26f000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a26f000-10a310000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a310000-10a311000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a311000-10a3b2000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a3b2000-10a3b3000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a3b3000-10a454000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a454000-10a455000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a455000-10a4f6000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a4f6000-10a4f7000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a4f7000-10a598000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a598000-10a599000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a599000-10a63a000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a63a000-10a63b000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a63b000-10a6dc000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a6dc000-10a6dd000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a6dd000-10a77e000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a77e000-10a77f000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a77f000-10a820000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a820000-10a821000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a821000-10a8c2000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a8c2000-10a8c3000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a8c3000-10a964000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a964000-10a965000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10a965000-10aa06000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10aa06000-10aa07000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10aa07000-10aaa8000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10aaa8000-10aaa9000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10aaa9000-10ab4a000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10ab4a000-10ab4b000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10ab4b000-10abec000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10abec000-10abed000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10abed000-10ac8e000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10ac8e000-10ac8f000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10ac8f000-10ad30000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10ad30000-10ad31000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10ad31000-10add2000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10add2000-10add3000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10add3000-10ae74000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10ae74000-10ae75000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10ae75000-10af16000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10af16000-10af17000 --- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10af17000-10afb8000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10afb8000-10afbc000 r-x /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10afbc000-10afc0000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10afc0000-10afc4000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10afc4000-10afc5000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/encdb.bundle
10afc5000-10afc8000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/trans/transdb.bundle
10afc8000-10afcc000 r-x /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/trans/transdb.bundle
10afcc000-10afd0000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/trans/transdb.bundle
10afd0000-10afd4000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/trans/transdb.bundle
10afd4000-10afd5000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/enc/trans/transdb.bundle
10afd5000-10afd8000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/monitor.bundle
10afd8000-10afd9000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/monitor.bundle
10afd9000-10afdd000 r-x /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/monitor.bundle
10afdd000-10afe1000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/monitor.bundle
10afe1000-10afe5000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/monitor.bundle
10afe5000-10afe7000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/monitor.bundle
10afe7000-10afe9000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/pathname.bundle
10afe9000-10aff1000 r-x /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/pathname.bundle
10aff1000-10aff5000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/pathname.bundle
10aff5000-10aff9000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/pathname.bundle
10aff9000-10affe000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/pathname.bundle
10affe000-10b001000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/etc.bundle
10b001000-10b005000 r-x /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/etc.bundle
10b005000-10b009000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/etc.bundle
10b009000-10b00d000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/etc.bundle
10b00d000-10b010000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/etc.bundle
10b010000-10b011000 rw- /Users/rl/repos/or-tools/lib/or_tools/ext.bundle
10b011000-10b0b5000 r-x /Users/rl/repos/or-tools/lib/or_tools/ext.bundle
10b0b5000-10b0b9000 r-- /Users/rl/repos/or-tools/lib/or_tools/ext.bundle
10b0b9000-10b0bd000 rw- /Users/rl/repos/or-tools/lib/or_tools/ext.bundle
10b0bd000-10b17e000 r-- /Users/rl/repos/or-tools/lib/or_tools/ext.bundle
10b17e000-10b181000 rw- /usr/local/Cellar/or-tools/8.1/lib/libortools.8.1.dylib
10b181000-10b78d000 r-x /usr/local/Cellar/or-tools/8.1/lib/libortools.8.1.dylib
10b78d000-10b7b9000 r-- /usr/local/Cellar/or-tools/8.1/lib/libortools.8.1.dylib
10b7b9000-10b7c1000 rw- /usr/local/Cellar/or-tools/8.1/lib/libortools.8.1.dylib
10b7c1000-10b7dd000 rw- /usr/local/Cellar/or-tools/8.1/lib/libortools.8.1.dylib
10b7dd000-10bc3b000 r-- /usr/local/Cellar/or-tools/8.1/lib/libortools.8.1.dylib
10bc3b000-10bc3d000 rw- /usr/local/Cellar/protobuf/3.14.0/lib/libprotobuf.25.dylib
10bc3d000-10bd85000 r-x /usr/local/Cellar/protobuf/3.14.0/lib/libprotobuf.25.dylib
10bd85000-10bd8d000 r-- /usr/local/Cellar/protobuf/3.14.0/lib/libprotobuf.25.dylib
10bd8d000-10bd91000 rw- /usr/local/Cellar/protobuf/3.14.0/lib/libprotobuf.25.dylib
10bd91000-10be86000 r-- /usr/local/Cellar/protobuf/3.14.0/lib/libprotobuf.25.dylib
10be86000-10be89000 rw- /usr/local/Cellar/cbc/2.10.5/lib/libOsiCbc.3.10.5.dylib
10be89000-10be91000 r-x /usr/local/Cellar/cbc/2.10.5/lib/libOsiCbc.3.10.5.dylib
10be91000-10be95000 r-- /usr/local/Cellar/cbc/2.10.5/lib/libOsiCbc.3.10.5.dylib
10be95000-10be99000 rw- /usr/local/Cellar/cbc/2.10.5/lib/libOsiCbc.3.10.5.dylib
10be99000-10bea3000 r-- /usr/local/Cellar/cbc/2.10.5/lib/libOsiCbc.3.10.5.dylib
10bea3000-10bea5000 rw- /usr/local/Cellar/cbc/2.10.5/lib/libCbcSolver.3.10.5.dylib
10bea5000-10bf61000 r-x /usr/local/Cellar/cbc/2.10.5/lib/libCbcSolver.3.10.5.dylib
10bf61000-10bf69000 r-- /usr/local/Cellar/cbc/2.10.5/lib/libCbcSolver.3.10.5.dylib
10bf69000-10bf6d000 rw- /usr/local/Cellar/cbc/2.10.5/lib/libCbcSolver.3.10.5.dylib
10bf6d000-10bf99000 r-- /usr/local/Cellar/cbc/2.10.5/lib/libCbcSolver.3.10.5.dylib
10bf99000-10c039000 r-x /usr/local/Cellar/cbc/2.10.5/lib/libCbc.3.10.5.dylib
10c039000-10c041000 r-- /usr/local/Cellar/cbc/2.10.5/lib/libCbc.3.10.5.dylib
10c041000-10c045000 rw- /usr/local/Cellar/cbc/2.10.5/lib/libCbc.3.10.5.dylib
10c045000-10c083000 r-- /usr/local/Cellar/cbc/2.10.5/lib/libCbc.3.10.5.dylib
10c083000-10c085000 rw- /usr/local/Cellar/cgl/0.60.3/lib/libCgl.1.10.3.dylib
10c085000-10c139000 r-x /usr/local/Cellar/cgl/0.60.3/lib/libCgl.1.10.3.dylib
10c139000-10c13d000 r-- /usr/local/Cellar/cgl/0.60.3/lib/libCgl.1.10.3.dylib
10c13d000-10c141000 rw- /usr/local/Cellar/cgl/0.60.3/lib/libCgl.1.10.3.dylib
10c141000-10c165000 r-- /usr/local/Cellar/cgl/0.60.3/lib/libCgl.1.10.3.dylib
10c165000-10c191000 r-x /usr/local/Cellar/clp/1.17.6_1/lib/libOsiClp.1.14.6.dylib
10c191000-10c195000 r-- /usr/local/Cellar/clp/1.17.6_1/lib/libOsiClp.1.14.6.dylib
10c195000-10c199000 rw- /usr/local/Cellar/clp/1.17.6_1/lib/libOsiClp.1.14.6.dylib
10c199000-10c1af000 r-- /usr/local/Cellar/clp/1.17.6_1/lib/libOsiClp.1.14.6.dylib
10c1af000-10c1b1000 rw- /usr/local/Cellar/clp/1.17.6_1/lib/libClpSolver.1.14.6.dylib
10c1b1000-10c219000 r-x /usr/local/Cellar/clp/1.17.6_1/lib/libClpSolver.1.14.6.dylib
10c219000-10c21d000 r-- /usr/local/Cellar/clp/1.17.6_1/lib/libClpSolver.1.14.6.dylib
10c21d000-10c221000 rw- /usr/local/Cellar/clp/1.17.6_1/lib/libClpSolver.1.14.6.dylib
10c221000-10c22f000 r-- /usr/local/Cellar/clp/1.17.6_1/lib/libClpSolver.1.14.6.dylib
10c22f000-10c231000 rw- /usr/lib/dyld
10c233000-10c2cf000 r-x /usr/lib/dyld
10c2cf000-10c2d7000 r-- /usr/lib/dyld
10c2d7000-10c2db000 rw- /usr/lib/dyld
10c2db000-10c30f000 rw- /usr/lib/dyld
10c30f000-10c347000 r-- /usr/lib/dyld
10c347000-10c34b000 r-- /usr/local/Cellar/clp/1.17.6_1/lib/libClp.1.14.6.dylib
10c34b000-10c463000 r-x /usr/local/Cellar/clp/1.17.6_1/lib/libClp.1.14.6.dylib
10c463000-10c467000 r-- /usr/local/Cellar/clp/1.17.6_1/lib/libClp.1.14.6.dylib
10c467000-10c46b000 rw- /usr/local/Cellar/clp/1.17.6_1/lib/libClp.1.14.6.dylib
10c46b000-10c49d000 r-- /usr/local/Cellar/clp/1.17.6_1/lib/libClp.1.14.6.dylib
10c49d000-10c49f000 rw- /usr/local/Cellar/osi/0.108.6/lib/libOsi.1.13.6.dylib
10c49f000-10c4cf000 r-x /usr/local/Cellar/osi/0.108.6/lib/libOsi.1.13.6.dylib
10c4cf000-10c4d3000 r-- /usr/local/Cellar/osi/0.108.6/lib/libOsi.1.13.6.dylib
10c4d3000-10c4d7000 rw- /usr/local/Cellar/osi/0.108.6/lib/libOsi.1.13.6.dylib
10c4d7000-10c4ed000 r-- /usr/local/Cellar/osi/0.108.6/lib/libOsi.1.13.6.dylib
10c4ed000-10c4ef000 rw- /usr/local/Cellar/coinutils/2.11.4_1/lib/libCoinUtils.3.11.4.dylib
10c4ef000-10c5a3000 r-x /usr/local/Cellar/coinutils/2.11.4_1/lib/libCoinUtils.3.11.4.dylib
10c5a3000-10c5a7000 r-- /usr/local/Cellar/coinutils/2.11.4_1/lib/libCoinUtils.3.11.4.dylib
10c5a7000-10c5ab000 rw- /usr/local/Cellar/coinutils/2.11.4_1/lib/libCoinUtils.3.11.4.dylib
10c5ab000-10c5da000 r-- /usr/local/Cellar/coinutils/2.11.4_1/lib/libCoinUtils.3.11.4.dylib
10c5da000-10c5db000 rw- /usr/local/Cellar/openblas/0.3.13/lib/libopenblasp-r0.3.13.dylib
10c5db000-10fef7000 r-x /usr/local/Cellar/openblas/0.3.13/lib/libopenblasp-r0.3.13.dylib
10fef7000-10ff0f000 rw- /usr/local/Cellar/openblas/0.3.13/lib/libopenblasp-r0.3.13.dylib
10ff0f000-10ff1b000 rw- /usr/local/Cellar/openblas/0.3.13/lib/libopenblasp-r0.3.13.dylib
10ff1b000-11009a000 r-- /usr/local/Cellar/openblas/0.3.13/lib/libopenblasp-r0.3.13.dylib
11009a000-11009b000 rw- /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libgfortran.5.dylib
11009b000-110347000 r-x /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libgfortran.5.dylib
110347000-11034b000 r-- /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libgfortran.5.dylib
11034b000-11034f000 rw- /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libgfortran.5.dylib
11034f000-1103ca000 r-- /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libgfortran.5.dylib
1103ca000-1103cb000 rw- /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libgomp.1.dylib
1103cb000-110403000 r-x /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libgomp.1.dylib
110403000-110407000 r-- /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libgomp.1.dylib
110407000-11040b000 rw- /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libgomp.1.dylib
11040b000-110427000 r-- /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libgomp.1.dylib
110427000-110467000 r-x /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libquadmath.0.dylib
110467000-11046b000 r-- /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libquadmath.0.dylib
11046b000-11046f000 rw- /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libquadmath.0.dylib
11046f000-11047c000 r-- /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libquadmath.0.dylib
11047c000-11047f000 rw- /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libgcc_s.1.dylib
11047f000-110497000 r-x /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libgcc_s.1.dylib
110497000-11049b000 rw- /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libgcc_s.1.dylib
11049b000-1104a5000 r-- /usr/local/Cellar/gcc/10.2.0/lib/gcc/10/libgcc_s.1.dylib
1104a5000-1104a7000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/stringio.bundle
1104a7000-1184a7000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/stringio.bundle
1184a7000-1204a7000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/stringio.bundle
1204a7000-1284a7000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/stringio.bundle
1284a7000-1304a7000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/stringio.bundle
1304a7000-1384a7000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/stringio.bundle
1384a7000-1404a7000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/stringio.bundle
1404a7000-1404af000 r-x /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/stringio.bundle
1404af000-1404b3000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/stringio.bundle
1404b3000-1404b7000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/stringio.bundle
1404b7000-1404bb000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/stringio.bundle
1404bb000-1404fb000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/date_core.bundle
1404fb000-140543000 r-x /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/date_core.bundle
140543000-140547000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/date_core.bundle
140547000-14054b000 rw- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/date_core.bundle
14054b000-140565000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/ruby/2.7.0/x86_64-darwin20/date_core.bundle
140565000-140567000 rw- /Users/rl/.rbenv/versions/2.7.2/bin/ruby
140567000-140574000 r-- /Users/rl/.rbenv/versions/2.7.2/bin/ruby
140574000-140983000 r-- /Users/rl/.rbenv/versions/2.7.2/lib/libruby.2.7.dylib
140983000-1409e9000 r-- /usr/lib/system/libsystem_platform.dylib
1409e9000-141487000 r-- /usr/local/Cellar/or-tools/8.1/lib/libortools.8.1.dylib
141487000-1415f4000 r-- /Users/rl/repos/or-tools/lib/or_tools/ext.bundle
700001fe1000-700001fe2000 ---
700001fe2000-700002064000 rw-
700002064000-700002065000 ---
700002065000-700002267000 rw-
700002267000-700002268000 ---
700002268000-70000246a000 rw-
7ff201c00000-7ff201d00000 rw-
7ff201d00000-7ff201d1b000 rw-
7ff201d1b000-7ff201e1b000 rw-
7ff201e1b000-7ff201e2b000 rw-
7ff201e2b000-7ff201e8b000 rw-
7ff201e8b000-7ff201e9f000 rw-
7ff201e9f000-7ff201eba000 rw-
7ff201eba000-7ff201ed2000 rw-
7ff201ed2000-7ff201eef000 rw-
7ff201f00000-7ff202000000 rw-
7ff202000000-7ff202800000 rw-
7ff202800000-7ff204800000 rw-
7ff204800000-7ff205000000 rw-
7ff205000000-7ff205100000 rw-
7ff205100000-7ff205200000 rw-
7ff205200000-7ff205239000 rw-
7ff205239000-7ff205272000 rw-
7ff205272000-7ff2052ab000 rw-
7ff205300000-7ff205400000 rw-
7ff205400000-7ff205500000 rw-
7ff205500000-7ff205600000 rw-
7ff205600000-7ff205700000 rw-
7ff205700000-7ff205800000 rw-
7ff205800000-7ff206000000 rw-
7ff206000000-7ff206800000 rw-
7ff206800000-7ff207000000 rw-
7ff207000000-7ff207800000 rw-
7ff207800000-7ff207900000 rw-
7ff207900000-7ff207a00000 rw-
7ff207a00000-7ff207b00000 rw-
7ff207b00000-7ff207c00000 rw-
7ff207c00000-7ff207d00000 rw-
7ff207d00000-7ff207e00000 rw-
7ff208000000-7ff208800000 rw-
7ffee2557000-7ffee5d57000 ---
7ffee5d57000-7ffee6557000 rw-
7fff00000000-7fff80000000 r--
7fff80000000-7fff8023b000 r--
7fff8023b000-7fff80400000 rw-
7fff80400000-7fff88400000 r--
7fff88400000-7fff88600000 rw-
7fff88600000-7fff88800000 rw-
7fff88800000-7fff88a00000 rw-
7fff88a00000-7fff88c00000 rw-
7fff88c00000-7fff88e00000 rw-
7fff88e00000-7fff89000000 rw-
7fff89000000-7fff89200000 r--
7fff89200000-7fff89400000 rw-
7fff89400000-7fff8de00000 r--
7fff8de00000-7fff8e000000 rw-
7fff8e000000-7fffc0000000 r--
7fffc0000000-7fffffe00000 r--
7fffffe00000-7fffffe01000 r--
7fffffee3000-7fffffee4000 r-x
[IMPORTANT]
Don't forget to include the Crash Report log file under
DiagnosticReports directory in bug reports.

rake aborted!
SignalException: SIGABRT
/Users/rl/.rbenv/versions/2.7.2/bin/bundle:23:in load' /Users/rl/.rbenv/versions/2.7.2/bin/bundle:23:in

'
Tasks: TOP => test
(See full trace by running task with --trace)

or-tools fails to build.

Rice 4.0.2 seems to change where headers are placed which causes or-tools builds to fail..

The error log below is from macOS 10.15.7 with ruby 3.0.1 installed via rbenv.

Looking at the rice package is a single header file now?

% gem install or-tools

Building native extensions. This could take a while...
ERROR: Error installing or-tools:
ERROR: Failed to build gem native extension.

current directory: /Users/stevenshack/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/or-tools-0.5.0/ext/or-tools

/Users/stevenshack/.rbenv/versions/3.0.1/bin/ruby -I /Users/stevenshack/.rbenv/versions/3.0.1/lib/ruby/3.0.0 -r ./siteconf20210520-25873-7tqtcn.rb extconf.rb
checking for rice/rice.hpp in /Users/stevenshack/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/rice-4.0.2/include... yes
checking for -lc++... yes
checking for -lstdc++... yes
checking for -lortools... yes
creating Makefile

current directory: /Users/stevenshack/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/or-tools-0.5.0/ext/or-tools
make DESTDIR= clean

current directory: /Users/stevenshack/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/or-tools-0.5.0/ext/or-tools
make DESTDIR=
compiling assignment.cpp
assignment.cpp:3:10: fatal error: 'rice/Array.hpp' file not found
#include <rice/Array.hpp>
^~~~~~~~~~~~~~~~
1 error generated.
make: *** [assignment.o] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/stevenshack/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/or-tools-0.5.0 for inspection.
Results logged to /Users/stevenshack/.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/extensions/x86_64-darwin-19/3.0.0/or-tools-0.5.0/gem_make.out

Doesn't build on M1 Mac

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /Users/ollym/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/or-tools-0.7.0/ext/or-tools
/Users/ollym/.rbenv/versions/3.1.0/bin/ruby -I /Users/ollym/.rbenv/versions/3.1.0/lib/ruby/site_ruby/3.1.0 -r
./siteconf20220525-14153-650tu6.rb extconf.rb
checking for rice/rice.hpp in /Users/ollym/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rice-4.0.4/include... yes
checking for -lc++... yes
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/Users/ollym/.rbenv/versions/3.1.0/bin/$(RUBY_BASE_NAME)
	--with-c++-dir
	--without-c++-dir
	--with-c++-include
	--without-c++-include=${c++-dir}/include
	--with-c++-lib
	--without-c++-lib=${c++-dir}/lib
	--with-c++lib
	--without-c++lib
	--with-or-tools-dir
	--without-or-tools-dir
	--with-or-tools-include
	--without-or-tools-include=${or-tools-dir}/include
	--with-or-tools-lib
	--without-or-tools-lib=${or-tools-dir}/lib
/Users/ollym/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/or-tools-0.7.0/ext/or-tools/vendor.rb:11:in `<top (required)>': Binary
installation not available for this platform: Mac ARM (RuntimeError)

Run:
brew install or-tools
bundle config build.or-tools --with-or-tools-dir=/opt/homebrew

	from extconf.rb:15:in `require_relative'
	from extconf.rb:15:in `<main>'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Users/ollym/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/extensions/arm64-darwin-21/3.1.0/or-tools-0.7.0/mkmf.log

extconf failed, exit code 1

Mac M1 (arm64) or-tools installation bug

Not caused by this gem but maybe someone already solved it. I'v followed instructions for README and when bundling received an error:

Installing or-tools 0.3.3 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/or-tools-0.3.3/ext/or-tools
/Users/artur/.rbenv/versions/2.6.6/bin/ruby -I /Users/artur/.rbenv/versions/2.6.6/lib/ruby/2.6.0 -r ./siteconf20220404-17366-xmbcyt.rb extconf.rb --with-or-tools-dir\=/opt/homebrew
/Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/rice-4.0.3/lib/mkmf-rice.rb:16: warning: already initialized constant MakeMakefile::CONFTEST_C
/Users/artur/.rbenv/versions/2.6.6/lib/ruby/2.6.0/mkmf.rb:259: warning: previous definition of CONFTEST_C was here
checking for rice/rice.hpp in /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/rice-4.0.3/include... yes
checking for -lc++... yes
checking for -lstdc++... yes
checking for -lortools... yes
creating Makefile

current directory: /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/or-tools-0.3.3/ext/or-tools
make "DESTDIR=" clean

current directory: /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/or-tools-0.3.3/ext/or-tools
make "DESTDIR="
compiling ext.cpp
clang: warning: argument unused during compilation: '-diag-disable=175,188,2259' [-Wunused-command-line-argument]
warning: unknown warning option '-Wduplicated-cond' [-Wunknown-warning-option]
warning: unknown warning option '-Wrestrict' [-Wunknown-warning-option]
warning: unknown warning option '-Wimplicit-fallthrough=0'; did you mean '-Wimplicit-fallthrough'? [-Wunknown-warning-option]
warning: unknown warning option '-Wno-packed-bitfield-compat' [-Wunknown-warning-option]
warning: unknown warning option '-Wsuggest-attribute=format'; did you mean '-Wproperty-attribute-mismatch'? [-Wunknown-warning-option]
warning: unknown warning option '-Wsuggest-attribute=noreturn' [-Wunknown-warning-option]
In file included from ext.cpp:4:
In file included from /opt/homebrew/include/ortools/constraint_solver/routing.h:179:
/opt/homebrew/include/ortools/base/map_util.h:173:1: error: 'auto' return without trailing return type; deduced return types are a C++14 extension
auto& InsertKeyOrDie(Collection* const collection,
^
/opt/homebrew/include/ortools/base/map_util.h:175:8: warning: decomposition declarations are a C++17 extension [-Wc++17-extensions]
  auto [it, did_insert] = collection->insert(typename Collection::value_type(
       ^~~~~~~~~~~~~~~~
In file included from ext.cpp:4:
In file included from /opt/homebrew/include/ortools/constraint_solver/routing.h:181:
In file included from /opt/homebrew/include/ortools/constraint_solver/constraint_solver.h:89:
In file included from /opt/homebrew/include/absl/random/random.h:40:
/opt/homebrew/include/absl/random/internal/randen_engine.h:70:3: warning: definition of implicit copy assignment operator for 'randen_engine<unsigned long long>' is deprecated because it has a user-declared copy
constructor [-Wdeprecated-copy]
  randen_engine(const randen_engine&) = default;
  ^
/opt/homebrew/include/absl/random/internal/nonsecure_base.h:53:61: note: in implicit copy assignment operator for 'absl::random_internal::randen_engine<unsigned long long>' first required here
  NonsecureURBGBase& operator=(NonsecureURBGBase&&) = default;
                                                            ^
/opt/homebrew/include/ortools/sat/util.h:97:20: note: in defaulted move assignment operator for 'absl::random_internal::NonsecureURBGBase<absl::random_internal::randen_engine<unsigned long long>>' first required
here
      absl_random_ = absl::BitGen(absl::SeedSeq({params.random_seed()}));
                   ^
In file included from ext.cpp:4:
In file included from /opt/homebrew/include/ortools/constraint_solver/routing.h:188:
In file included from /opt/homebrew/include/ortools/sat/theta_tree.h:21:
In file included from /opt/homebrew/include/ortools/sat/integer.h:42:
/opt/homebrew/include/ortools/sat/sat_solver.h:163:43: warning: loop variable 'p' creates a copy from type 'const std::pair<Literal, double>' [-Wrange-loop-construct]
    for (const std::pair<Literal, double> p : prefs) {
                                          ^
/opt/homebrew/include/ortools/sat/sat_solver.h:163:10: note: use reference type 'const std::pair<Literal, double> &' to prevent copying
    for (const std::pair<Literal, double> p : prefs) {
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                          &
ext.cpp:13:10: fatal error: 'rice/Array.hpp' file not found
#include <rice/Array.hpp>
         ^~~~~~~~~~~~~~~~
9 warnings and 2 errors generated.
make: *** [ext.o] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/or-tools-0.3.3 for inspection.
Results logged to /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/extensions/-darwin-21/2.6.0/or-tools-0.3.3/gem_make.out

  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/builder.rb:99:in `run'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/builder.rb:51:in `block in make'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/builder.rb:43:in `each'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/builder.rb:43:in `make'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/ext_conf_builder.rb:62:in `block in build'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/2.6.0/tempfile.rb:295:in `open'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/ext_conf_builder.rb:29:in `build'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/builder.rb:185:in `block in build_extension'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/2.6.0/monitor.rb:235:in `mon_synchronize'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/builder.rb:181:in `build_extension'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/builder.rb:229:in `block in build_extensions'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/builder.rb:226:in `each'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/ext/builder.rb:226:in `build_extensions'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/2.6.0/rubygems/installer.rb:830:in `build_extensions'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.2.31/lib/bundler/rubygems_gem_installer.rb:71:in `build_extensions'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.2.31/lib/bundler/rubygems_gem_installer.rb:28:in `install'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.2.31/lib/bundler/source/rubygems.rb:200:in `install'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.2.31/lib/bundler/installer/gem_installer.rb:54:in `install'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.2.31/lib/bundler/installer/gem_installer.rb:59:in `block in install_with_settings'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.2.31/lib/bundler/rubygems_integration.rb:575:in `install_with_build_args'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.2.31/lib/bundler/installer/gem_installer.rb:59:in `install_with_settings'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.2.31/lib/bundler/installer/gem_installer.rb:16:in `install_from_spec'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.2.31/lib/bundler/installer/parallel_installer.rb:186:in `do_install'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.2.31/lib/bundler/installer/parallel_installer.rb:177:in `block in worker_pool'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.2.31/lib/bundler/worker.rb:62:in `apply_func'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.2.31/lib/bundler/worker.rb:57:in `block in process_queue'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.2.31/lib/bundler/worker.rb:54:in `loop'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.2.31/lib/bundler/worker.rb:54:in `process_queue'
  /Users/artur/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.2.31/lib/bundler/worker.rb:91:in `block (2 levels) in create_threads'

An error occurred while installing or-tools (0.3.3), and Bundler cannot continue.

In Gemfile:
  or-tools

[$200 Bounty] Doctor Appointment Problem

We need a model built to solve a specific problem but I figured instead of spending hours understanding OR Tools and doing it ourself, someone here who's got a spare 20 minutes or so might be interested in helping us out?

The first post on this issue with the correct answer I'll transfer $200 to an account of your choosing (ACH/Wire/PayPal, etc.)

The problem is this:

# Figure out a way to schedule appointments to the least number of doctors possible

appointments = [
  [ "A1", { starts_at: Time.parse("2022-05-14T12:30:00-06:00"), ends_at: Time.parse("2022-05-14T15:00:00-06:00") }],
  [ "B1", { starts_at: Time.parse("2022-05-14T13:30:00-06:00"), ends_at: Time.parse("2022-05-14T17:00:00-06:00") }],
  [ "C1", { starts_at: Time.parse("2022-05-14T13:30:00-06:00"), ends_at: Time.parse("2022-05-14T17:00:00-06:00") }],
  [ "D1", { starts_at: Time.parse("2022-05-14T13:30:00-06:00"), ends_at: Time.parse("2022-05-14T17:00:00-06:00") }],
  [ "E1", { starts_at: Time.parse("2022-05-14T11:00:00-06:00"), ends_at: Time.parse("2022-05-14T12:30:00-06:00") }],
  [ "F1", { starts_at: Time.parse("2022-05-14T11:00:00-06:00"), ends_at: Time.parse("2022-05-14T12:30:00-06:00") }],
  [ "G1", { starts_at: Time.parse("2022-05-14T11:00:00-06:00"), ends_at: Time.parse("2022-05-14T12:30:00-06:00") }],
  [ "H1", { starts_at: Time.parse("2022-05-14T11:00:00-06:00"), ends_at: Time.parse("2022-05-14T12:30:00-06:00") }],
  [ "I1", { starts_at: Time.parse("2022-05-14T11:00:00-06:00"), ends_at: Time.parse("2022-05-14T12:30:00-06:00") }],
  [ "J1", { starts_at: Time.parse("2022-05-14T11:00:00-06:00"), ends_at: Time.parse("2022-05-14T12:30:00-06:00") }],
  [ "K1", { starts_at: Time.parse("2022-05-14T11:00:00-06:00"), ends_at: Time.parse("2022-05-14T12:30:00-06:00") }],
  [ "L1", { starts_at: Time.parse("2022-05-14T11:00:00-06:00"), ends_at: Time.parse("2022-05-14T12:30:00-06:00") }],
  [ "M1", { starts_at: Time.parse("2022-05-14T11:00:00-06:00"), ends_at: Time.parse("2022-05-14T12:30:00-06:00") }],
  [ "N1", { starts_at: Time.parse("2022-05-14T11:00:00-06:00"), ends_at: Time.parse("2022-05-14T12:30:00-06:00") }],
  [ "O1", { starts_at: Time.parse("2022-05-14T11:00:00-06:00"), ends_at: Time.parse("2022-05-14T12:30:00-06:00") }],
  [ "P1", { starts_at: Time.parse("2022-05-14T11:00:00-06:00"), ends_at: Time.parse("2022-05-14T12:30:00-06:00") }],
  [ "Q1", { starts_at: Time.parse("2022-05-14T12:30:00-06:00"), ends_at: Time.parse("2022-05-14T15:00:00-06:00") }],
  [ "R1", { starts_at: Time.parse("2022-05-14T12:30:00-06:00"), ends_at: Time.parse("2022-05-14T15:00:00-06:00") }],
  [ "S1", { starts_at: Time.parse("2022-05-14T12:30:00-06:00"), ends_at: Time.parse("2022-05-14T15:00:00-06:00") }],
  [ "T1", { starts_at: Time.parse("2022-05-14T12:00:00-06:00"), ends_at: Time.parse("2022-05-14T13:30:00-06:00") }],
  [ "U1", { starts_at: Time.parse("2022-05-14T12:00:00-06:00"), ends_at: Time.parse("2022-05-14T13:30:00-06:00") }],
  [ "V1", { starts_at: Time.parse("2022-05-14T12:00:00-06:00"), ends_at: Time.parse("2022-05-14T13:30:00-06:00") }],
  [ "W1", { starts_at: Time.parse("2022-05-14T12:00:00-06:00"), ends_at: Time.parse("2022-05-14T13:30:00-06:00") }],
  [ "X1", { starts_at: Time.parse("2022-05-14T12:00:00-06:00"), ends_at: Time.parse("2022-05-14T13:30:00-06:00") }],
  [ "Y1", { starts_at: Time.parse("2022-05-14T12:00:00-06:00"), ends_at: Time.parse("2022-05-14T13:30:00-06:00") }],
  [ "Z1", { starts_at: Time.parse("2022-05-14T12:00:00-06:00"), ends_at: Time.parse("2022-05-14T13:30:00-06:00") }],
  [ "A2", { starts_at: Time.parse("2022-05-14T12:00:00-06:00"), ends_at: Time.parse("2022-05-14T13:30:00-06:00") }],
  [ "B2", { starts_at: Time.parse("2022-05-14T12:00:00-06:00"), ends_at: Time.parse("2022-05-14T13:30:00-06:00") }],
  [ "C2", { starts_at: Time.parse("2022-05-14T12:00:00-06:00"), ends_at: Time.parse("2022-05-14T13:30:00-06:00") }],
  [ "D2", { starts_at: Time.parse("2022-05-14T12:00:00-06:00"), ends_at: Time.parse("2022-05-14T13:30:00-06:00") }],
  [ "E2", { starts_at: Time.parse("2022-05-14T12:00:00-06:00"), ends_at: Time.parse("2022-05-14T13:30:00-06:00") }],
  [ "F2", { starts_at: Time.parse("2022-05-14T14:00:00-06:00"), ends_at: Time.parse("2022-05-14T15:30:00-06:00") }],
  [ "G2", { starts_at: Time.parse("2022-05-14T14:00:00-06:00"), ends_at: Time.parse("2022-05-14T15:30:00-06:00") }],
  [ "H2", { starts_at: Time.parse("2022-05-14T14:00:00-06:00"), ends_at: Time.parse("2022-05-14T15:30:00-06:00") }],
  [ "I2", { starts_at: Time.parse("2022-05-14T14:00:00-06:00"), ends_at: Time.parse("2022-05-14T15:30:00-06:00") }],
  [ "J2", { starts_at: Time.parse("2022-05-14T15:00:00-06:00"), ends_at: Time.parse("2022-05-14T16:30:00-06:00") }],
  [ "K2", { starts_at: Time.parse("2022-05-14T15:00:00-06:00"), ends_at: Time.parse("2022-05-14T16:30:00-06:00") }],
  [ "L2", { starts_at: Time.parse("2022-05-14T15:00:00-06:00"), ends_at: Time.parse("2022-05-14T16:30:00-06:00") }],
  [ "M2", { starts_at: Time.parse("2022-05-14T15:00:00-06:00"), ends_at: Time.parse("2022-05-14T16:30:00-06:00") }],
  [ "N2", { starts_at: Time.parse("2022-05-14T15:00:00-06:00"), ends_at: Time.parse("2022-05-14T16:30:00-06:00") }],
  [ "O2", { starts_at: Time.parse("2022-05-14T15:00:00-06:00"), ends_at: Time.parse("2022-05-14T16:30:00-06:00") }],
  [ "P2", { starts_at: Time.parse("2022-05-14T15:00:00-06:00"), ends_at: Time.parse("2022-05-14T16:30:00-06:00") }],
  [ "Q2", { starts_at: Time.parse("2022-05-14T15:00:00-06:00"), ends_at: Time.parse("2022-05-14T16:30:00-06:00") }],
  [ "R2", { starts_at: Time.parse("2022-05-14T15:00:00-06:00"), ends_at: Time.parse("2022-05-14T16:30:00-06:00") }],
  [ "S2", { starts_at: Time.parse("2022-05-14T15:00:00-06:00"), ends_at: Time.parse("2022-05-14T16:30:00-06:00") }],
  [ "T2", { starts_at: Time.parse("2022-05-14T15:00:00-06:00"), ends_at: Time.parse("2022-05-14T16:30:00-06:00") }],
  [ "U2", { starts_at: Time.parse("2022-05-14T15:00:00-06:00"), ends_at: Time.parse("2022-05-14T16:30:00-06:00") }],
  [ "V2", { starts_at: Time.parse("2022-05-14T14:00:00-06:00"), ends_at: Time.parse("2022-05-14T15:30:00-06:00") }],
  [ "W2", { starts_at: Time.parse("2022-05-14T14:00:00-06:00"), ends_at: Time.parse("2022-05-14T15:30:00-06:00") }],
  [ "X2", { starts_at: Time.parse("2022-05-14T14:00:00-06:00"), ends_at: Time.parse("2022-05-14T15:30:00-06:00") }],
  [ "Y2", { starts_at: Time.parse("2022-05-14T14:00:00-06:00"), ends_at: Time.parse("2022-05-14T15:30:00-06:00") }],
  [ "Z2", { starts_at: Time.parse("2022-05-14T14:00:00-06:00"), ends_at: Time.parse("2022-05-14T15:30:00-06:00") }],
  [ "A2", { starts_at: Time.parse("2022-05-14T14:00:00-06:00"), ends_at: Time.parse("2022-05-14T15:30:00-06:00") }],
  [ "B2", { starts_at: Time.parse("2022-05-14T14:00:00-06:00"), ends_at: Time.parse("2022-05-14T15:30:00-06:00") }],
  [ "C2", { starts_at: Time.parse("2022-05-14T10:00:00-06:00"), ends_at: Time.parse("2022-05-14T11:30:00-06:00") }],
  [ "D2", { starts_at: Time.parse("2022-05-14T10:00:00-06:00"), ends_at: Time.parse("2022-05-14T11:30:00-06:00") }],
  [ "E2", { starts_at: Time.parse("2022-05-14T10:00:00-06:00"), ends_at: Time.parse("2022-05-14T11:30:00-06:00") }],
  [ "F2", { starts_at: Time.parse("2022-05-14T10:00:00-06:00"), ends_at: Time.parse("2022-05-14T11:30:00-06:00") }],
  [ "G2", { starts_at: Time.parse("2022-05-14T10:00:00-06:00"), ends_at: Time.parse("2022-05-14T11:30:00-06:00") }],
  [ "H2", { starts_at: Time.parse("2022-05-14T10:00:00-06:00"), ends_at: Time.parse("2022-05-14T11:30:00-06:00") }],
  [ "I2", { starts_at: Time.parse("2022-05-14T10:00:00-06:00"), ends_at: Time.parse("2022-05-14T11:30:00-06:00") }],
  [ "J2", { starts_at: Time.parse("2022-05-14T10:00:00-06:00"), ends_at: Time.parse("2022-05-14T11:30:00-06:00") }],
  [ "K2", { starts_at: Time.parse("2022-05-14T10:00:00-06:00"), ends_at: Time.parse("2022-05-14T11:30:00-06:00") }],
  [ "L2", { starts_at: Time.parse("2022-05-14T10:00:00-06:00"), ends_at: Time.parse("2022-05-14T11:30:00-06:00") }],
  [ "M2", { starts_at: Time.parse("2022-05-14T10:00:00-06:00"), ends_at: Time.parse("2022-05-14T11:30:00-06:00") }],
  [ "N2", { starts_at: Time.parse("2022-05-14T10:00:00-06:00"), ends_at: Time.parse("2022-05-14T11:30:00-06:00") }],
  [ "O2", { starts_at: Time.parse("2022-05-14T13:00:00-06:00"), ends_at: Time.parse("2022-05-14T14:30:00-06:00") }],
  [ "P2", { starts_at: Time.parse("2022-05-14T13:00:00-06:00"), ends_at: Time.parse("2022-05-14T14:30:00-06:00") }],
  [ "Q2", { starts_at: Time.parse("2022-05-14T13:00:00-06:00"), ends_at: Time.parse("2022-05-14T14:30:00-06:00") }],
  [ "R2", { starts_at: Time.parse("2022-05-14T13:00:00-06:00"), ends_at: Time.parse("2022-05-14T14:30:00-06:00") }],
  [ "S2", { starts_at: Time.parse("2022-05-14T13:00:00-06:00"), ends_at: Time.parse("2022-05-14T14:30:00-06:00") }],
  [ "T2", { starts_at: Time.parse("2022-05-14T13:00:00-06:00"), ends_at: Time.parse("2022-05-14T14:30:00-06:00") }],
  [ "U2", { starts_at: Time.parse("2022-05-14T13:00:00-06:00"), ends_at: Time.parse("2022-05-14T14:30:00-06:00") }],
  [ "V2", { starts_at: Time.parse("2022-05-14T13:00:00-06:00"), ends_at: Time.parse("2022-05-14T14:30:00-06:00") }],
  [ "W2", { starts_at: Time.parse("2022-05-14T13:00:00-06:00"), ends_at: Time.parse("2022-05-14T14:30:00-06:00") }],
  [ "X2", { starts_at: Time.parse("2022-05-14T13:00:00-06:00"), ends_at: Time.parse("2022-05-14T14:30:00-06:00") }],
  [ "Y2", { starts_at: Time.parse("2022-05-14T13:00:00-06:00"), ends_at: Time.parse("2022-05-14T14:30:00-06:00") }],
  [ "Z2", { starts_at: Time.parse("2022-05-14T13:00:00-06:00"), ends_at: Time.parse("2022-05-14T14:30:00-06:00") }]
]

doctors = [ "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" ]

# solve to schedule appointments to doctors in a way that requires the least number of doctors.
# the same doctor cannot have an overlapping appointment
# and there's no limit to how many appointments a doctor can have
# output like:

output = {
  "1" => ["A1", "B1", "C1"],
  "2" => ["P1"],
  #...etc
}

# Where the output key is the doctor and the value is an array of appointments assigned to them

Feature request SetStartValue

The python API for or-tools has a number of useful tools for setting values and ranges - particularly useful for VRP problems. Could we add:

SetStartValue
setstartmin
setstartmax
setstartrange

setendmin
setendmax
setendrange
setendvalue

I believe these should make it easier to for example set the starting time of a vehicle (no more midnight deliveries!).
Further making it easier to directly use the planners output without adding or subtracting error prone time offsets.

Error installing gem

after install the gem, i run the rails console and get this error :(

3:03 $ rails c

The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.

/usr/local/rvm/gems/ruby-2.5.3/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require': libortools.so: cannot open shared object file: No such file or directory - /usr/local/rvm/gems/ruby-2.5.3/gems/or-tools-0.2.0/lib/or_tools/ext.so (LoadError)

the ext.so file exists
image

tried on a rvm version 2.5.3 and 2.4.1, same error

also installed the or-tools from source, without any problem.

Thanks in advance.

Gem installation in macOS Catalina 10.15.7

Hi, I'm having a problem installing gem.
I run:
gem install or-tools -v '0.4.0'
and I get the error below:

Building native extensions. This could take a while...
ERROR:  Error installing or-tools:
	ERROR: Failed to build gem native extension.

    current directory: /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/ext/or-tools
/Users/stevenchern/.rbenv/versions/2.6.3/bin/ruby -I /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/2.6.0 -r ./siteconf20210217-92877-129hv8h.rb extconf.rb
checking for -lstdc++... yes
checking for -lortools... yes
creating Makefile

current directory: /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/ext/or-tools
make "DESTDIR=" clean

current directory: /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/ext/or-tools
make "DESTDIR="
compiling ext.cpp
In file included from ext.cpp:4:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/constraint_solver/routing.h:186:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/lp_solver.h:20:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/preprocessor.h:27:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/revised_simplex.h:99:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/basis_representation.h:18:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/lu_factorization.h:17:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/markowitz.h:84:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/sparse.h:38:
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/sparse_column.h:102:21: warning: loop variable 'e' of type 'const operations_research::glop::SparseColumnEntry' creates a copy from type 'const operations_research::glop::SparseColumnEntry' [-Wrange-loop-analysis]
    for (const auto e : *this) {
                    ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/sparse_column.h:102:10: note: use reference type 'const operations_research::glop::SparseColumnEntry &' to prevent copying
    for (const auto e : *this) {
         ^~~~~~~~~~~~~~
                    &
In file included from ext.cpp:4:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/constraint_solver/routing.h:186:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/lp_solver.h:20:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/preprocessor.h:27:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/revised_simplex.h:99:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/basis_representation.h:20:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/rank_one_update.h:19:
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/lp_utils.h:84:34: warning: loop variable 'e' of type 'const SparseColumn::Entry' (aka 'const operations_research::glop::SparseColumnEntry') creates a copy from type 'const SparseColumn::Entry' [-Wrange-loop-analysis]
  for (const SparseColumn::Entry e : v) {
                                 ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/lp_utils.h:84:8: note: use reference type 'const SparseColumn::Entry &' (aka 'const operations_research::glop::SparseColumnEntry &') to prevent copying
  for (const SparseColumn::Entry e : v) {
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                 &
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/lp_utils.h:106:34: warning: loop variable 'e' of type 'const SparseColumn::Entry' (aka 'const operations_research::glop::SparseColumnEntry') creates a copy from type 'const SparseColumn::Entry' [-Wrange-loop-analysis]
  for (const SparseColumn::Entry e : v) {
                                 ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/lp_utils.h:106:8: note: use reference type 'const SparseColumn::Entry &' (aka 'const operations_research::glop::SparseColumnEntry &') to prevent copying
  for (const SparseColumn::Entry e : v) {
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                 &
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/lp_utils.h:121:19: warning: loop variable 'e' of type 'const operations_research::glop::ScatteredColumnEntry' creates a copy from type 'const operations_research::glop::ScatteredColumnEntry' [-Wrange-loop-analysis]
  for (const auto e : v) {
                  ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/lp_utils.h:121:8: note: use reference type 'const operations_research::glop::ScatteredColumnEntry &' to prevent copying
  for (const auto e : v) {
       ^~~~~~~~~~~~~~
                  &
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/lp_utils.h:133:34: warning: loop variable 'e' of type 'const SparseColumn::Entry' (aka 'const operations_research::glop::SparseColumnEntry') creates a copy from type 'const SparseColumn::Entry' [-Wrange-loop-analysis]
  for (const SparseColumn::Entry e : v) {
                                 ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/lp_utils.h:133:8: note: use reference type 'const SparseColumn::Entry &' (aka 'const operations_research::glop::SparseColumnEntry &') to prevent copying
  for (const SparseColumn::Entry e : v) {
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                 &
In file included from ext.cpp:4:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/constraint_solver/routing.h:191:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/theta_tree.h:20:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/integer.h:39:
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_base.h:114:22: warning: loop variable 'literal' of type 'const operations_research::sat::Literal' creates a copy from type 'const operations_research::sat::Literal' [-Wrange-loop-analysis]
  for (const Literal literal : literals) {
                     ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_base.h:114:8: note: use reference type 'const operations_research::sat::Literal &' to prevent copying
  for (const Literal literal : literals) {
       ^~~~~~~~~~~~~~~~~~~~~~~
                     &
In file included from ext.cpp:4:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/constraint_solver/routing.h:191:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/theta_tree.h:20:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/integer.h:40:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_solver.h:38:
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/clause.h:128:24: warning: loop variable 'l' of type 'const operations_research::sat::Literal' creates a copy from type 'const operations_research::sat::Literal' [-Wrange-loop-analysis]
    for (const Literal l : new_clause) literals_[size_++] = l;
                       ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/clause.h:128:10: note: use reference type 'const operations_research::sat::Literal &' to prevent copying
    for (const Literal l : new_clause) literals_[size_++] = l;
         ^~~~~~~~~~~~~~~~~
                       &
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/clause.h:654:26: warning: loop variable 'b' of type 'const operations_research::sat::Literal' creates a copy from type 'const operations_research::sat::Literal' [-Wrange-loop-analysis]
      for (const Literal b : implications_[i]) {
                         ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/clause.h:654:12: note: use reference type 'const operations_research::sat::Literal &' to prevent copying
      for (const Literal b : implications_[i]) {
           ^~~~~~~~~~~~~~~~~
                         &
In file included from ext.cpp:4:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/constraint_solver/routing.h:191:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/theta_tree.h:20:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/integer.h:40:
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_solver.h:163:43: warning: loop variable 'p' of type 'const std::pair<Literal, double>' creates a copy from type 'const std::pair<Literal, double>' [-Wrange-loop-analysis]
    for (const std::pair<Literal, double> p : prefs) {
                                          ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_solver.h:163:10: note: use reference type 'const std::pair<Literal, double> &' to prevent copying
    for (const std::pair<Literal, double> p : prefs) {
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                          &
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_solver.h:882:24: warning: loop variable 'l' of type 'const operations_research::sat::Literal' creates a copy from type 'const operations_research::sat::Literal' [-Wrange-loop-analysis]
    for (const Literal l : literals) {
                       ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_solver.h:882:10: note: use reference type 'const operations_research::sat::Literal &' to prevent copying
    for (const Literal l : literals) {
         ^~~~~~~~~~~~~~~~~
                       &
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_solver.h:896:24: warning: loop variable 'l' of type 'const operations_research::sat::Literal' creates a copy from type 'const operations_research::sat::Literal' [-Wrange-loop-analysis]
    for (const Literal l : literals) {
                       ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_solver.h:896:10: note: use reference type 'const operations_research::sat::Literal &' to prevent copying
    for (const Literal l : literals) {
         ^~~~~~~~~~~~~~~~~
                       &
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_solver.h:910:24: warning: loop variable 'l' of type 'const operations_research::sat::Literal' creates a copy from type 'const operations_research::sat::Literal' [-Wrange-loop-analysis]
    for (const Literal l : literals) {
                       ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_solver.h:910:10: note: use reference type 'const operations_research::sat::Literal &' to prevent copying
    for (const Literal l : literals) {
         ^~~~~~~~~~~~~~~~~
                       &
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_solver.h:939:24: warning: loop variable 'l' of type 'const operations_research::sat::Literal' creates a copy from type 'const operations_research::sat::Literal' [-Wrange-loop-analysis]
    for (const Literal l : literals) {
                       ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_solver.h:939:10: note: use reference type 'const operations_research::sat::Literal &' to prevent copying
    for (const Literal l : literals) {
         ^~~~~~~~~~~~~~~~~
                       &
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_solver.h:956:24: warning: loop variable 'l' of type 'const operations_research::sat::Literal' creates a copy from type 'const operations_research::sat::Literal' [-Wrange-loop-analysis]
    for (const Literal l : enforcement_literals) {
                       ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_solver.h:956:10: note: use reference type 'const operations_research::sat::Literal &' to prevent copying
    for (const Literal l : enforcement_literals) {
         ^~~~~~~~~~~~~~~~~
                       &
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_solver.h:959:24: warning: loop variable 'l' of type 'const operations_research::sat::Literal' creates a copy from type 'const operations_research::sat::Literal' [-Wrange-loop-analysis]
    for (const Literal l : clause) {
                       ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_solver.h:959:10: note: use reference type 'const operations_research::sat::Literal &' to prevent copying
    for (const Literal l : clause) {
         ^~~~~~~~~~~~~~~~~
                       &
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_solver.h:973:24: warning: loop variable 'l' of type 'const operations_research::sat::Literal' creates a copy from type 'const operations_research::sat::Literal' [-Wrange-loop-analysis]
    for (const Literal l : literals) {
                       ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/sat_solver.h:973:10: note: use reference type 'const operations_research::sat::Literal &' to prevent copying
    for (const Literal l : literals) {
         ^~~~~~~~~~~~~~~~~
                       &
In file included from ext.cpp:4:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/constraint_solver/routing.h:191:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/theta_tree.h:20:
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/integer.h:1529:26: warning: loop variable 'literal' of type 'const operations_research::sat::Literal' creates a copy from type 'const operations_research::sat::Literal' [-Wrange-loop-analysis]
      for (const Literal literal : enforcement_literals) {
                         ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/integer.h:1529:12: note: use reference type 'const operations_research::sat::Literal &' to prevent copying
      for (const Literal literal : enforcement_literals) {
           ^~~~~~~~~~~~~~~~~~~~~~~
                         &
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/integer.h:1538:26: warning: loop variable 'literal' of type 'const operations_research::sat::Literal' creates a copy from type 'const operations_research::sat::Literal' [-Wrange-loop-analysis]
      for (const Literal literal : enforcement_literals) {
                         ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/integer.h:1538:12: note: use reference type 'const operations_research::sat::Literal &' to prevent copying
      for (const Literal literal : enforcement_literals) {
           ^~~~~~~~~~~~~~~~~~~~~~~
                         &
In file included from ext.cpp:4:
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/constraint_solver/routing.h:629:33: warning: loop variable 'disjunction' of type 'const operations_research::RoutingModel::DisjunctionIndex' (aka 'const IntType<operations_research::RoutingDisjunctionIndex_tag_, int>') creates a copy from type 'const operations_research::RoutingModel::DisjunctionIndex' [-Wrange-loop-analysis]
    for (const DisjunctionIndex disjunction : GetDisjunctionIndices(index)) {
                                ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/constraint_solver/routing.h:629:10: note: use reference type 'const operations_research::RoutingModel::DisjunctionIndex &' (aka 'const IntType<operations_research::RoutingDisjunctionIndex_tag_, int> &') to prevent copying
    for (const DisjunctionIndex disjunction : GetDisjunctionIndices(index)) {
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                &
In file included from ext.cpp:13:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rice-3.0.0/ruby/lib/include/rice/Array.hpp:4:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rice-3.0.0/ruby/lib/include/rice/Builtin_Object.hpp:4:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rice-3.0.0/ruby/lib/include/rice/Builtin_Object_defn.hpp:4:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rice-3.0.0/ruby/lib/include/rice/Object_defn.hpp:7:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rice-3.0.0/ruby/lib/include/rice/Identifier.hpp:4:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rice-3.0.0/ruby/lib/include/rice/detail/ruby.hpp:20:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/include/ruby-2.6.0/ruby.h:33:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/include/ruby-2.6.0/ruby/ruby.h:2111:
/Users/stevenchern/.rbenv/versions/2.6.3/include/ruby-2.6.0/ruby/intern.h:56:19: error: ISO C++17 does not allow 'register' storage class specifier [-Wregister]
void rb_mem_clear(register VALUE*, register long);
                  ^~~~~~~~~
/Users/stevenchern/.rbenv/versions/2.6.3/include/ruby-2.6.0/ruby/intern.h:56:36: error: ISO C++17 does not allow 'register' storage class specifier [-Wregister]
void rb_mem_clear(register VALUE*, register long);
                                   ^~~~~~~~~
In file included from ext.cpp:4:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/constraint_solver/routing.h:186:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/lp_solver.h:20:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/preprocessor.h:27:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/revised_simplex.h:99:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/basis_representation.h:18:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/lu_factorization.h:17:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/markowitz.h:84:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/sparse.h:37:
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/scattered_vector.h:148:22: warning: loop variable 'index' of type 'const gtl::IntType<operations_research::glop::ColIndex_tag_, int>' creates a copy from type 'const gtl::IntType<operations_research::glop::ColIndex_tag_, int>' [-Wrange-loop-analysis]
    for (const Index index : non_zeros) is_non_zero[index] = true;
                     ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/rank_one_update.h:173:8: note: in instantiation of member function 'operations_research::glop::ScatteredVector<gtl::IntType<operations_research::glop::ColIndex_tag_, int>, operations_research::glop::VectorIterator<operations_research::glop::ScatteredRowEntry> >::RepopulateSparseMask' requested here
    y->RepopulateSparseMask();
       ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/scattered_vector.h:148:10: note: use reference type 'const gtl::IntType<operations_research::glop::ColIndex_tag_, int> &' to prevent copying
    for (const Index index : non_zeros) is_non_zero[index] = true;
         ^~~~~~~~~~~~~~~~~~~
                     &
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/scattered_vector.h:138:24: warning: loop variable 'index' of type 'const gtl::IntType<operations_research::glop::ColIndex_tag_, int>' creates a copy from type 'const gtl::IntType<operations_research::glop::ColIndex_tag_, int>' [-Wrange-loop-analysis]
      for (const Index index : non_zeros) {
                       ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/rank_one_update.h:183:8: note: in instantiation of member function 'operations_research::glop::ScatteredVector<gtl::IntType<operations_research::glop::ColIndex_tag_, int>, operations_research::glop::VectorIterator<operations_research::glop::ScatteredRowEntry> >::ClearSparseMask' requested here
    y->ClearSparseMask();
       ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/scattered_vector.h:138:12: note: use reference type 'const gtl::IntType<operations_research::glop::ColIndex_tag_, int> &' to prevent copying
      for (const Index index : non_zeros) {
           ^~~~~~~~~~~~~~~~~~~
                       &
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/scattered_vector.h:148:22: warning: loop variable 'index' of type 'const gtl::IntType<operations_research::glop::RowIndex_tag_, int>' creates a copy from type 'const gtl::IntType<operations_research::glop::RowIndex_tag_, int>' [-Wrange-loop-analysis]
    for (const Index index : non_zeros) is_non_zero[index] = true;
                     ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/rank_one_update.h:207:8: note: in instantiation of member function 'operations_research::glop::ScatteredVector<gtl::IntType<operations_research::glop::RowIndex_tag_, int>, operations_research::glop::VectorIterator<operations_research::glop::ScatteredColumnEntry> >::RepopulateSparseMask' requested here
    d->RepopulateSparseMask();
       ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/scattered_vector.h:148:10: note: use reference type 'const gtl::IntType<operations_research::glop::RowIndex_tag_, int> &' to prevent copying
    for (const Index index : non_zeros) is_non_zero[index] = true;
         ^~~~~~~~~~~~~~~~~~~
                     &
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/scattered_vector.h:138:24: warning: loop variable 'index' of type 'const gtl::IntType<operations_research::glop::RowIndex_tag_, int>' creates a copy from type 'const gtl::IntType<operations_research::glop::RowIndex_tag_, int>' [-Wrange-loop-analysis]
      for (const Index index : non_zeros) {
                       ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/glop/rank_one_update.h:218:8: note: in instantiation of member function 'operations_research::glop::ScatteredVector<gtl::IntType<operations_research::glop::RowIndex_tag_, int>, operations_research::glop::VectorIterator<operations_research::glop::ScatteredColumnEntry> >::ClearSparseMask' requested here
    d->ClearSparseMask();
       ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/lp_data/scattered_vector.h:138:12: note: use reference type 'const gtl::IntType<operations_research::glop::RowIndex_tag_, int> &' to prevent copying
      for (const Index index : non_zeros) {
           ^~~~~~~~~~~~~~~~~~~
                       &
In file included from ext.cpp:4:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/constraint_solver/routing.h:180:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/constraint_solver/constraint_solver.h:91:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/util/piecewise_linear_function.h:32:
In file included from /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/util/saturated_arithmetic.h:19:
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/util/bitset.h:773:28: warning: loop variable 'i' of type 'const gtl::IntType<operations_research::sat::BooleanVariable_tag_, int>' creates a copy from type 'const gtl::IntType<operations_research::sat::BooleanVariable_tag_, int>' [-Wrange-loop-analysis]
    for (const IntegerType i : to_clear_) bitset_.ClearBucket(i);
                           ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/util/bitset.h:784:7: note: in instantiation of member function 'operations_research::SparseBitset<gtl::IntType<operations_research::sat::BooleanVariable_tag_, int> >::SparseClearAll' requested here
      SparseClearAll();
      ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/pb_constraint.h:694:11: note: in instantiation of member function 'operations_research::SparseBitset<gtl::IntType<operations_research::sat::BooleanVariable_tag_, int> >::ClearAndResize' requested here
    seen_.ClearAndResize(BooleanVariable(num_variables));
          ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/util/bitset.h:773:10: note: use reference type 'const gtl::IntType<operations_research::sat::BooleanVariable_tag_, int> &' to prevent copying
    for (const IntegerType i : to_clear_) bitset_.ClearBucket(i);
         ^~~~~~~~~~~~~~~~~~~~~
                           &
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/util/bitset.h:773:28: warning: loop variable 'i' of type 'const gtl::IntType<operations_research::sat::IntegerVariable_tag_, int>' creates a copy from type 'const gtl::IntType<operations_research::sat::IntegerVariable_tag_, int>' [-Wrange-loop-analysis]
    for (const IntegerType i : to_clear_) bitset_.ClearBucket(i);
                           ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/util/bitset.h:784:7: note: in instantiation of member function 'operations_research::SparseBitset<gtl::IntType<operations_research::sat::IntegerVariable_tag_, int> >::SparseClearAll' requested here
      SparseClearAll();
      ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/sat/integer.h:787:8: note: in instantiation of member function 'operations_research::SparseBitset<gtl::IntType<operations_research::sat::IntegerVariable_tag_, int> >::ClearAndResize' requested here
    p->ClearAndResize(NumIntegerVariables());
       ^
/Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0/tmp/or-tools/include/ortools/util/bitset.h:773:10: note: use reference type 'const gtl::IntType<operations_research::sat::IntegerVariable_tag_, int> &' to prevent copying
    for (const IntegerType i : to_clear_) bitset_.ClearBucket(i);
         ^~~~~~~~~~~~~~~~~~~~~
                           &
25 warnings and 2 errors generated.
make: *** [ext.o] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/or-tools-0.4.0 for inspection.
Results logged to /Users/stevenchern/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/extensions/x86_64-darwin-19/2.6.0/or-tools-0.4.0/gem_make.out

Installing with Dokku

Hi I am trying to install or-tools 0.4.2 on a server using Dokku. I am using this heroku buildpack.

And I get this error:

Installing or-tools 0.4.2 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
       
       current directory:
       /tmp/build/vendor/bundle/ruby/2.7.0/gems/or-tools-0.4.2/ext/or-tools
       /tmp/build/vendor/ruby-2.7.0/bin/ruby -I
       /tmp/build/vendor/ruby-2.7.0/lib/ruby/2.7.0 -r ./siteconf20210326-371-180bap0.rb
       extconf.rb
       checking for -lstdc++... yes
       *** extconf.rb failed ***
       Could not create Makefile due to some reason, probably lack of necessary
       libraries and/or headers.  Check the mkmf.log file for more details.  You may
       need configuration options.
       
       Provided configuration options:
--with-opt-dir
--without-opt-dir
--with-opt-include
--without-opt-include=${opt-dir}/include
--with-opt-lib
--without-opt-lib=${opt-dir}/lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=/tmp/build/vendor/ruby-2.7.0/bin/$(RUBY_BASE_NAME)
--with-libpath
--without-libpath
--with-stdc++-dir
--without-stdc++-dir
--with-stdc++-include
--without-stdc++-include=${stdc++-dir}/include
--with-stdc++-lib
--without-stdc++-lib=${stdc++-dir}/lib
--with-stdc++lib
--without-stdc++lib
--with-or-tools-dir
--without-or-tools-dir
--with-or-tools-include
--without-or-tools-include=${or-tools-dir}/include
--with-or-tools-lib
--without-or-tools-lib=${or-tools-dir}/lib
       /tmp/build/vendor/bundle/ruby/2.7.0/gems/or-tools-0.4.2/ext/or-tools/vendor.rb:29:in
       `<top (required)>': Binary installation not available for this platform.
       (RuntimeError)
       
       Build the OR-Tools C++ library from source, then run:
       bundle config build.or-tools --with-or-tools-dir=/path/to/or-tools
       
       from extconf.rb:17:in `require_relative'
       from extconf.rb:17:in `<main>'
       
       To see why this extension failed to compile, please check the mkmf.log which can
       be found here:
       
       /tmp/build/vendor/bundle/ruby/2.7.0/extensions/x86_64-linux/2.7.0/or-tools-0.4.2/mkmf.log
       
       extconf failed, exit code 1
       
       Gem files will remain installed in
       /tmp/build/vendor/bundle/ruby/2.7.0/gems/or-tools-0.4.2 for inspection.
       Results logged to
       /tmp/build/vendor/bundle/ruby/2.7.0/extensions/x86_64-linux/2.7.0/or-tools-0.4.2/gem_make.out
       
       An error occurred while installing or-tools (0.4.2), and Bundler cannot
       continue.
       Make sure that `gem install or-tools -v '0.4.2' --source
       'https://rubygems.org/'` succeeds before bundling.

Can you help me? Thanks!

install it on openSUSE tumbleweed

Trying to install it on openSUSE Tumbleweed and having issues.

I have already the packages installed (see my zypper call in the end of the log) but the gem cannot find it.

kimura@linux-qouy:~/wongi/wongi-sandbox/subscriptions/or-tools-ruby> bundle exec rake compile
cd tmp/x86_64-linux/ext/3.2.2
/home/kimura/.rvm/rubies/ruby-3.2.2/bin/ruby -I. -r.rake-compiler-siteconf.rb ../../../../ext/or-tools/extconf.rb
checking for rice/rice.hpp in /home/kimura/.rvm/gems/ruby-3.2.2/gems/rice-4.1.0/include... yes
checking for -lstdc++... yes
*** ../../../../ext/or-tools/extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib64
	--with-make-prog
	--without-make-prog
	--srcdir=../../../../ext/or-tools
	--curdir
	--ruby=/home/kimura/.rvm/rubies/ruby-3.2.2/bin/$(RUBY_BASE_NAME)
	--with-stdc++-dir
	--without-stdc++-dir
	--with-stdc++-include
	--without-stdc++-include=${stdc++-dir}/include
	--with-stdc++-lib
	--without-stdc++-lib=${stdc++-dir}/lib64
	--with-stdc++lib
	--without-stdc++lib
	--with-or-tools-dir
	--without-or-tools-dir
	--with-or-tools-include
	--without-or-tools-include=${or-tools-dir}/include
	--with-or-tools-lib
	--without-or-tools-lib=${or-tools-dir}/lib64
/home/kimura/wongi/wongi-sandbox/subscriptions/or-tools-ruby/ext/or-tools/vendor.rb:61:in `<top (required)>': Binary installation not available for this platform: opensuse-tumbleweed 20230616 (RuntimeError)

Build the OR-Tools C++ library from source, then run:
bundle config build.or-tools --with-or-tools-dir=/path/to/or-tools


	from ../../../../ext/or-tools/extconf.rb:15:in `require_relative'
	from ../../../../ext/or-tools/extconf.rb:15:in `<main>'
rake aborted!
Command failed with status (1): [/home/kimura/.rvm/rubies/ruby-3.2.2/bin/...]
/home/kimura/.rvm/gems/ruby-3.2.2/gems/rake-compiler-1.2.3/lib/rake/extensiontask.rb:220:in `block (2 levels) in define_compile_tasks'
/home/kimura/.rvm/gems/ruby-3.2.2/gems/rake-compiler-1.2.3/lib/rake/extensiontask.rb:219:in `block in define_compile_tasks'
/home/kimura/.rvm/gems/ruby-3.2.2/bin/bundle:25:in `load'
/home/kimura/.rvm/gems/ruby-3.2.2/bin/bundle:25:in `<main>'
Tasks: TOP => compile => compile:x86_64-linux => compile:ext:x86_64-linux => copy:ext:x86_64-linux:3.2.2 => tmp/x86_64-linux/ext/3.2.2/ext.so => tmp/x86_64-linux/ext/3.2.2/Makefile
(See full trace by running task with --trace)
kimura@linux-qouy:~/wongi/wongi-sandbox/subscriptions/or-tools-ruby> zypper se or-tools
Loading repository data...
Reading installed packages...

S  | Name                      | Summary                                               | Type
---+---------------------------+-------------------------------------------------------+--------
   | eclipse-contributor-tools | Tools for Eclipse Contributors                        | package
i+ | google-or-tools           | Suite for solving combinatorial optimization problems | package
i+ | google-or-tools-devel     | Suite for solving combinatorial optimization problems | package
   | google-or-tools-minizinc  | OR-Tools minizinc solver                              | package
kimura@linux-qouy:~/wongi/wongi-sandbox/subscriptions/or-tools-ruby> 

Fails to build with Ubuntu 22.04 LTS

When installing this gem into a Ubuntu server (QEMU ARM VM), I get an ERROR: Failed to build gem native extension.

Full Error

current directory: /home/dev/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/or-tools-0.10.1/ext/or-tools

/home/dev/.asdf/installs/ruby/3.2.2/bin/ruby extconf.rb --with-or-tools-dir\=/home/dev/or-tools
checking for rice/rice.hpp in /home/dev/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/rice-4.1.0/include... yes
checking for -lstdc++... yes
checking for -lortools... yes
creating Makefile

current directory: /home/dev/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/or-tools-0.10.1/ext/or-tools
make DESTDIR\= sitearchdir\=./.gem.20231101-63192-jsji3m sitelibdir\=./.gem.20231101-63192-jsji3m clean

current directory: /home/dev/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/or-tools-0.10.1/ext/or-tools
make DESTDIR\= sitearchdir\=./.gem.20231101-63192-jsji3m sitelibdir\=./.gem.20231101-63192-jsji3m
compiling assignment.cpp
compiling bin_packing.cpp
compiling constraint.cpp
compiling ext.cpp
compiling linear.cpp
compiling network_flows.cpp
compiling routing.cpp
routing.cpp: In function ‘void init_routing(Rice::Module&)’:
routing.cpp:356:57: error: ‘GetPickupIndexPairs’ is not a member of ‘operations_research::RoutingModel’
  356 |     .define_method("pickup_index_pairs", &RoutingModel::GetPickupIndexPairs)
      |                                                         ^~~~~~~~~~~~~~~~~~~
routing.cpp:357:59: error: ‘GetDeliveryIndexPairs’ is not a member of ‘operations_research::RoutingModel’
  357 |     .define_method("delivery_index_pairs", &RoutingModel::GetDeliveryIndexPairs)
      |                                                           ^~~~~~~~~~~~~~~~~~~~~
At global scope:
cc1plus: note: unrecognized command-line option ‘-Wno-shorten-64-to-32’ may have been intended to silence earlier diagnostics
make: *** [Makefile:240: routing.o] Error 1

make failed, exit code 2

Specs

  • Command: gem install or-tools -- --with-or-tools-dir=/home/dev/or-tools
  • Ruby: ruby 3.2.2 (2023-03-30 revision e51014f9c0) [aarch64-linux]
  • OR Tools: v9.5, installed from their repo
  • VM OS: Linux 5.15.0-88-generic #98-Ubuntu SMP Mon Oct 2 15:23:16 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux
  • Host OS: Apple M1 Sonoma 14.1

Cannot sum bool vars into model

          model = ORTools::CpModel.new
          a = model.new_bool_var('a')
          b = model.new_bool_var('b')
          c = model.new_bool_var('c')
          model.add([a,b,c].sum < 1)
 undefined method `+' for an instance of ORTools::BoolVar (NoMethodError)

Using manylinux version for Apple Silicon

Hey, about #25 (comment) (i.e. adding a package once it's available)

I'm having issues getting the gem to install in docker (Debian Bullseye) on a MacBook M1 Max.

Someone from the ortools repo suggested using the manylinux package

Edit: what I mean is for you to make the gem to automatically use the manylinux package on arm64

Wdyt? Good idea? Did I misunderstand their answer?

extconf does not work with custom lib dirs.

I've compiled or-tools and installed into the system. Or-tools is installed into /usr/local.
Some libs are placed into /usr/local/lib, while others are /usr/local/lib64.
libprotobuf.a is on lib64.

I used flags --with-or-tools-dir=/usr/local --with-or-tools-lib=/usr/local/lib:/usr/local/lib64 to install the gem, but it doesn't work because extconf tries to find the library in a directory that doesn't exist (/usr/local/lib:/usr/local/lib64/libprotobuf.a).

M1 Silicon

Having issues getting the gem working on m1 silicon. Tried creating a new rails app, and just adding the gem just to make sure I don't have a conflict with something else but I am receiving the same error.

/Users/nano/.rbenv/versions/3.0.3/lib/ruby/gems/3.0.0/gems/bootsnap-1.9.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require': dlopen(/Users/nano/.rbenv/versions/3.0.3/lib/ruby/gems/3.0.0/gems/or-tools-0.6.0/lib/or_tools/ext.bundle, 0x0009): symbol not found in flat namespace '__ZN19operations_research10LinearExprC1EPKNS_10MPVariableE' - /Users/nano/.rbenv/versions/3.0.3/lib/ruby/gems/3.0.0/gems/or-tools-0.6.0/lib/or_tools/ext.bundle (LoadError)

Do you have any idea how can I fix this?

stop_search missing

Hey, so I was trying to convert this code from Python to Ruby using the following employee scheduling guide here. Towards the end, the Python calls StopSearch, but this isn't available in this lib.

Duno if this is the right approach but I had some success adding this definition into constraint.cpp

#include <ortools/sat/swig_helper.h>
using operations_research::sat::SolutionCallback;

Rice::define_class_under<SolutionCallback>(m, "SolutionCallback")
  .define_method("stop_search", &SolutionCallback::StopSearch);

then Updating cp_solver_solution_callback.rb to:

class CpSolverSolutionCallback < SolutionCallback

I could at least call the stop_search function in the NursesPartialSolutionPrinter from the guide. But I got stuck with the atomic bool here:

https://github.com/google/or-tools/blob/5425dedcfbb22cb74c636c1374a9b5ad684b1eb5/ortools/sat/swig_helper.cc#L90

The CPP stuff is a bit beyond me, to be honest 😢.

Any chance the stop_search method could get added?

Problem with install

Hi,

I`m getting some trouble installing or-tools.

The log shows this message:
find_header: checking for rice/rice.hpp in /home/viniciuscurti/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rice-4.0.2/include... -------------------- yes

"g++ -o conftest -I/home/viniciuscurti/.rbenv/versions/2.6.3/include/ruby-2.6.0/x86_64-linux -I/home/viniciuscurti/.rbenv/versions/2.6.3/include/ruby-2.6.0/ruby/backward -I/home/viniciuscurti/.rbenv/versions/2.6.3/include/ruby-2.6.0 -I. -I/home/viniciuscurti/.rbenv/versions/2.6.3/include -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wrestrict -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable conftest.cc -L. -L/home/viniciuscurti/.rbenv/versions/2.6.3/lib -Wl,-rpath,/home/viniciuscurti/.rbenv/versions/2.6.3/lib -L. -L/home/viniciuscurti/.rbenv/versions/2.6.3/lib -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,-rpath,/home/viniciuscurti/.rbenv/versions/2.6.3/lib -L/home/viniciuscurti/.rbenv/versions/2.6.3/lib -lruby -lm -lc"
cc1plus: warning: command line option ‘-Wdeclaration-after-statement’ is valid for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wimplicit-function-declaration’ is valid for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wimplicit-int’ is valid for C/ObjC but not for C++
cc1plus: warning: unrecognized command line option ‘-Wno-self-assign’
cc1plus: warning: unrecognized command line option ‘-Wno-parentheses-equality’
cc1plus: warning: unrecognized command line option ‘-Wno-constant-logical-operand’
checked program was:
/* begin */
1: #include "ruby.h"
2:
3: int main(int argc, char *argv)
4: {
5: return 0;
6: }
/
end */

"g++ -E -I/home/viniciuscurti/.rbenv/versions/2.6.3/include/ruby-2.6.0/x86_64-linux -I/home/viniciuscurti/.rbenv/versions/2.6.3/include/ruby-2.6.0/ruby/backward -I/home/viniciuscurti/.rbenv/versions/2.6.3/include/ruby-2.6.0 -I. -I/home/viniciuscurti/.rbenv/versions/2.6.3/include -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wrestrict -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -fPIC conftest.cc -o conftest.i"
cc1plus: warning: command line option ‘-Wdeclaration-after-statement’ is valid for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wimplicit-function-declaration’ is valid for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wimplicit-int’ is valid for C/ObjC but not for C++
conftest.cc:3:10: fatal error: rice/rice.hpp: No such file or directory
3 | #include <rice/rice.hpp>
| ^~~~~~~~~~~~~~~
compilation terminated.
checked program was:
/* begin /
1: #include "ruby.h"
2:
3: #include <rice/rice.hpp>
/
end */

"g++ -E -I/home/viniciuscurti/.rbenv/versions/2.6.3/include/ruby-2.6.0/x86_64-linux -I/home/viniciuscurti/.rbenv/versions/2.6.3/include/ruby-2.6.0/ruby/backward -I/home/viniciuscurti/.rbenv/versions/2.6.3/include/ruby-2.6.0 -I. -I/home/viniciuscurti/.rbenv/versions/2.6.3/include -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wrestrict -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -fPIC -I/home/viniciuscurti/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rice-4.0.2/include conftest.cc -o conftest.i"
cc1plus: warning: command line option ‘-Wdeclaration-after-statement’ is valid for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wimplicit-function-declaration’ is valid for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wimplicit-int’ is valid for C/ObjC but not for C++
cc1plus: warning: unrecognized command line option ‘-Wno-self-assign’
cc1plus: warning: unrecognized command line option ‘-Wno-parentheses-equality’
cc1plus: warning: unrecognized command line option ‘-Wno-constant-logical-operand’
checked program was:
/* begin /
1: #include "ruby.h"
2:
3: #include <rice/rice.hpp>
/
end */


have_library: checking for -lstdc++... -------------------- yes

"g++ -o conftest -I/home/viniciuscurti/.rbenv/versions/2.6.3/include/ruby-2.6.0/x86_64-linux -I/home/viniciuscurti/.rbenv/versions/2.6.3/include/ruby-2.6.0/ruby/backward -I/home/viniciuscurti/.rbenv/versions/2.6.3/include/ruby-2.6.0 -I. -I/home/viniciuscurti/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rice-4.0.2/include -I/home/viniciuscurti/.rbenv/versions/2.6.3/include -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wrestrict -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable conftest.cc -L. -L/home/viniciuscurti/.rbenv/versions/2.6.3/lib -Wl,-rpath,/home/viniciuscurti/.rbenv/versions/2.6.3/lib -L. -L/home/viniciuscurti/.rbenv/versions/2.6.3/lib -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,-rpath,/home/viniciuscurti/.rbenv/versions/2.6.3/lib -L/home/viniciuscurti/.rbenv/versions/2.6.3/lib -lruby -lstdc++ -lm -lc"
cc1plus: warning: command line option ‘-Wdeclaration-after-statement’ is valid for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wimplicit-function-declaration’ is valid for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wimplicit-int’ is valid for C/ObjC but not for C++
cc1plus: warning: unrecognized command line option ‘-Wno-self-assign’
cc1plus: warning: unrecognized command line option ‘-Wno-parentheses-equality’
cc1plus: warning: unrecognized command line option ‘-Wno-constant-logical-operand’
checked program was:
/* begin /
1: #include "ruby.h"
2:
3: /top/
4: extern int t(void);
5: int main(int argc, char *argv)
6: {
7: if (argc > 1000000) {
8: int (
volatile tp)(void)=(int (
)(void))&t;
9: printf("%d", (tp)());
10: }
11:
12: return 0;
13: }
14:
15: int t(void) { ; return 0; }
/
end */


have_library: checking for -lstdc++... -------------------- yes

"g++ -o conftest -I/home/viniciuscurti/.rbenv/versions/2.6.3/include/ruby-2.6.0/x86_64-linux -I/home/viniciuscurti/.rbenv/versions/2.6.3/include/ruby-2.6.0/ruby/backward -I/home/viniciuscurti/.rbenv/versions/2.6.3/include/ruby-2.6.0 -I. -I/home/viniciuscurti/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rice-4.0.2/include -I/home/viniciuscurti/.rbenv/versions/2.6.3/include -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wrestrict -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable conftest.cc -L. -L/home/viniciuscurti/.rbenv/versions/2.6.3/lib -Wl,-rpath,/home/viniciuscurti/.rbenv/versions/2.6.3/lib -L. -L/home/viniciuscurti/.rbenv/versions/2.6.3/lib -fstack-protector-strong -rdynamic -Wl,-export-dynamic -lstdc++ -Wl,-rpath,/home/viniciuscurti/.rbenv/versions/2.6.3/lib -L/home/viniciuscurti/.rbenv/versions/2.6.3/lib -lruby -lstdc++ -lstdc++ -lm -lc"
cc1plus: warning: command line option ‘-Wdeclaration-after-statement’ is valid for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wimplicit-function-declaration’ is valid for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wimplicit-int’ is valid for C/ObjC but not for C++
cc1plus: warning: unrecognized command line option ‘-Wno-self-assign’
cc1plus: warning: unrecognized command line option ‘-Wno-parentheses-equality’
cc1plus: warning: unrecognized command line option ‘-Wno-constant-logical-operand’
checked program was:
/* begin /
1: #include "ruby.h"
2:
3: /top/
4: extern int t(void);
5: int main(int argc, char *argv)
6: {
7: if (argc > 1000000) {
8: int (
volatile tp)(void)=(int (
)(void))&t;
9: printf("%d", (tp)());
10: }
11:
12: return 0;
13: }
14:
15: int t(void) { ; return 0; }
/
end */


have_library: checking for -lortools... -------------------- no

"g++ -o conftest -I/home/viniciuscurti/.rbenv/versions/2.6.3/include/ruby-2.6.0/x86_64-linux -I/home/viniciuscurti/.rbenv/versions/2.6.3/include/ruby-2.6.0/ruby/backward -I/home/viniciuscurti/.rbenv/versions/2.6.3/include/ruby-2.6.0 -I. -I/home/viniciuscurti/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rice-4.0.2/include -I/path/to/or-tools/include -I/path/to/or-tools/include -I/home/viniciuscurti/.rbenv/versions/2.6.3/include -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wrestrict -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable conftest.cc -L. -L/home/viniciuscurti/.rbenv/versions/2.6.3/lib -Wl,-rpath,/home/viniciuscurti/.rbenv/versions/2.6.3/lib -L/path/to/or-tools/lib -Wl,-rpath,/path/to/or-tools/lib -L. -L/home/viniciuscurti/.rbenv/versions/2.6.3/lib -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,-rpath,/path/to/or-tools/lib -L/path/to/or-tools/lib -lstdc++ -lstdc++ -Wl,-rpath,/home/viniciuscurti/.rbenv/versions/2.6.3/lib -L/home/viniciuscurti/.rbenv/versions/2.6.3/lib -lruby -lortools -lstdc++ -lstdc++ -lm -lc"
cc1plus: warning: command line option ‘-Wdeclaration-after-statement’ is valid for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wimplicit-function-declaration’ is valid for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wimplicit-int’ is valid for C/ObjC but not for C++
cc1plus: warning: unrecognized command line option ‘-Wno-self-assign’
cc1plus: warning: unrecognized command line option ‘-Wno-parentheses-equality’
cc1plus: warning: unrecognized command line option ‘-Wno-constant-logical-operand’
/usr/bin/ld: cannot find -lortools
collect2: error: ld returned 1 exit status
checked program was:
/* begin /
1: #include "ruby.h"
2:
3: /top/
4: extern int t(void);
5: int main(int argc, char *argv)
6: {
7: if (argc > 1000000) {
8: int (
volatile tp)(void)=(int (
)(void))&t;
9: printf("%d", (tp)());
10: }
11:
12: return 0;
13: }
14:
15: int t(void) { ; return 0; }
/
end */

Could you help me with??

I`m using pop os 21.04 as OS.

Thanks.

Question: Have you seen segfaults ever?

Been porting my python solver implementation over, and have been encountering segfaults on occasion?

Trying to figure out if it's my implementation or no.

Unable to find OR-Tools when installing gem locally

Hey there,

I'm trying to get the gem setup for further local development, however I'm having trouble getting it to find OR-Tools.

I'm following the instructions in the README, which are:

git clone https://github.com/ankane/or-tools.git
cd or-tools
bundle install
bundle exec rake compile
bundle exec rake test

I can clone, cd and bundle install fine, but when I run bundle exec rake compile, I get the following error:

$ bundle exec rake install
or-tools 0.2.0 built to pkg/or-tools-0.2.0.gem.rake aborted!
Couldn't install gem, run `gem install /home/rodreegez/Projects/or-tools/pkg/or-tools-0.2.0.gem' for more detailed output/home/rodreegez/.asdf/installs/ruby/2.7.1/bin/bundle:23:in `load'
/home/rodreegez/.asdf/installs/ruby/2.7.1/bin/bundle:23:in `<main>'
Tasks: TOP => install
(See full trace by running task with --trace)

Just gem installing as the error suggests gives me the following error:

$ gem install /home/rodreegez/Projects/or-tools/pkg/or-tools-0.2.0.gem
Building native extensions. This could take a while...ERROR:  Error installing /home/rodreegez/Projects/or-tools/pkg/or-tools-0.2.0.gem:
	ERROR: Failed to build gem native extension.    current directory: /home/rodreegez/.asdf/installs/ruby/2.7.1/lib/ruby/gems/2.7.0/gems/or-tools-0.2.0/ext/or-tools
/home/rodreegez/.asdf/installs/ruby/2.7.1/bin/ruby -I /home/rodreegez/.asdf/installs/ruby/2.7.1/lib/ruby/2.7.0 -r ./siteconf20200720-22754-z3hyz7.rb extconf.rb
checking for -lstdc++... yes
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/home/rodreegez/.asdf/installs/ruby/2.7.1/bin/$(RUBY_BASE_NAME)
	--with-libpath
	--without-libpath
	--with-stdc++-dir
	--without-stdc++-dir
	--with-stdc++-include
	--without-stdc++-include=${stdc++-dir}/include
	--with-stdc++-lib
	--without-stdc++-lib=${stdc++-dir}/lib
	--with-stdc++lib
	--without-stdc++lib
	--with-or-tools-dir
	--without-or-tools-dir
	--with-or-tools-include
	--without-or-tools-include=${or-tools-dir}/include
	--with-or-tools-lib
	--without-or-tools-lib=${or-tools-dir}/lib
/home/rodreegez/.asdf/installs/ruby/2.7.1/lib/ruby/gems/2.7.0/gems/or-tools-0.2.0/ext/or-tools/vendor.rb:29:in `<top (required)>': Binary installation not available for this platform. (RuntimeError)

Build the OR-Tools C++ library from source, then run:
bundle config build.or-tools --with-or-tools-dir=/path/to/or-tools

	from extconf.rb:17:in `require_relative'
	from extconf.rb:17:in `<main>'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /home/rodreegez/.asdf/installs/ruby/2.7.1/lib/ruby/gems/2.7.0/extensions/x86_64-linux/2.7.0/or-tools-0.2.0/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in /home/rodreegez/.asdf/installs/ruby/2.7.1/lib/ruby/gems/2.7.0/gems/or-tools-0.2.0 for inspection.
Results logged to /home/rodreegez/.asdf/installs/ruby/2.7.1/lib/ruby/gems/2.7.0/extensions/x86_64-linux/2.7.0/or-tools-0.2.0/gem_make.out

I clocked the error message about telling bundler where to find OR-Tools, so I ran:

bundle config build.or-tools --with-or-tools-dir=/home/rodreegez/src/or-tools/or-tools_Ubuntu-20.04-64bit_v7.7.7810

Running bundle exec rake install yeilds the same error (which I'm not all that surprised about).

The mkmf.log doesn't seem to be all that enlightening, but I include it here just in case:

mkmf.log
$ cat /home/rodreegez/.asdf/installs/ruby/2.7.1/lib/ruby/gems/2.7.0/extensions/x86_64-linux/2.7.0/or-tools-0.2.0/mkmf.log
have_library: checking for -lstdc++... -------------------- yes

"g++ -o conftest -I/home/rodreegez/.asdf/installs/ruby/2.7.1/include/ruby-2.7.0/x86_64-linux -I/home/rodreegez/.asdf/installs/ruby/2.7.1/include/ruby-2.7.0/ruby/backward -I/home/rodreegez/.asdf/installs/ruby/2.7.1/include/ruby-2.7.0 -I. -I/home/rodreegez/.asdf/installs/ruby/2.7.1/include     -I/home/rodreegez/.asdf/installs/ruby/2.7.1/lib/ruby/gems/2.7.0/gems/rice-2.2.0/ruby/lib/include -g -O2 conftest.c  -L. -L/home/rodreegez/.asdf/installs/ruby/2.7.1/lib -Wl,-rpath,/home/rodreegez/.asdf/installs/ruby/2.7.1/lib -L. -L/home/rodreegez/.asdf/installs/ruby/2.7.1/lib  -fstack-protector-strong -rdynamic -Wl,-export-dynamic  -L/home/rodreegez/.asdf/installs/ruby/2.7.1/lib/ruby/gems/2.7.0/gems/rice-2.2.0/ruby/lib/lib -lrice     -Wl,-rpath,/home/rodreegez/.asdf/installs/ruby/2.7.1/lib -L/home/rodreegez/.asdf/installs/ruby/2.7.1/lib -lruby  -lm   -lc"
checked program was:
/* begin */
1: #include "ruby.h"
2: 
3: int main(int argc, char **argv)
4: {
5:   return !!argv[argc];
6: }
/* end */

"g++ -o conftest -I/home/rodreegez/.asdf/installs/ruby/2.7.1/include/ruby-2.7.0/x86_64-linux -I/home/rodreegez/.asdf/installs/ruby/2.7.1/include/ruby-2.7.0/ruby/backward -I/home/rodreegez/.asdf/installs/ruby/2.7.1/include/ruby-2.7.0 -I. -I/home/rodreegez/.asdf/installs/ruby/2.7.1/include     -I/home/rodreegez/.asdf/installs/ruby/2.7.1/lib/ruby/gems/2.7.0/gems/rice-2.2.0/ruby/lib/include -g -O2 conftest.c  -L. -L/home/rodreegez/.asdf/installs/ruby/2.7.1/lib -Wl,-rpath,/home/rodreegez/.asdf/installs/ruby/2.7.1/lib -L. -L/home/rodreegez/.asdf/installs/ruby/2.7.1/lib  -fstack-protector-strong -rdynamic -Wl,-export-dynamic  -L/home/rodreegez/.asdf/installs/ruby/2.7.1/lib/ruby/gems/2.7.0/gems/rice-2.2.0/ruby/lib/lib -lrice     -Wl,-rpath,/home/rodreegez/.asdf/installs/ruby/2.7.1/lib -L/home/rodreegez/.asdf/installs/ruby/2.7.1/lib -lruby -lstdc++  -lm   -lc"
checked program was:
/* begin */
 1: #include "ruby.h"
 2: 
 3: /*top*/
 4: extern int t(void);
 5: int main(int argc, char **argv)
 6: {
 7:   if (argc > 1000000) {
 8:     int (* volatile tp)(void)=(int (*)(void))&t;
 9:     printf("%d", (*tp)());
10:   }
11: 
12:   return !!argv[argc];
13: }
14: 
15: int t(void) { ; return 0; }
/* end */

--------------------

I'm running Pop OS locally and have a rails app with the or-tools gem running just fine. Pop is based off of Ubuntu, and the version I'm running is specifically based off of 20.04. There is a 20.04 version of the OR Tools binary available. I did do some mad stuff in /ext/or-tools/vendor.rb to try and have the gem vendor the Ubuntu 20.04 OR Tools binary but that didn't seem to work either and I think is perhaps deviating away from the core issue?

(p.s. I wonder if the script should check lsb_release -cs and grab the codename of the OS rather than the Distributor ID? I think that would mean the gem would install more liberally on the various ubuntu-a-likes? Dunno, might be a whole new world of pain).

I feel like passing in the --with-or-tools-dir used to work but maybe since the vendoring stuff went in perhaps maybe it doesn't anymore?

TLDR; I think bundle exec rake install -- --with-or-tools-lib=/path/to/or-tools should work but it doesn't seem to. Any idea what's up with that?

ORTools::SatIntVar can't be coerced into Integer (TypeError)

Hi there,

I'm working on trying to port one Python example to Ruby and I've hit a roadblock. (I'll prefix that by saying this was reasonably smooth up until now). I am not going to pretend I understand how this works but my assumption is everytime you do something like

model.add(->> this is something that is evaluated later <<-)

In my port of a Staff Scheduling solution

https://github.com/braindeaf/staff_scheduling

I am now stuck.

namely, how I would do something like..

    cost_variables = []
    cost_coefficients = []
    sum_var = model.NewIntVar(hard_min, hard_max, '')
    # This adds the hard constraints on the sum.
    model.Add(sum_var == sum(works))

    # Penalize sums below the soft_min target.
    if soft_min > hard_min and min_cost > 0:
        delta = model.NewIntVar(-len(works), len(works), '') 
        model.Add(delta == soft_min - sum_var) # this line right here.
model.add(delta == soft_min - sum_var)

causes

staff_scheduling_sat.rb:286:in `-': ORTools::SatIntVar can't be coerced into Integer (TypeError)

I know that soft_min is an Integer, so it's evaluating now and doesn't make sense. Is there a method for doing that subtraction in a way that is evaluated later?)

Many many thanks in advance :)

RobL

seg fault @ run solver.

hey, im back again
i've made a service file for testing:


def self.ejemplo
    # define the data
    num_nurses = 4
    num_shifts = 3
    num_days = 3
    all_nurses = num_nurses.times.to_a
    all_shifts = num_shifts.times.to_a
    all_days = num_days.times.to_a

    # create the variables
    model = ORTools::CpModel.new

    shifts = {}
    all_nurses.each do |n|
      all_days.each do |d|
        all_shifts.each do |s|
          shifts[[n, d, s]] = model.new_bool_var("shift_n%id%is%i" % [n, d, s])
        end
      end
    end

    # assign nurses to shifts
    all_days.each do |d|
      all_shifts.each do |s|
        model.add(model.sum(all_nurses.map { |n| shifts[[n, d, s]] }) == 1)
      end
    end

    all_nurses.each do |n|
      all_days.each do |d|
        model.add(model.sum(all_shifts.map { |s| shifts[[n, d, s]] }) <= 1)
      end
    end

    # assign shifts evenly
    min_shifts_per_nurse = (num_shifts * num_days) / num_nurses
    max_shifts_per_nurse = min_shifts_per_nurse + 1
    all_nurses.each do |n|
      num_shifts_worked = model.sum(all_days.flat_map { |d| all_shifts.map { |s| shifts[[n, d, s]] } })
      model.add(num_shifts_worked >= min_shifts_per_nurse)
      model.add(num_shifts_worked <= max_shifts_per_nurse)
    end

    # call the solver and display the results
    solver = ORTools::CpSolver.new
    
    a_few_solutions = 5.times.to_a
    solution_printer = NursesPartialSolutionPrinter.new(
      shifts, num_nurses, num_days, num_shifts, a_few_solutions
      )
    solver.search_for_all_solutions(model,solution_printer)

    puts
    puts "Statistics"
    puts "  - conflicts       : %i" % solver.num_conflicts
    puts "  - branches        : %i" % solver.num_branches
    puts "  - wall time       : %f s" % solver.wall_time
    puts "  - solutions found : %i" % solution_printer.solution_count
  end

3] pry(main)> DevelService.ejemplo
/usr/local/rvm/gems/ruby-2.4.1/gems/or-tools-0.2.0/lib/or_tools/cp_solver.rb:24: [BUG] Segmentation fault at 0x00000000000000
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]

-- Control frame information -----------------------------------------------
c:0057 p:---- s:0338 e:000337 CFUNC :_solve_with_observer
c:0056 p:0014 s:0331 e:000330 METHOD /usr/local/rvm/gems/ruby-2.4.1/gems/or-tools-0.2.0/lib/or_tools/cp_solver.rb:24
c:0055 p:0202 s:0325 E:001988 METHOD /home/coke/_prj/turnos-copec/app/services/devel_service.rb:125
c:0054 p:0012 s:0308 E:0019f0 EVAL (pry):3 [FINISH]
c:0053 p:---- s:0305 e:000304 CFUNC :eval
c:0052 p:0052 s:0298 E:001a70 METHOD /usr/local/rvm/gems/ruby-2.4.1/gems/pry-0.13.1/lib/pry/pry_instance.rb:290
c:0051 p:0292 s:0292 E:001b18 METHOD /usr/local/rvm/gems/ruby-2.4.1/gems/pry-0.13.1/lib/pry/pry_instance.rb:659
c:0050 p:0014 s:0281 E:001c00 BLOCK /usr/local/rvm/gems/ruby-2.4.1/gems/pry-0.13.1/lib/pry/pry_instance.rb:261 [FINISH]

ORTools::LinearSumAssignment not finding solution to a 20 * 16 cost matrix

I have tried the given example of ORTools::LinearSumAssignment in the README section which works for 4 * 4 cost matrix:

costs = [
  [90, 76, 75, 70],
  [35, 85, 55, 65],
  [125, 95, 90, 105],
  [45, 110, 95, 115],
]

Now, I am trying to solve a similar problem for a slightly larger cost matrix which is 20 * 16 matrix and the cost matrix is:

cost_matrix = [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0], [4, 0, 2, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 2, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]]

But, solver is returning infeasible status. And, I am not sure if I am doing something wrong, or the ORTools::LinearSumAssignment is not the right solver to solve this type of cost matrix. Could you please shed some lights if I should use any other configuration with ORTools::LinearSumAssignment to solve the above 20 * 16 cost matrix?

Thank you in advance.

Issue building or-tools 0.10.1 with native extensions

This is on M1 Pro mac with latest brew update or-tools (which is 9.6)

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/or-tools-0.10.1/ext/or-tools
/Users/ollym/.rbenv/versions/3.2.1/bin/ruby -I /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0 extconf.rb --with-or-tools-dir\=/opt/homebrew
checking for rice/rice.hpp in /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/rice-4.1.0/include... yes
checking for -lc++... yes
checking for -lortools... yes
creating Makefile

current directory: /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/or-tools-0.10.1/ext/or-tools
make DESTDIR\= sitearchdir\=./.gem.20230628-98570-n9sw9s sitelibdir\=./.gem.20230628-98570-n9sw9s clean

current directory: /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/or-tools-0.10.1/ext/or-tools
make DESTDIR\= sitearchdir\=./.gem.20230628-98570-n9sw9s sitelibdir\=./.gem.20230628-98570-n9sw9s
compiling assignment.cpp
compiling bin_packing.cpp
compiling constraint.cpp
compiling ext.cpp
compiling linear.cpp
compiling network_flows.cpp
compiling routing.cpp
linking shared-object or_tools/ext.bundle
Undefined symbols for architecture arm64:
  "_FLAGS_stderrthreshold", referenced from:
      operations_research::CppBridge::SetFlags(operations_research::CppFlags const&) in ext.o
  "absl::lts_20230125::log_internal::LogMessageFatal::LogMessageFatal(char const*, int, std::__1::basic_string_view<char, std::__1::char_traits<char>>)", referenced from:
      Rice::detail::NativeFunction<operations_research::sat::CpSolverResponse, init_constraint(Rice::Module&)::$_44, true>::call(int, unsigned long*, unsigned long) in constraint.o
      google::protobuf::RepeatedField<int>::GrowNoAnnotate(int, int) in constraint.o
      google::protobuf::RepeatedField<int>::~RepeatedField() in constraint.o
      void google::protobuf::RepeatedField<int>::InternalDeallocate<false>() (.cold.1) in constraint.o
      Rice::detail::NativeFunction<operations_research::MPSolver, init_linear(Rice::Module&)::$_1, true>::call(int, unsigned long*, unsigned long) in linear.o
      operations_research::RoutingIndexManager::IndexToNode(long long) const (.cold.1) in routing.o
      operations_research::RoutingIndexManager::IndexToNode(long long) const (.cold.2) in routing.o
      ...
  "absl::lts_20230125::log_internal::LogMessageFatal::~LogMessageFatal()", referenced from:
      Rice::detail::NativeFunction<operations_research::sat::CpSolverResponse, init_constraint(Rice::Module&)::$_44, true>::call(int, unsigned long*, unsigned long) in constraint.o
      google::protobuf::RepeatedField<int>::GrowNoAnnotate(int, int) in constraint.o
      google::protobuf::RepeatedField<int>::~RepeatedField() in constraint.o
      void google::protobuf::RepeatedField<int>::InternalDeallocate<false>() (.cold.1) in constraint.o
      Rice::detail::NativeFunction<operations_research::MPSolver, init_linear(Rice::Module&)::$_1, true>::call(int, unsigned long*, unsigned long) in linear.o
      operations_research::RoutingIndexManager::IndexToNode(long long) const (.cold.1) in routing.o
      operations_research::RoutingIndexManager::IndexToNode(long long) const (.cold.2) in routing.o
      ...
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>* absl::lts_20230125::log_internal::MakeCheckOpString<long long, long long>(long long, long long, char const*)", referenced from:
      Rice::detail::NativeFunction<operations_research::sat::CpSolverResponse, init_constraint(Rice::Module&)::$_44, true>::call(int, unsigned long*, unsigned long) in constraint.o
      google::protobuf::RepeatedField<int>::GrowNoAnnotate(int, int) in constraint.o
      google::protobuf::RepeatedField<int>::~RepeatedField() in constraint.o
      void google::protobuf::RepeatedField<int>::InternalDeallocate<false>() (.cold.1) in constraint.o
      operations_research::RoutingIndexManager::IndexToNode(long long) const (.cold.1) in routing.o
      operations_research::RoutingIndexManager::NodeToIndex(gtl::IntType<operations_research::RoutingNodeIndex_tag_, int>) const (.cold.2) in routing.o
      operations_research::RoutingModel::SetVehicleUsedWhenEmpty(bool, int) (.cold.1) in routing.o
      ...
  "absl::lts_20230125::log_internal::CheckOpMessageBuilder::ForVar2()", referenced from:
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>* absl::lts_20230125::log_internal::MakeCheckOpString<absl::lts_20230125::Duration const&, absl::lts_20230125::Duration
const&>(absl::lts_20230125::Duration const&, absl::lts_20230125::Duration const&, char const*) in linear.o
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>* absl::lts_20230125::log_internal::MakeCheckOpString<long long, unsigned long long>(long long, unsigned long long, char const*) in routing.o
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>* absl::lts_20230125::log_internal::MakeCheckOpString<unsigned long long, long long>(unsigned long long, long long, char const*) in routing.o
  "absl::lts_20230125::log_internal::CheckOpMessageBuilder::NewString()", referenced from:
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>* absl::lts_20230125::log_internal::MakeCheckOpString<absl::lts_20230125::Duration const&, absl::lts_20230125::Duration
const&>(absl::lts_20230125::Duration const&, absl::lts_20230125::Duration const&, char const*) in linear.o
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>* absl::lts_20230125::log_internal::MakeCheckOpString<long long, unsigned long long>(long long, unsigned long long, char const*) in routing.o
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>* absl::lts_20230125::log_internal::MakeCheckOpString<unsigned long long, long long>(unsigned long long, long long, char const*) in routing.o
  "absl::lts_20230125::log_internal::CheckOpMessageBuilder::CheckOpMessageBuilder(char const*)", referenced from:
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>* absl::lts_20230125::log_internal::MakeCheckOpString<absl::lts_20230125::Duration const&, absl::lts_20230125::Duration
const&>(absl::lts_20230125::Duration const&, absl::lts_20230125::Duration const&, char const*) in linear.o
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>* absl::lts_20230125::log_internal::MakeCheckOpString<long long, unsigned long long>(long long, unsigned long long, char const*) in routing.o
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>* absl::lts_20230125::log_internal::MakeCheckOpString<unsigned long long, long long>(unsigned long long, long long, char const*) in routing.o
  "absl::lts_20230125::InitializeLog()", referenced from:
      _Init_ext in ext.o
  "absl::lts_20230125::hash_internal::MixingHashState::kSeed", referenced from:
      operations_research::RoutingModel::IsVehicleAllowedForIndex(int, long long) in routing.o
  "absl::lts_20230125::FormatDuration(absl::lts_20230125::Duration)", referenced from:
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>* absl::lts_20230125::log_internal::MakeCheckOpString<absl::lts_20230125::Duration const&, absl::lts_20230125::Duration
const&>(absl::lts_20230125::Duration const&, absl::lts_20230125::Duration const&, char const*) in linear.o
  "absl::lts_20230125::flags_internal::FlagImpl::Write(void const*)", referenced from:
      operations_research::CppBridge::SetFlags(operations_research::CppFlags const&) in ext.o
  "absl::lts_20230125::EnableLogPrefix(bool)", referenced from:
      operations_research::CppBridge::SetFlags(operations_research::CppFlags const&) in ext.o
  "absl::lts_20230125::container_internal::kEmptyGroup", referenced from:
      Rice::detail::NativeFunction<unsigned long, init_constraint(Rice::Module&)::$_45, true>::call(int, unsigned long*, unsigned long) in constraint.o
      Rice::Constructor<operations_research::sat::CpModelBuilder>::construct(unsigned long) in constraint.o
  "absl::lts_20230125::ToInt64Milliseconds(absl::lts_20230125::Duration)", referenced from:
      operations_research::MPSolver::wall_time() const in linear.o
  "absl::lts_20230125::SetProgramUsageMessage(std::__1::basic_string_view<char, std::__1::char_traits<char>>)", referenced from:
      _Init_ext in ext.o
  "absl::lts_20230125::Now()", referenced from:
      operations_research::MPSolver::wall_time() const in linear.o
  "absl::lts_20230125::Duration::operator-=(absl::lts_20230125::Duration)", referenced from:
      operations_research::MPSolver::wall_time() const in linear.o
  "absl::lts_20230125::Duration::operator*=(double)", referenced from:
      Rice::detail::NativeFunction<operations_research::MPSolver, init_linear(Rice::Module&)::$_1, true>::call(int, unsigned long*, unsigned long) in linear.o
  "google::protobuf::TextFormat::PrintToString(google::protobuf::Message const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>*)", referenced from:
      Rice::detail::NativeFunction<operations_research::sat::CpModelBuilder, init_constraint(Rice::Module&)::$_40, true>::call(int, unsigned long*, unsigned long) in constraint.o
  "google::protobuf::Arena::AllocateForArray(unsigned long)", referenced from:
      google::protobuf::RepeatedField<int>::GrowNoAnnotate(int, int) in constraint.o
  "google::protobuf::Duration* google::protobuf::Arena::CreateMaybeMessage<google::protobuf::Duration>(google::protobuf::Arena*)", referenced from:
      Rice::detail::NativeFunction<operations_research::RoutingSearchParameters, init_routing(Rice::Module&)::$_4, true>::call(int, unsigned long*, unsigned long) in routing.o
      Rice::detail::NativeFunction<operations_research::RoutingSearchParameters, init_routing(Rice::Module&)::$_5, true>::call(int, unsigned long*, unsigned long) in routing.o
  "google::protobuf::internal::ThreadSafeArena::thread_cache_", referenced from:
      void google::protobuf::RepeatedField<int>::InternalDeallocate<false>() in constraint.o
  "google::protobuf::internal::protobuf_assumption_failed(char const*, char const*, int)", referenced from:
      void google::protobuf::RepeatedField<int>::InternalDeallocate<false>() in constraint.o
  "absl::lts_20230125::flags_internal::FlagImpl::AssertValidType(void const*, std::type_info const* (*)()) const", referenced from:
      operations_research::CppBridge::SetFlags(operations_research::CppFlags const&) in ext.o
  "google::protobuf::internal::ThreadSafeArena::SpaceAllocated() const", referenced from:
      google::protobuf::RepeatedField<int>::~RepeatedField() in constraint.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [ext.bundle] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/or-tools-0.10.1 for inspection.
Results logged to /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/extensions/arm64-darwin-22/3.2.0/or-tools-0.10.1/gem_make.out

  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/rubygems/ext/builder.rb:102:in `run'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/rubygems/ext/builder.rb:51:in `block in make'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/rubygems/ext/builder.rb:43:in `each'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/rubygems/ext/builder.rb:43:in `make'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/rubygems/ext/ext_conf_builder.rb:42:in `build'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/rubygems/ext/builder.rb:170:in `build_extension'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/rubygems/ext/builder.rb:204:in `block in build_extensions'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/rubygems/ext/builder.rb:201:in `each'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/rubygems/ext/builder.rb:201:in `build_extensions'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/rubygems/installer.rb:843:in `build_extensions'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/bundler/rubygems_gem_installer.rb:72:in `build_extensions'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/bundler/rubygems_gem_installer.rb:28:in `install'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/bundler/source/rubygems.rb:200:in `install'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/bundler/installer/gem_installer.rb:54:in `install'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/bundler/installer/gem_installer.rb:16:in `install_from_spec'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/bundler/installer/parallel_installer.rb:155:in `do_install'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/bundler/installer/parallel_installer.rb:146:in `block in worker_pool'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/bundler/worker.rb:62:in `apply_func'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/bundler/worker.rb:57:in `block in process_queue'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/bundler/worker.rb:54:in `loop'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/bundler/worker.rb:54:in `process_queue'
  /Users/ollym/.rbenv/versions/3.2.1/lib/ruby/3.2.0/bundler/worker.rb:90:in `block (2 levels) in create_threads'

An error occurred while installing or-tools (0.10.1), and Bundler cannot continue.

[VRPTW] Add SolveFromAssignmentWithParameters

I'm trying to define initial routes to the solver, but it is missing solve_from_assignment_with_parameters API.

Would it be possible to add solve_from_assignment_with_parameters?

# https://developers.google.com/optimization/routing/routing_tasks#setting-initial-routes-for-a-search
# python example: 
initial_solution = routing.ReadAssignmentFromRoutes(data['initial_routes'],
                                                    True)
print('Initial solution:')
print_solution(data, manager, routing, initial_solution)

# Set default search parameters.
search_parameters = pywrapcp.DefaultRoutingSearchParameters()

# Solve the problem.
solution = routing.SolveFromAssignmentWithParameters(
    initial_solution, search_parameters)

Installing on Heroku

Before I begin, I would like to say:

  • I'm really sorry, and,
  • I'm weirdly a huge fan - I use a bunch of your other gems regularly. Thanks!

I've spent most of today trying to get OR Tools running on Heroku. I have little to no idea what I'm doing. It's been fun.

I've created a buildpack that seems to install OR Tools properly on a fresh heroku-18 stack, and I've created a new Rails app to try to utilise that buildpack and install the or-tools gem.

As per the README in the Rails app, I have:

  • added the OR Tools buildpack (making sure it's run before the ruby/rails buildpack)
  • set the BUNDLE_BUILD__OR_TOOLS to what I think is the correct path for OR Tools on the Heroku filesystem with heroku config:set BUNDLE_BUILD__OR_TOOLS=/app/or-tools/or-tools_Ubuntu-18.04-64bit_v7.6.7691
  • pushed the app up to Heroku.

The deploy is rejected because or-tools fails to install.

The pertinent bit of the installation log is as follows:

remote: -----> Ruby app detected
remote: -----> Installing bundler 2.0.2
remote: -----> Removing BUNDLED WITH version in the Gemfile.lock
remote: -----> Compiling Ruby/Rails
remote: -----> Using Ruby version: ruby-2.5.7
remote: -----> Installing dependencies using bundler 2.0.2
remote:        Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
remote:        The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
remote:        Fetching gem metadata from https://rubygems.org/............
remote:        Using rake 13.0.1
... standard rails gems omitted ... 
remote:        Using rails 6.0.3.1
remote:        Using sass-rails 6.0.0
remote:        Installing rice 2.2.0 with native extensions
remote:        Fetching or-tools 0.1.5
remote:        Installing or-tools 0.1.5 with native extensions
remote:        Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
remote:
remote:        current directory:
remote:        /tmp/build_cf53ce24d0d4ec56170536db996a2607/vendor/bundle/ruby/2.5.0/gems/or-tools-0.1.5/ext/or-tools
remote:        /tmp/build_cf53ce24d0d4ec56170536db996a2607/vendor/ruby-2.5.7/bin/ruby -r
remote:        ./siteconf20200521-449-1fns9ab.rb extconf.rb
remote:        checking for -lstdc++... yes
remote:        creating Makefile
remote:
remote:        current directory:
remote:        /tmp/build_cf53ce24d0d4ec56170536db996a2607/vendor/bundle/ruby/2.5.0/gems/or-tools-0.1.5/ext/or-tools
remote:        make "DESTDIR=" clean
remote:
remote:        current directory:
remote:        /tmp/build_cf53ce24d0d4ec56170536db996a2607/vendor/bundle/ruby/2.5.0/gems/or-tools-0.1.5/ext/or-tools
remote:        make "DESTDIR="
remote:        compiling ext.cpp
remote:        cc1plus: warning: command line option ‘-Wimplicit-int’ is valid for C/ObjC but
remote:        not for C++
remote:        cc1plus: warning: command line option ‘-Wdeclaration-after-statement’ is valid
remote:        for C/ObjC but not for C++
remote:        cc1plus: warning: command line option ‘-Wimplicit-function-declaration’ is valid
remote:        for C/ObjC but not for C++
remote:        ext.cpp:2:10: fatal error: ortools/algorithms/knapsack_solver.h: No such file or
remote:        directory
remote:         #include <ortools/algorithms/knapsack_solver.h>
remote:                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
remote:        compilation terminated.
remote:        Makefile:298: recipe for target 'ext.o' failed
remote:        make: *** [ext.o] Error 1
remote:
remote:        make failed, exit code 2
remote:
remote:        Gem files will remain installed in
remote:        /tmp/build_cf53ce24d0d4ec56170536db996a2607/vendor/bundle/ruby/2.5.0/gems/or-tools-0.1.5
remote:        for inspection.
remote:        Results logged to
remote:        /tmp/build_cf53ce24d0d4ec56170536db996a2607/vendor/bundle/ruby/2.5.0/extensions/x86_64-linux/2.5.0/or-tools-0.1.5/gem_make.out
remote:
remote:        An error occurred while installing or-tools (0.1.5), and Bundler cannot
remote:        continue.
remote:        Make sure that `gem install or-tools -v '0.1.5' --source
remote:        'https://rubygems.org/'` succeeds before bundling.
remote:
remote:        In Gemfile:
remote:          or-tools

I did find an issue on the Rice project that seemed to indicate that I might be stuffed due to the way Heroku uses a statically linked Ruby, however it seems someone has been digging into this more recently and figured out that you can in fact use Rice on Heroku, which seems to ring true as the error seems to be a failure to compile Knapsack, which is inside of OR Tools, so I presume it is at least trying to install or-tools with native extensions.

I don't really know where to go from here! Any ideas what to try next?

It would be wonderful to be able to run or-tools on Heroku from ruby/rails. And again, thanks for all your work both here and elsewhere.

Cheers.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.