or-tools 0.6.0 → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1775ae46a18be137ae64fce870d29c17c3ae385c61f295f79d7ded40ed0be0bd
4
- data.tar.gz: 28262f8b77a8dd0dc085e16a261005a47e1352d8f9f5c148ed524c348daec8db
3
+ metadata.gz: a94dfe67ccc7166a4ab27cbf5747d332452715db7ad302fa325ef7b5b270ef12
4
+ data.tar.gz: 36aacbdbf3be07f26e8711bc0ec00d8c1ac929288c62661f7425c721eb827c5d
5
5
  SHA512:
6
- metadata.gz: 771d9a78ace00ce16d8f5e71f595a4523fd8613c81b8e09691d231cb1e7881ce94e8cdd0e21dd60168a58d40e0135891988cfc47fac33d511b551cf932819bae
7
- data.tar.gz: 5231109d9afb080481f608bd784b3e86cdfc0b336f828d9fad714b5fa37eda0c4f02495e3718eeb9b0c05135b5b344a7084df55c7f26674ef2e73653ad7d8a3d
6
+ metadata.gz: 9c66c41c7b34b75f09725bbf74c04e7d7a9c2eee5251cc294480baa9a4f8a1a0fcde3534f75f3462d69fdc7c97ec5367dac1cf5fae210351ae731c1cb3c4d5f3
7
+ data.tar.gz: c8cc4f3c87e7199f9322caa714435699e000be1888f33e2c6b1121aa72dfab1d8b10ba8100fd3ff64b6dcc43853c2b36485922cab2f3b0268ec8cddb1fe15bdc
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## 0.6.3 (2022-03-13)
2
+
3
+ - Reduced gem size
4
+
5
+ ## 0.6.2 (2022-02-09)
6
+
7
+ - Fixed segfaults with `Solver`
8
+
9
+ ## 0.6.1 (2022-01-22)
10
+
11
+ - Added installation instructions for Mac ARM
12
+ - Removed dependency on `lsb_release` for binary installation on Linux
13
+
1
14
  ## 0.6.0 (2021-12-16)
2
15
 
3
16
  - Updated OR-Tools to 9.2
data/NOTICE.txt CHANGED
@@ -1,5 +1,5 @@
1
- Copyright 2010-2018 Google LLC
2
- Copyright 2020-2021 Andrew Kane
1
+ Copyright 2010-2021 Google LLC
2
+ Copyright 2020-2022 Andrew Kane
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
data/README.md CHANGED
@@ -9,10 +9,10 @@
9
9
  Add this line to your application’s Gemfile:
10
10
 
11
11
  ```ruby
12
- gem 'or-tools'
12
+ gem "or-tools"
13
13
  ```
14
14
 
15
- Installation can take a few minutes as OR-Tools downloads and builds.
15
+ Installation can take a few minutes as OR-Tools downloads and builds. For Mac ARM, also follow [these instructions](#additional-instructions).
16
16
 
17
17
  ## Higher Level Interfaces
18
18
 
@@ -2201,6 +2201,17 @@ possible_tables.each do |table|
2201
2201
  end
2202
2202
  ```
2203
2203
 
2204
+ ## Additional Instructions
2205
+
2206
+ ### Mac ARM
2207
+
2208
+ ARM binaries are not available for Mac yet, so use Homebrew to install OR-Tools before installing the gem.
2209
+
2210
+ ```sh
2211
+ brew install or-tools
2212
+ bundle config build.or-tools --with-or-tools-dir=/opt/homebrew
2213
+ ```
2214
+
2204
2215
  ## History
2205
2216
 
2206
2217
  View the [changelog](https://github.com/ankane/or-tools-ruby/blob/master/CHANGELOG.md)
@@ -25,12 +25,7 @@ end
25
25
 
26
26
  $INCFLAGS << " -I#{inc}"
27
27
 
28
- $LDFLAGS << " -Wl,-rpath,#{rpath}"
29
- $LDFLAGS << " -L#{lib}"
28
+ $LDFLAGS.prepend("-Wl,-rpath,#{rpath} -L#{lib} ")
30
29
  raise "OR-Tools not found" unless have_library("ortools")
31
30
 
32
- Dir["#{lib}/libabsl_*.a"].each do |lib|
33
- $LDFLAGS << " #{lib}"
34
- end
35
-
36
31
  create_makefile("or_tools/ext")
@@ -46,86 +46,14 @@ namespace Rice::detail
46
46
 
47
47
  void init_linear(Rice::Module& m) {
48
48
  Rice::define_class_under<LinearRange>(m, "LinearRange");
49
+
50
+ // TODO remove in 0.7.0
49
51
  auto rb_cLinearExpr = Rice::define_class_under<LinearExpr>(m, "LinearExpr");
52
+ rb_cLinearExpr.define_constructor(Rice::Constructor<LinearExpr>());
50
53
 
51
- Rice::define_class_under<MPVariable>(m, "MPVariable")
54
+ Rice::define_class_under<MPVariable, LinearExpr>(m, "MPVariable")
52
55
  .define_method("name", &MPVariable::name)
53
- .define_method("solution_value", &MPVariable::solution_value)
54
- .define_method(
55
- "+",
56
- [](MPVariable& self, LinearExpr& other) {
57
- LinearExpr s(&self);
58
- return s + other;
59
- })
60
- .define_method(
61
- "-",
62
- [](MPVariable& self, LinearExpr& other) {
63
- LinearExpr s(&self);
64
- return s - other;
65
- })
66
- .define_method(
67
- "*",
68
- [](MPVariable& self, double other) {
69
- LinearExpr s(&self);
70
- return s * other;
71
- })
72
- .define_method(
73
- "inspect",
74
- [](MPVariable& self) {
75
- return "#<ORTools::MPVariable @name=\"" + self.name() + "\">";
76
- });
77
-
78
- rb_cLinearExpr
79
- .define_constructor(Rice::Constructor<LinearExpr>())
80
- .define_method(
81
- "_add_linear_expr",
82
- [](LinearExpr& self, LinearExpr& other) {
83
- return self + other;
84
- })
85
- .define_method(
86
- "_add_mp_variable",
87
- [](LinearExpr& self, MPVariable &other) {
88
- LinearExpr o(&other);
89
- return self + o;
90
- })
91
- .define_method(
92
- "_gte_double",
93
- [](LinearExpr& self, double other) {
94
- LinearExpr o(other);
95
- return self >= o;
96
- })
97
- .define_method(
98
- "_gte_linear_expr",
99
- [](LinearExpr& self, LinearExpr& other) {
100
- return self >= other;
101
- })
102
- .define_method(
103
- "_lte_double",
104
- [](LinearExpr& self, double other) {
105
- LinearExpr o(other);
106
- return self <= o;
107
- })
108
- .define_method(
109
- "_lte_linear_expr",
110
- [](LinearExpr& self, LinearExpr& other) {
111
- return self <= other;
112
- })
113
- .define_method(
114
- "==",
115
- [](LinearExpr& self, double other) {
116
- LinearExpr o(other);
117
- return self == o;
118
- })
119
- .define_method(
120
- "to_s",
121
- [](LinearExpr& self) {
122
- return self.ToString();
123
- })
124
- .define_method(
125
- "inspect",
126
- [](LinearExpr& self) {
127
- return "#<ORTools::LinearExpr \"" + self.ToString() + "\">";
128
- });
56
+ .define_method("solution_value", &MPVariable::solution_value);
129
57
 
130
58
  Rice::define_class_under<MPConstraint>(m, "MPConstraint")
131
59
  .define_method("set_coefficient", &MPConstraint::SetCoefficient);
@@ -133,7 +61,8 @@ void init_linear(Rice::Module& m) {
133
61
  Rice::define_class_under<MPObjective>(m, "MPObjective")
134
62
  .define_method("value", &MPObjective::Value)
135
63
  .define_method("set_coefficient", &MPObjective::SetCoefficient)
136
- .define_method("set_maximization", &MPObjective::SetMaximization);
64
+ .define_method("set_maximization", &MPObjective::SetMaximization)
65
+ .define_method("set_minimization", &MPObjective::SetMinimization);
137
66
 
138
67
  Rice::define_class_under<MPSolver>(m, "Solver")
139
68
  .define_constructor(Rice::Constructor<MPSolver, std::string, MPSolver::OptimizationProblemType>())
@@ -155,21 +84,6 @@ void init_linear(Rice::Module& m) {
155
84
  .define_method("iterations", &MPSolver::iterations)
156
85
  .define_method("nodes", &MPSolver::nodes)
157
86
  .define_method("objective", &MPSolver::MutableObjective)
158
- .define_method(
159
- "maximize",
160
- [](MPSolver& self, LinearExpr& expr) {
161
- return self.MutableObjective()->MaximizeLinearExpr(expr);
162
- })
163
- .define_method(
164
- "minimize",
165
- [](MPSolver& self, LinearExpr& expr) {
166
- return self.MutableObjective()->MinimizeLinearExpr(expr);
167
- })
168
- .define_method(
169
- "add",
170
- [](MPSolver& self, const LinearRange& range) {
171
- return self.MakeRowConstraint(range);
172
- })
173
87
  .define_method(
174
88
  "constraint",
175
89
  [](MPSolver& self, double lb, double ub) {
@@ -1,3 +1,4 @@
1
+ require "csv"
1
2
  require "digest"
2
3
  require "fileutils"
3
4
  require "net/http"
@@ -6,27 +7,46 @@ require "tmpdir"
6
7
  version = "9.2.9972"
7
8
 
8
9
  if RbConfig::CONFIG["host_os"] =~ /darwin/i
9
- filename = "or-tools_MacOsX-12.0.1_v#{version}.tar.gz"
10
- checksum = "796791a8ef84507d62e193e647cccb1c7725dae4f1474476e1777fe4a44ee3e0"
10
+ if RbConfig::CONFIG["host_cpu"] =~ /arm|aarch64/i
11
+ raise <<~MSG
12
+ Binary installation not available for this platform: Mac ARM
13
+
14
+ Run:
15
+ brew install or-tools
16
+ bundle config build.or-tools --with-or-tools-dir=/opt/homebrew
17
+
18
+ MSG
19
+ else
20
+ filename = "or-tools_MacOsX-12.0.1_v#{version}.tar.gz"
21
+ checksum = "796791a8ef84507d62e193e647cccb1c7725dae4f1474476e1777fe4a44ee3e0"
22
+ end
11
23
  else
12
- os = %x[lsb_release -is].chomp rescue nil
13
- os_version = %x[lsb_release -rs].chomp rescue nil
14
- if os == "Ubuntu" && os_version == "20.04"
24
+ # try /etc/os-release with fallback to /usr/lib/os-release
25
+ # https://www.freedesktop.org/software/systemd/man/os-release.html
26
+ os_filename = File.exist?("/etc/os-release") ? "/etc/os-release" : "/usr/lib/os-release"
27
+
28
+ # for safety, parse rather than source
29
+ os_info = CSV.read(os_filename, col_sep: "=").to_h rescue {}
30
+
31
+ os = os_info["ID"]
32
+ os_version = os_info["VERSION_ID"]
33
+
34
+ if os == "ubuntu" && os_version == "20.04"
15
35
  filename = "or-tools_amd64_ubuntu-20.04_v#{version}.tar.gz"
16
36
  checksum = "985e3036eaecacfc8a0258ec2ebef429240491577d4e0896d68fc076e65451ec"
17
- elsif os == "Ubuntu" && os_version == "18.04"
37
+ elsif os == "ubuntu" && os_version == "18.04"
18
38
  filename = "or-tools_amd64_ubuntu-18.04_v#{version}.tar.gz"
19
39
  checksum = "e36406c4fe8c111e1ace0ede9d0787ff0e98f11afd7db9cc074adfd0f55628a6"
20
- elsif os == "Debian" && os_version == "11"
40
+ elsif os == "debian" && os_version == "11"
21
41
  filename = "or-tools_amd64_debian-11_v#{version}.tar.gz"
22
42
  checksum = "bd49ee916213b2140ab255414d35a28f19dff7caf87632309753d3fc553f85dd"
23
- elsif os == "Debian" && os_version == "10"
43
+ elsif os == "debian" && os_version == "10"
24
44
  filename = "or-tools_amd64_debian-10_v#{version}.tar.gz"
25
45
  checksum = "b152fee584f0c8228fe2ff21b74c789870ff9b7064e42ca26305c6b5653f0064"
26
- elsif os == "CentOS" && os_version == "8"
46
+ elsif os == "centos" && os_version == "8"
27
47
  filename = "or-tools_amd64_centos-8_v#{version}.tar.gz"
28
48
  checksum = "66ed4bb800acf92c672f7e68acdf4ea27bbfdb17bbddc02f8326cd55a97305f6"
29
- elsif os == "CentOS" && os_version == "7"
49
+ elsif os == "centos" && os_version == "7"
30
50
  filename = "or-tools_amd64_centos-7_v#{version}.tar.gz"
31
51
  checksum = "4a5c1b1639a2828cd7e1ba82a574ef37876557b59e8aab8b81811bb750d53035"
32
52
  else
@@ -101,12 +121,33 @@ end
101
121
  download_checksum = Digest::SHA256.file(download_path).hexdigest
102
122
  raise "Bad checksum: #{download_checksum}" if download_checksum != checksum
103
123
 
104
- # extract - can't use Gem::Package#extract_tar_gz from RubyGems
105
- # since it limits filenames to 100 characters (doesn't support UStar format)
106
124
  path = File.expand_path("../../tmp/or-tools", __dir__)
107
125
  FileUtils.mkdir_p(path)
108
- tar_args = Gem.win_platform? ? ["--force-local"] : []
109
- system "tar", "zxf", download_path, "-C", path, "--strip-components=1", *tar_args
126
+
127
+ # extract - can't use Gem::Package#extract_tar_gz from RubyGems
128
+ # since it limits filenames to 100 characters (doesn't support UStar format)
129
+ # for space, only keep licenses, include, and shared library
130
+ Dir.mktmpdir do |extract_path|
131
+ tar_args = Gem.win_platform? ? ["--force-local"] : []
132
+ system "tar", "zxf", download_path, "-C", extract_path, "--strip-components=1", *tar_args
133
+
134
+ # licenses
135
+ license_files = Dir.glob("**/*{LICENSE,LICENCE,NOTICE,COPYING,license,licence,notice,copying}*", base: extract_path)
136
+ raise "License not found" unless license_files.any?
137
+ license_files.each do |file|
138
+ FileUtils.mkdir_p(File.join(path, File.dirname(file)))
139
+ FileUtils.cp(File.join(extract_path, file), File.join(path, file))
140
+ end
141
+
142
+ # include
143
+ FileUtils.cp_r(File.join(extract_path, "include"), File.join(path, "include"))
144
+
145
+ # shared library
146
+ FileUtils.mkdir(File.join(path, "lib"))
147
+ Dir.glob("lib/libortools.{dylib,so}", base: extract_path) do |file|
148
+ FileUtils.cp(File.join(extract_path, file), File.join(path, file))
149
+ end
150
+ end
110
151
 
111
152
  # export
112
153
  $vendor_path = path
data/lib/or-tools.rb CHANGED
@@ -5,17 +5,22 @@ require "or_tools/ext"
5
5
  require "or_tools/comparison"
6
6
  require "or_tools/comparison_operators"
7
7
  require "or_tools/bool_var"
8
+ require "or_tools/constant"
8
9
  require "or_tools/cp_model"
9
10
  require "or_tools/cp_solver"
10
11
  require "or_tools/cp_solver_solution_callback"
11
12
  require "or_tools/int_var"
12
13
  require "or_tools/knapsack_solver"
14
+ require "or_tools/linear_constraint"
13
15
  require "or_tools/linear_expr"
16
+ require "or_tools/mp_variable"
17
+ require "or_tools/product_cst"
14
18
  require "or_tools/routing_index_manager"
15
19
  require "or_tools/routing_model"
16
20
  require "or_tools/sat_linear_expr"
17
21
  require "or_tools/sat_int_var"
18
22
  require "or_tools/solver"
23
+ require "or_tools/sum_array"
19
24
  require "or_tools/version"
20
25
 
21
26
  # solution printers
@@ -8,8 +8,13 @@ module ORTools
8
8
  @right = right
9
9
  end
10
10
 
11
- def inspect
11
+ def to_s
12
12
  "#{left.inspect} #{operator} #{right.inspect}"
13
13
  end
14
+
15
+ # TODO add class
16
+ def inspect
17
+ to_s
18
+ end
14
19
  end
15
20
  end
@@ -0,0 +1,23 @@
1
+ module ORTools
2
+ class Constant < LinearExpr
3
+ def initialize(val)
4
+ @val = val
5
+ end
6
+
7
+ def to_s
8
+ @val.to_s
9
+ end
10
+
11
+ def add_self_to_coeff_map_or_stack(coeffs, multiplier, stack)
12
+ coeffs[OFFSET_KEY] += @val * multiplier
13
+ end
14
+ end
15
+
16
+ class FakeMPVariableRepresentingTheConstantOffset
17
+ def solution_value
18
+ 1
19
+ end
20
+ end
21
+
22
+ OFFSET_KEY = FakeMPVariableRepresentingTheConstantOffset.new
23
+ end
@@ -0,0 +1,50 @@
1
+ module ORTools
2
+ class LinearConstraint
3
+ attr_reader :expr, :lb, :ub
4
+
5
+ def initialize(expr, lb, ub)
6
+ @expr = expr
7
+ @lb = lb
8
+ @ub = ub
9
+ end
10
+
11
+ def to_s
12
+ if @lb > -Float::INFINITY && @ub < Float::INFINITY
13
+ if @lb == @ub
14
+ "#{@expr} == #{@lb}"
15
+ else
16
+ "#{@lb} <= #{@expr} <= #{@ub}"
17
+ end
18
+ elsif @lb > -Float::INFINITY
19
+ "#{@expr} >= #{@lb}"
20
+ elsif @ub < Float::INFINITY
21
+ "#{@expr} <= #{@ub}"
22
+ else
23
+ "Trivial inequality (always true)"
24
+ end
25
+ end
26
+
27
+ def inspect
28
+ "#<#{self.class.name} #{to_s}>"
29
+ end
30
+
31
+ def extract(solver)
32
+ coeffs = @expr.coeffs
33
+ constant = coeffs.delete(OFFSET_KEY) || 0.0
34
+ lb = -solver.infinity
35
+ ub = solver.infinity
36
+ if @lb > -Float::INFINITY
37
+ lb = @lb - constant
38
+ end
39
+ if @ub < Float::INFINITY
40
+ ub = @ub - constant
41
+ end
42
+
43
+ constraint = solver.constraint(lb, ub)
44
+ coeffs.each do |v, c|
45
+ constraint.set_coefficient(v, c.to_f)
46
+ end
47
+ constraint
48
+ end
49
+ end
50
+ end
@@ -1,27 +1,73 @@
1
1
  module ORTools
2
2
  class LinearExpr
3
- def +(other)
4
- if other.is_a?(LinearExpr)
5
- _add_linear_expr(other)
3
+ def solution_value
4
+ coeffs.sum { |var, coeff| var.solution_value * coeff }
5
+ end
6
+
7
+ def coeffs
8
+ coeffs = Hash.new(0.0)
9
+ stack = [[1.0, self]]
10
+ while stack.any?
11
+ current_multiplier, current_expression = stack.pop
12
+
13
+ # skip empty LinearExpr for backwards compatibility
14
+ next if current_expression.instance_of?(LinearExpr)
15
+
16
+ current_expression.add_self_to_coeff_map_or_stack(coeffs, current_multiplier, stack)
17
+ end
18
+ coeffs
19
+ end
20
+
21
+ def +(expr)
22
+ SumArray.new([self, expr])
23
+ end
24
+
25
+ def -(expr)
26
+ SumArray.new([self, -expr])
27
+ end
28
+
29
+ def *(other)
30
+ ProductCst.new(self, other)
31
+ end
32
+
33
+ def /(cst)
34
+ ProductCst.new(self, 1.0 / other)
35
+ end
36
+
37
+ def -@
38
+ ProductCst.new(self, -1)
39
+ end
40
+
41
+ def ==(arg)
42
+ if arg.is_a?(Numeric)
43
+ LinearConstraint.new(self, arg, arg)
6
44
  else
7
- _add_mp_variable(other)
45
+ LinearConstraint.new(self - arg, 0.0, 0.0)
8
46
  end
9
47
  end
10
48
 
11
- def >=(other)
12
- if other.is_a?(LinearExpr)
13
- _gte_linear_expr(other)
49
+ def >=(arg)
50
+ if arg.is_a?(Numeric)
51
+ LinearConstraint.new(self, arg, Float::INFINITY)
14
52
  else
15
- _gte_double(other)
53
+ LinearConstraint.new(self - arg, 0.0, Float::INFINITY)
16
54
  end
17
55
  end
18
56
 
19
- def <=(other)
20
- if other.is_a?(LinearExpr)
21
- _lte_linear_expr(other)
57
+ def <=(arg)
58
+ if arg.is_a?(Numeric)
59
+ LinearConstraint.new(self, -Float::INFINITY, arg)
22
60
  else
23
- _lte_double(other)
61
+ LinearConstraint.new(self - arg, -Float::INFINITY, 0.0)
24
62
  end
25
63
  end
64
+
65
+ def to_s
66
+ "(empty)"
67
+ end
68
+
69
+ def inspect
70
+ "#<#{self.class.name} #{to_s}>"
71
+ end
26
72
  end
27
73
  end
@@ -0,0 +1,12 @@
1
+ module ORTools
2
+ # TODO change to VariableExpr in 0.7.0
3
+ class MPVariable < LinearExpr
4
+ def add_self_to_coeff_map_or_stack(coeffs, multiplier, stack)
5
+ coeffs[self] += multiplier
6
+ end
7
+
8
+ def to_s
9
+ name
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,31 @@
1
+ module ORTools
2
+ class ProductCst < LinearExpr
3
+ attr_reader :expr, :coef
4
+
5
+ def initialize(expr, coef)
6
+ @expr = cast_to_lin_exp(expr)
7
+ # TODO improve message
8
+ raise TypeError, "expected numeric" unless coef.is_a?(Numeric)
9
+ @coef = coef
10
+ end
11
+
12
+ def to_s
13
+ if @coef == -1
14
+ "-#{@expr}"
15
+ else
16
+ "(#{@coef} * #{@expr})"
17
+ end
18
+ end
19
+
20
+ def add_self_to_coeff_map_or_stack(coeffs, multiplier, stack)
21
+ current_multiplier = multiplier * @coef
22
+ if current_multiplier
23
+ stack << [current_multiplier, @expr]
24
+ end
25
+ end
26
+
27
+ def cast_to_lin_exp(v)
28
+ v.is_a?(Numeric) ? Constant.new(v) : v
29
+ end
30
+ end
31
+ end
@@ -18,9 +18,13 @@ module ORTools
18
18
  SatLinearExpr.new([[self, -1]])
19
19
  end
20
20
 
21
- # for now
22
- def inspect
21
+ def to_s
23
22
  name
24
23
  end
24
+
25
+ # TODO add class
26
+ def inspect
27
+ to_s
28
+ end
25
29
  end
26
30
  end
@@ -24,7 +24,7 @@ module ORTools
24
24
  end
25
25
  end
26
26
 
27
- def inspect
27
+ def to_s
28
28
  vars.map do |v|
29
29
  k = v[0]
30
30
  k = k.respond_to?(:name) ? k.name : k.inspect
@@ -36,6 +36,11 @@ module ORTools
36
36
  end.join(" + ").sub(" + -", " - ")
37
37
  end
38
38
 
39
+ # TODO add class
40
+ def inspect
41
+ to_s
42
+ end
43
+
39
44
  private
40
45
 
41
46
  def add(other, sign)
@@ -1,7 +1,25 @@
1
1
  module ORTools
2
2
  class Solver
3
3
  def sum(arr)
4
- arr.sum(LinearExpr.new)
4
+ SumArray.new(arr)
5
+ end
6
+
7
+ def add(expr)
8
+ expr.extract(self)
9
+ end
10
+
11
+ def maximize(expr)
12
+ expr.coeffs.each do |v, c|
13
+ objective.set_coefficient(v, c)
14
+ end
15
+ objective.set_maximization
16
+ end
17
+
18
+ def minimize(expr)
19
+ expr.coeffs.each do |v, c|
20
+ objective.set_coefficient(v, c)
21
+ end
22
+ objective.set_minimization
5
23
  end
6
24
  end
7
25
  end
@@ -0,0 +1,23 @@
1
+ module ORTools
2
+ class SumArray < LinearExpr
3
+ attr_reader :array
4
+
5
+ def initialize(array)
6
+ @array = array.map { |v| cast_to_lin_exp(v) }
7
+ end
8
+
9
+ def add_self_to_coeff_map_or_stack(coeffs, multiplier, stack)
10
+ @array.reverse.each do |arg|
11
+ stack << [multiplier, arg]
12
+ end
13
+ end
14
+
15
+ def cast_to_lin_exp(v)
16
+ v.is_a?(Numeric) ? Constant.new(v) : v
17
+ end
18
+
19
+ def to_s
20
+ "(#{@array.map(&:to_s).join(" + ")})"
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module ORTools
2
- VERSION = "0.6.0"
2
+ VERSION = "0.6.3"
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.6.0
4
+ version: 0.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-17 00:00:00.000000000 Z
11
+ date: 2022-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rice
@@ -50,13 +50,17 @@ files:
50
50
  - lib/or_tools/bool_var.rb
51
51
  - lib/or_tools/comparison.rb
52
52
  - lib/or_tools/comparison_operators.rb
53
+ - lib/or_tools/constant.rb
53
54
  - lib/or_tools/cp_model.rb
54
55
  - lib/or_tools/cp_solver.rb
55
56
  - lib/or_tools/cp_solver_solution_callback.rb
56
57
  - lib/or_tools/int_var.rb
57
58
  - lib/or_tools/knapsack_solver.rb
59
+ - lib/or_tools/linear_constraint.rb
58
60
  - lib/or_tools/linear_expr.rb
61
+ - lib/or_tools/mp_variable.rb
59
62
  - lib/or_tools/objective_solution_printer.rb
63
+ - lib/or_tools/product_cst.rb
60
64
  - lib/or_tools/routing_index_manager.rb
61
65
  - lib/or_tools/routing_model.rb
62
66
  - lib/or_tools/sat_int_var.rb
@@ -64,6 +68,7 @@ files:
64
68
  - lib/or_tools/seating.rb
65
69
  - lib/or_tools/solver.rb
66
70
  - lib/or_tools/sudoku.rb
71
+ - lib/or_tools/sum_array.rb
67
72
  - lib/or_tools/tsp.rb
68
73
  - lib/or_tools/var_array_and_objective_solution_printer.rb
69
74
  - lib/or_tools/var_array_solution_printer.rb
@@ -87,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
92
  - !ruby/object:Gem::Version
88
93
  version: '0'
89
94
  requirements: []
90
- rubygems_version: 3.2.32
95
+ rubygems_version: 3.3.7
91
96
  signing_key:
92
97
  specification_version: 4
93
98
  summary: Operations research tools for Ruby