or-tools 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 18b9ab384a5aa4b8d27a3415de9ba751085e63b95cbdc431d1fee206b05e1c37
4
- data.tar.gz: 4b8d29c3f6b5fff8181a817737a818e2c3d7cf6cd0184d82078d4606c2c94740
3
+ metadata.gz: e557f98fc061c46799334f589a41f1592da361bce8a6e199120d3425efe67c0a
4
+ data.tar.gz: be6fa049625b6d9aae8134b34a4731053b1e3b12c7481dd041bdb98e40648c1d
5
5
  SHA512:
6
- metadata.gz: 26e5b155bdd5c0d37aaf13fe26c674ac15ac693933999056a477e340823ced7e86b8565c00c941d4ecdfd35e0b5a4716465e2418bf1e44ca7c1586d171e77515
7
- data.tar.gz: 1c87b6df5082d9ab61b1ab63d154e563fdd9405fa3dda5fd00df2f6aafc65c7f5f8d251938cab9cba58de04efb7f38b11893701c128833059b8290b3a3dfb0da
6
+ metadata.gz: 5f5542b967fc7fd25afa4598bcfa99c17978e8020ced4af449ca00e8e7e20f2aeb1e5de2b6d562a60cd880afa14f9ea383c12a3d3fe7434dc2f4837d98e18d24
7
+ data.tar.gz: 69506b406afe60200592f5b526ce617fba45d8581e253ca12b143d243aa1d9fdda5c2e122e24d5dd516e9e141a542ed5eaef834861ccfa3917693d8f1971ffca
@@ -1,3 +1,25 @@
1
+ ## 0.4.0 (2021-01-14)
2
+
3
+ - Updated OR-Tools to 8.1
4
+
5
+ ## 0.3.4 (2021-01-14)
6
+
7
+ - Added support for time limit for `CpSolver`
8
+ - Added `add_dimension_with_vehicle_transits` and `status` methods to `RoutingModel`
9
+
10
+ ## 0.3.3 (2020-10-12)
11
+
12
+ - Added support for start and end points for routing
13
+
14
+ ## 0.3.2 (2020-08-04)
15
+
16
+ - Updated OR-Tools to 7.8
17
+ - Added binary installation for Ubuntu 20.04
18
+
19
+ ## 0.3.1 (2020-07-21)
20
+
21
+ - Reduced gem size
22
+
1
23
  ## 0.3.0 (2020-07-21)
2
24
 
3
25
  - Updated OR-Tools to 7.7
data/NOTICE.txt CHANGED
@@ -1,4 +1,5 @@
1
- Copyright 2020 Andrew Kane
1
+ Copyright 2010-2018 Google LLC
2
+ Copyright 2020-2021 Andrew Kane
2
3
 
3
4
  Licensed under the Apache License, Version 2.0 (the "License");
4
5
  you may not use this file except in compliance with the License.
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [OR-Tools](https://github.com/google/or-tools) - operations research tools - for Ruby
4
4
 
5
- [![Build Status](https://travis-ci.org/ankane/or-tools.svg?branch=master)](https://travis-ci.org/ankane/or-tools)
5
+ [![Build Status](https://github.com/ankane/or-tools/workflows/build/badge.svg?branch=master)](https://github.com/ankane/or-tools/actions)
6
6
 
7
7
  ## Installation
8
8
 
@@ -267,6 +267,7 @@ Constraint Optimization
267
267
  - [Solving an Optimization Problem](#solving-an-optimization-problem)
268
268
  - [Cryptarithmetic](#cryptarithmetic)
269
269
  - [The N-queens Problem](#the-n-queens-problem)
270
+ - [Setting Solver Limits](#setting-solver-limits) [master]
270
271
 
271
272
  Assignment
272
273
 
@@ -578,6 +579,39 @@ puts
578
579
  puts "Solutions found : %i" % solution_printer.solution_count
579
580
  ```
580
581
 
582
+ ### Setting Solver Limits
583
+
584
+ [Guide](https://developers.google.com/optimization/cp/cp_tasks)
585
+
586
+ ```ruby
587
+ # create the model
588
+ model = ORTools::CpModel.new
589
+
590
+ # create the variables
591
+ num_vals = 3
592
+ x = model.new_int_var(0, num_vals - 1, "x")
593
+ y = model.new_int_var(0, num_vals - 1, "y")
594
+ z = model.new_int_var(0, num_vals - 1, "z")
595
+
596
+ # add an all-different constraint
597
+ model.add(x != y)
598
+
599
+ # create the solver
600
+ solver = ORTools::CpSolver.new
601
+
602
+ # set a time limit of 10 seconds.
603
+ solver.parameters.max_time_in_seconds = 10
604
+
605
+ # solve the model
606
+ status = solver.solve(model)
607
+
608
+ # display the first solution
609
+ if status == :optimal
610
+ puts "x = #{solver.value(x)}"
611
+ puts "y = #{solver.value(y)}"
612
+ puts "z = #{solver.value(z)}"
613
+ end
614
+ ```
581
615
 
582
616
  ### Assignment
583
617
 
@@ -101,6 +101,14 @@ Object to_ruby<RoutingNodeIndex>(RoutingNodeIndex const &x)
101
101
  return to_ruby<int>(x.value());
102
102
  }
103
103
 
104
+ std::vector<RoutingNodeIndex> nodeIndexVector(Array x) {
105
+ std::vector<RoutingNodeIndex> res;
106
+ for (auto const& v : x) {
107
+ res.push_back(from_ruby<RoutingNodeIndex>(v));
108
+ }
109
+ return res;
110
+ }
111
+
104
112
  template<>
105
113
  inline
106
114
  operations_research::sat::LinearExpr from_ruby<operations_research::sat::LinearExpr>(Object x)
@@ -630,18 +638,24 @@ void Init_ext()
630
638
  self.Minimize(expr);
631
639
  });
632
640
 
641
+ define_class_under<SatParameters>(rb_mORTools, "SatParameters")
642
+ .define_constructor(Constructor<SatParameters>())
643
+ .define_method("max_time_in_seconds=",
644
+ *[](SatParameters& self, double value) {
645
+ self.set_max_time_in_seconds(value);
646
+ });
647
+
633
648
  define_class_under(rb_mORTools, "CpSolver")
634
649
  .define_method(
635
650
  "_solve_with_observer",
636
- *[](Object self, CpModelBuilder& model, Object callback, bool all_solutions) {
651
+ *[](Object self, CpModelBuilder& model, SatParameters& parameters, Object callback, bool all_solutions) {
637
652
  operations_research::sat::Model m;
638
653
 
639
654
  if (all_solutions) {
640
655
  // set parameters for SearchForAllSolutions
641
- SatParameters parameters;
642
656
  parameters.set_enumerate_all_solutions(true);
643
- m.Add(NewSatParameters(parameters));
644
657
  }
658
+ m.Add(NewSatParameters(parameters));
645
659
 
646
660
  m.Add(NewFeasibleSolutionObserver(
647
661
  [callback](const CpSolverResponse& r) {
@@ -654,8 +668,10 @@ void Init_ext()
654
668
  })
655
669
  .define_method(
656
670
  "_solve",
657
- *[](Object self, CpModelBuilder& model) {
658
- return Solve(model.Build());
671
+ *[](Object self, CpModelBuilder& model, SatParameters& parameters) {
672
+ operations_research::sat::Model m;
673
+ m.Add(NewSatParameters(parameters));
674
+ return SolveCpModel(model.Build(), &m);
659
675
  })
660
676
  .define_method(
661
677
  "_solution_integer_value",
@@ -693,13 +709,24 @@ void Init_ext()
693
709
  return Symbol("infeasible");
694
710
  } else if (status == CpSolverStatus::MODEL_INVALID) {
695
711
  return Symbol("model_invalid");
712
+ } else if (status == CpSolverStatus::UNKNOWN) {
713
+ return Symbol("unknown");
696
714
  } else {
697
715
  throw std::runtime_error("Unknown solver status");
698
716
  }
699
717
  });
700
718
 
701
719
  define_class_under<RoutingIndexManager>(rb_mORTools, "RoutingIndexManager")
702
- .define_constructor(Constructor<RoutingIndexManager, int, int, RoutingNodeIndex>())
720
+ .define_singleton_method(
721
+ "_new_depot",
722
+ *[](int num_nodes, int num_vehicles, RoutingNodeIndex depot) {
723
+ return RoutingIndexManager(num_nodes, num_vehicles, depot);
724
+ })
725
+ .define_singleton_method(
726
+ "_new_starts_ends",
727
+ *[](int num_nodes, int num_vehicles, Array starts, Array ends) {
728
+ return RoutingIndexManager(num_nodes, num_vehicles, nodeIndexVector(starts), nodeIndexVector(ends));
729
+ })
703
730
  .define_method("index_to_node", &RoutingIndexManager::IndexToNode)
704
731
  .define_method("node_to_index", &RoutingIndexManager::NodeToIndex);
705
732
 
@@ -789,6 +816,23 @@ void Init_ext()
789
816
  })
790
817
  .define_method("depot", &RoutingModel::GetDepot)
791
818
  .define_method("size", &RoutingModel::Size)
819
+ .define_method("status", *[](RoutingModel& self) {
820
+ auto status = self.status();
821
+
822
+ if (status == RoutingModel::ROUTING_NOT_SOLVED) {
823
+ return Symbol("not_solved");
824
+ } else if (status == RoutingModel::ROUTING_SUCCESS) {
825
+ return Symbol("success");
826
+ } else if (status == RoutingModel::ROUTING_FAIL) {
827
+ return Symbol("fail");
828
+ } else if (status == RoutingModel::ROUTING_FAIL_TIMEOUT) {
829
+ return Symbol("fail_timeout");
830
+ } else if (status == RoutingModel::ROUTING_INVALID) {
831
+ return Symbol("invalid");
832
+ } else {
833
+ throw std::runtime_error("Unknown solver status");
834
+ }
835
+ })
792
836
  .define_method("vehicle_var", &RoutingModel::VehicleVar)
793
837
  .define_method("set_arc_cost_evaluator_of_all_vehicles", &RoutingModel::SetArcCostEvaluatorOfAllVehicles)
794
838
  .define_method("set_arc_cost_evaluator_of_vehicle", &RoutingModel::SetArcCostEvaluatorOfVehicle)
@@ -805,6 +849,15 @@ void Init_ext()
805
849
  }
806
850
  self.AddDimensionWithVehicleCapacity(evaluator_index, slack_max, vehicle_capacities, fix_start_cumul_to_zero, name);
807
851
  })
852
+ .define_method(
853
+ "add_dimension_with_vehicle_transits",
854
+ *[](RoutingModel& self, Array rb_indices, int64 slack_max, int64 capacity, bool fix_start_cumul_to_zero, const std::string& name) {
855
+ std::vector<int> evaluator_indices;
856
+ for (std::size_t i = 0; i < rb_indices.size(); ++i) {
857
+ evaluator_indices.push_back(from_ruby<int>(rb_indices[i]));
858
+ }
859
+ self.AddDimensionWithVehicleTransits(evaluator_indices, slack_max, capacity, fix_start_cumul_to_zero, name);
860
+ })
808
861
  .define_method(
809
862
  "add_disjunction",
810
863
  *[](RoutingModel& self, Array rb_indices, int64 penalty) {
@@ -2,7 +2,7 @@ require "mkmf-rice"
2
2
 
3
3
  raise "Missing stdc++" unless have_library("stdc++")
4
4
 
5
- $CXXFLAGS << " -std=c++11 -DUSE_CBC"
5
+ $CXXFLAGS << " -std=c++17 -DUSE_CBC"
6
6
 
7
7
  # or-tools warnings
8
8
  $CXXFLAGS << " -Wno-sign-compare -Wno-shorten-64-to-32 -Wno-ignored-qualifiers"
@@ -3,26 +3,26 @@ require "fileutils"
3
3
  require "net/http"
4
4
  require "tmpdir"
5
5
 
6
- version = "7.7.7810"
6
+ version = "8.1.8487"
7
7
 
8
8
  if RbConfig::CONFIG["host_os"] =~ /darwin/i
9
- filename = "or-tools_MacOsX-10.15.5_v#{version}.tar.gz"
10
- checksum = "764f290f6d916bc366913a37d93e6f83bd7969ad33515ccc1ca390f544d65721"
9
+ filename = "or-tools_MacOsX-10.15.7_v#{version}.tar.gz"
10
+ checksum = "cdf5d5c4dd10ddfa39eb951e6b8122b2a48c7d1dbd87bb5f792a7596aea8b8bb"
11
11
  else
12
12
  os = %x[lsb_release -is].chomp rescue nil
13
13
  os_version = %x[lsb_release -rs].chomp rescue nil
14
- if os == "Ubuntu" && os_version == "18.04"
14
+ if os == "Ubuntu" && os_version == "20.04"
15
+ filename = "or-tools_ubuntu-20.04_v#{version}.tar.gz"
16
+ checksum = "2de596d649d9a0f0dfec8007d6e1018d8fdddced7aa340b4e68d02e61df89a2e"
17
+ elsif os == "Ubuntu" && os_version == "18.04"
15
18
  filename = "or-tools_ubuntu-18.04_v#{version}.tar.gz"
16
- checksum = "12bdac29144b077b3f9ba602f947e4b9b9ce63ed3df4e325cda1333827edbcf8"
17
- elsif os == "Ubuntu" && os_version == "16.04"
18
- filename = "or-tools_ubuntu-16.04_v#{version}.tar.gz"
19
- checksum = "cc696d342b97aa6cf7c62b6ae2cae95dfc665f2483d147c4117fdba434b13a53"
19
+ checksum = "201cf1d17379240311208f4c641bb5263ae19d8c4c1a6091d2778948fd375f48"
20
20
  elsif os == "Debian" && os_version == "10"
21
21
  filename = "or-tools_debian-10_v#{version}.tar.gz "
22
- checksum = "3dd0299e9ad8d12fe6d186bfd59e63080c8e9f3c6b0489af9900c389cf7e4224"
22
+ checksum = "18028ef7287cd83eed3dafeae1243a9adb445675f45984e8d3c60ab9e2aa75bd"
23
23
  elsif os == "CentOS" && os_version == "8"
24
24
  filename = "or-tools_centos-8_v#{version}.tar.gz"
25
- checksum = "1f7d8bce56807c4283374e05024ffac8afd81ff99063217418d02d626cf03088"
25
+ checksum = "e26229320f9b78315f0122b55d16093c79e2dc6c95d591f4788f323f27cfd3bf"
26
26
  else
27
27
  # there is a binary download for Windows
28
28
  # however, it's compiled with Visual Studio rather than MinGW (which RubyInstaller uses)
@@ -11,6 +11,7 @@ require "or_tools/cp_solver_solution_callback"
11
11
  require "or_tools/int_var"
12
12
  require "or_tools/knapsack_solver"
13
13
  require "or_tools/linear_expr"
14
+ require "or_tools/routing_index_manager"
14
15
  require "or_tools/routing_model"
15
16
  require "or_tools/sat_linear_expr"
16
17
  require "or_tools/sat_int_var"
@@ -7,7 +7,7 @@ module ORTools
7
7
  def_delegators :@response, :objective_value, :num_conflicts, :num_branches, :wall_time
8
8
 
9
9
  def solve(model)
10
- @response = _solve(model)
10
+ @response = _solve(model, parameters)
11
11
  @response.status
12
12
  end
13
13
 
@@ -20,13 +20,17 @@ module ORTools
20
20
  end
21
21
 
22
22
  def solve_with_solution_callback(model, observer)
23
- @response = _solve_with_observer(model, observer, false)
23
+ @response = _solve_with_observer(model, parameters, observer, false)
24
24
  @response.status
25
25
  end
26
26
 
27
27
  def search_for_all_solutions(model, observer)
28
- @response = _solve_with_observer(model, observer, true)
28
+ @response = _solve_with_observer(model, parameters, observer, true)
29
29
  @response.status
30
30
  end
31
+
32
+ def parameters
33
+ @parameters ||= SatParameters.new
34
+ end
31
35
  end
32
36
  end
@@ -0,0 +1,11 @@
1
+ module ORTools
2
+ class RoutingIndexManager
3
+ def self.new(num_nodes, num_vehicles, starts, ends = nil)
4
+ if ends
5
+ _new_starts_ends(num_nodes, num_vehicles, starts, ends)
6
+ else
7
+ _new_depot(num_nodes, num_vehicles, starts)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,3 +1,3 @@
1
1
  module ORTools
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: or-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-21 00:00:00.000000000 Z
11
+ date: 2021-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rice
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '2.2'
19
+ version: '3'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '2.2'
26
+ version: '3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -80,7 +80,7 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '5'
83
- description:
83
+ description:
84
84
  email: andrew@chartkick.com
85
85
  executables: []
86
86
  extensions:
@@ -102,10 +102,10 @@ files:
102
102
  - lib/or_tools/cp_model.rb
103
103
  - lib/or_tools/cp_solver.rb
104
104
  - lib/or_tools/cp_solver_solution_callback.rb
105
- - lib/or_tools/ext.bundle
106
105
  - lib/or_tools/int_var.rb
107
106
  - lib/or_tools/knapsack_solver.rb
108
107
  - lib/or_tools/linear_expr.rb
108
+ - lib/or_tools/routing_index_manager.rb
109
109
  - lib/or_tools/routing_model.rb
110
110
  - lib/or_tools/sat_int_var.rb
111
111
  - lib/or_tools/sat_linear_expr.rb
@@ -118,7 +118,7 @@ homepage: https://github.com/ankane/or-tools
118
118
  licenses:
119
119
  - MIT
120
120
  metadata: {}
121
- post_install_message:
121
+ post_install_message:
122
122
  rdoc_options: []
123
123
  require_paths:
124
124
  - lib
@@ -126,15 +126,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
126
126
  requirements:
127
127
  - - ">="
128
128
  - !ruby/object:Gem::Version
129
- version: '2.4'
129
+ version: '2.6'
130
130
  required_rubygems_version: !ruby/object:Gem::Requirement
131
131
  requirements:
132
132
  - - ">="
133
133
  - !ruby/object:Gem::Version
134
134
  version: '0'
135
135
  requirements: []
136
- rubygems_version: 3.1.2
137
- signing_key:
136
+ rubygems_version: 3.2.3
137
+ signing_key:
138
138
  specification_version: 4
139
139
  summary: Operations research tools for Ruby
140
140
  test_files: []
Binary file