or-tools 0.6.1 → 0.7.0
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 +4 -4
- data/CHANGELOG.md +15 -0
- data/NOTICE.txt +2 -2
- data/README.md +1 -1
- data/ext/or-tools/constraint.cpp +9 -19
- data/ext/or-tools/extconf.rb +1 -6
- data/ext/or-tools/linear.cpp +7 -93
- data/ext/or-tools/vendor.rb +39 -16
- data/lib/or-tools.rb +5 -0
- data/lib/or_tools/comparison.rb +6 -1
- data/lib/or_tools/constant.rb +23 -0
- data/lib/or_tools/linear_constraint.rb +50 -0
- data/lib/or_tools/linear_expr.rb +58 -12
- data/lib/or_tools/mp_variable.rb +12 -0
- data/lib/or_tools/product_cst.rb +31 -0
- data/lib/or_tools/sat_int_var.rb +6 -2
- data/lib/or_tools/sat_linear_expr.rb +6 -1
- data/lib/or_tools/solver.rb +19 -1
- data/lib/or_tools/sum_array.rb +23 -0
- data/lib/or_tools/version.rb +1 -1
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 03544e925041f7337e6e6ba1b00b6d6c4d97353bcd7ee3785a46959a952bf09c
|
4
|
+
data.tar.gz: eddbab6814900afc7ddda651da92a53aa06b0db857659ab2ccd1c1adb9770fe0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '041939b99da310567a099f7654658697b93e36436abf06779336ca51e0d02be94473c0474d238041285975f293734cde65c37e5db565b8f30b49f856fe519100'
|
7
|
+
data.tar.gz: '09f6a2f0701acb005f356555df0d0e19befe36090d4de1b2188e7944a55836c80022eed5d4e185dc3b3b016c9c73fa3d5957e8c3cf8adf83bf4773b1090e5f0a'
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
## 0.7.0 (2022-03-23)
|
2
|
+
|
3
|
+
- Updated OR-Tools to 9.3
|
4
|
+
- Removed `add_lin_min_equality` (use `add_min_equality` instead)
|
5
|
+
- Removed `add_lin_max_equality` (use `add_max_equality` instead)
|
6
|
+
- Dropped support for Debian 10
|
7
|
+
|
8
|
+
## 0.6.3 (2022-03-13)
|
9
|
+
|
10
|
+
- Reduced gem size
|
11
|
+
|
12
|
+
## 0.6.2 (2022-02-09)
|
13
|
+
|
14
|
+
- Fixed segfaults with `Solver`
|
15
|
+
|
1
16
|
## 0.6.1 (2022-01-22)
|
2
17
|
|
3
18
|
- Added installation instructions for Mac ARM
|
data/NOTICE.txt
CHANGED
data/README.md
CHANGED
data/ext/or-tools/constraint.cpp
CHANGED
@@ -57,11 +57,11 @@ namespace Rice::detail
|
|
57
57
|
auto coeff = From_Ruby<int64_t>().convert(cvar[1].value());
|
58
58
|
|
59
59
|
if (var.is_a(rb_cBoolVar)) {
|
60
|
-
expr
|
60
|
+
expr += From_Ruby<BoolVar>().convert(var.value()) * coeff;
|
61
61
|
} else if (var.is_a(rb_cInteger)) {
|
62
|
-
expr
|
62
|
+
expr += From_Ruby<int64_t>().convert(var.value()) * coeff;
|
63
63
|
} else {
|
64
|
-
expr
|
64
|
+
expr += From_Ruby<IntVar>().convert(var.value()) * coeff;
|
65
65
|
}
|
66
66
|
}
|
67
67
|
} else {
|
@@ -253,42 +253,32 @@ void init_constraint(Rice::Module& m) {
|
|
253
253
|
})
|
254
254
|
.define_method(
|
255
255
|
"add_min_equality",
|
256
|
-
[](CpModelBuilder& self,
|
256
|
+
[](CpModelBuilder& self, LinearExpr target, std::vector<LinearExpr> vars) {
|
257
257
|
return self.AddMinEquality(target, vars);
|
258
258
|
})
|
259
|
-
.define_method(
|
260
|
-
"add_lin_min_equality",
|
261
|
-
[](CpModelBuilder& self, LinearExpr target, std::vector<LinearExpr> exprs) {
|
262
|
-
return self.AddLinMinEquality(target, exprs);
|
263
|
-
})
|
264
259
|
.define_method(
|
265
260
|
"add_max_equality",
|
266
|
-
[](CpModelBuilder& self,
|
261
|
+
[](CpModelBuilder& self, LinearExpr target, std::vector<LinearExpr> vars) {
|
267
262
|
return self.AddMaxEquality(target, vars);
|
268
263
|
})
|
269
|
-
.define_method(
|
270
|
-
"add_lin_max_equality",
|
271
|
-
[](CpModelBuilder& self, LinearExpr target, std::vector<LinearExpr> exprs) {
|
272
|
-
return self.AddLinMaxEquality(target, exprs);
|
273
|
-
})
|
274
264
|
.define_method(
|
275
265
|
"add_division_equality",
|
276
|
-
[](CpModelBuilder& self,
|
266
|
+
[](CpModelBuilder& self, LinearExpr target, LinearExpr numerator, LinearExpr denominator) {
|
277
267
|
return self.AddDivisionEquality(target, numerator, denominator);
|
278
268
|
})
|
279
269
|
.define_method(
|
280
270
|
"add_abs_equality",
|
281
|
-
[](CpModelBuilder& self,
|
271
|
+
[](CpModelBuilder& self, LinearExpr target, LinearExpr var) {
|
282
272
|
return self.AddAbsEquality(target, var);
|
283
273
|
})
|
284
274
|
.define_method(
|
285
275
|
"add_modulo_equality",
|
286
|
-
[](CpModelBuilder& self,
|
276
|
+
[](CpModelBuilder& self, LinearExpr target, LinearExpr var, LinearExpr mod) {
|
287
277
|
return self.AddModuloEquality(target, var, mod);
|
288
278
|
})
|
289
279
|
.define_method(
|
290
280
|
"add_multiplication_equality",
|
291
|
-
[](CpModelBuilder& self,
|
281
|
+
[](CpModelBuilder& self, LinearExpr target, std::vector<LinearExpr> vars) {
|
292
282
|
return self.AddMultiplicationEquality(target, vars);
|
293
283
|
})
|
294
284
|
.define_method(
|
data/ext/or-tools/extconf.rb
CHANGED
@@ -25,12 +25,7 @@ end
|
|
25
25
|
|
26
26
|
$INCFLAGS << " -I#{inc}"
|
27
27
|
|
28
|
-
$LDFLAGS
|
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")
|
data/ext/or-tools/linear.cpp
CHANGED
@@ -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) {
|
data/ext/or-tools/vendor.rb
CHANGED
@@ -4,7 +4,7 @@ require "fileutils"
|
|
4
4
|
require "net/http"
|
5
5
|
require "tmpdir"
|
6
6
|
|
7
|
-
version = "9.
|
7
|
+
version = "9.3.10497"
|
8
8
|
|
9
9
|
if RbConfig::CONFIG["host_os"] =~ /darwin/i
|
10
10
|
if RbConfig::CONFIG["host_cpu"] =~ /arm|aarch64/i
|
@@ -17,8 +17,8 @@ if RbConfig::CONFIG["host_os"] =~ /darwin/i
|
|
17
17
|
|
18
18
|
MSG
|
19
19
|
else
|
20
|
-
filename = "or-tools_MacOsX-12.
|
21
|
-
checksum = "
|
20
|
+
filename = "or-tools_MacOsX-12.2.1_v#{version}.tar.gz"
|
21
|
+
checksum = "33941702c59983897935eef06d91aca6c89ed9a8f5f4de3a9dfe489e97d7ca8c"
|
22
22
|
end
|
23
23
|
else
|
24
24
|
# try /etc/os-release with fallback to /usr/lib/os-release
|
@@ -32,23 +32,21 @@ else
|
|
32
32
|
os_version = os_info["VERSION_ID"]
|
33
33
|
|
34
34
|
if os == "ubuntu" && os_version == "20.04"
|
35
|
-
|
36
|
-
|
35
|
+
# TODO remove sub in v9.4
|
36
|
+
filename = "or-tools_amd64_ubuntu-20.04_v#{version.sub(".10497", ".10502")}.tar.gz"
|
37
|
+
checksum = "3d1979967a2c9358b5bc956f2e6b608b00e89e13c71d48d075475ce4138b6d1c"
|
37
38
|
elsif os == "ubuntu" && os_version == "18.04"
|
38
39
|
filename = "or-tools_amd64_ubuntu-18.04_v#{version}.tar.gz"
|
39
|
-
checksum = "
|
40
|
+
checksum = "6ba5cc153417267e8f8e15f8b6390b17f22de07bacc61f3740a4172ccd56c274"
|
40
41
|
elsif os == "debian" && os_version == "11"
|
41
42
|
filename = "or-tools_amd64_debian-11_v#{version}.tar.gz"
|
42
|
-
checksum = "
|
43
|
-
elsif os == "debian" && os_version == "10"
|
44
|
-
filename = "or-tools_amd64_debian-10_v#{version}.tar.gz"
|
45
|
-
checksum = "b152fee584f0c8228fe2ff21b74c789870ff9b7064e42ca26305c6b5653f0064"
|
43
|
+
checksum = "db0636bab909eabf06a7004f7572dca6fa152f3823c1365b0b7428405bf250e6"
|
46
44
|
elsif os == "centos" && os_version == "8"
|
47
45
|
filename = "or-tools_amd64_centos-8_v#{version}.tar.gz"
|
48
|
-
checksum = "
|
46
|
+
checksum = "e5649069fd7a3e8228cc18b91e265a90562c5d03a0c962b0346911aada0aedc9"
|
49
47
|
elsif os == "centos" && os_version == "7"
|
50
48
|
filename = "or-tools_amd64_centos-7_v#{version}.tar.gz"
|
51
|
-
checksum = "
|
49
|
+
checksum = "3bffdec8c09fc1345dcbd6a553437e2894014093fafb53e50adc7d4d776bb08b"
|
52
50
|
else
|
53
51
|
platform =
|
54
52
|
if Gem.win_platform?
|
@@ -121,12 +119,37 @@ end
|
|
121
119
|
download_checksum = Digest::SHA256.file(download_path).hexdigest
|
122
120
|
raise "Bad checksum: #{download_checksum}" if download_checksum != checksum
|
123
121
|
|
124
|
-
# extract - can't use Gem::Package#extract_tar_gz from RubyGems
|
125
|
-
# since it limits filenames to 100 characters (doesn't support UStar format)
|
126
122
|
path = File.expand_path("../../tmp/or-tools", __dir__)
|
127
123
|
FileUtils.mkdir_p(path)
|
128
|
-
|
129
|
-
|
124
|
+
|
125
|
+
# extract - can't use Gem::Package#extract_tar_gz from RubyGems
|
126
|
+
# since it limits filenames to 100 characters (doesn't support UStar format)
|
127
|
+
# for space, only keep licenses, include, and shared library
|
128
|
+
Dir.mktmpdir do |extract_path|
|
129
|
+
tar_args = Gem.win_platform? ? ["--force-local"] : []
|
130
|
+
system "tar", "zxf", download_path, "-C", extract_path, "--strip-components=1", *tar_args
|
131
|
+
|
132
|
+
# licenses
|
133
|
+
license_files = Dir.glob("**/*{LICENSE,LICENCE,NOTICE,COPYING,license,licence,notice,copying}*", base: extract_path)
|
134
|
+
raise "License not found" unless license_files.any?
|
135
|
+
license_files.each do |file|
|
136
|
+
FileUtils.mkdir_p(File.join(path, File.dirname(file)))
|
137
|
+
FileUtils.cp(File.join(extract_path, file), File.join(path, file))
|
138
|
+
end
|
139
|
+
|
140
|
+
# include
|
141
|
+
FileUtils.cp_r(File.join(extract_path, "include"), File.join(path, "include"))
|
142
|
+
|
143
|
+
# shared library
|
144
|
+
FileUtils.mkdir(File.join(path, "lib"))
|
145
|
+
Dir.glob("lib/libortools.{dylib,so.9}", base: extract_path) do |file|
|
146
|
+
FileUtils.cp(File.join(extract_path, file), File.join(path, file))
|
147
|
+
end
|
148
|
+
so_path = File.join(path, "lib/libortools.so.9")
|
149
|
+
if File.exist?(so_path)
|
150
|
+
File.symlink(so_path, File.join(path, "lib/libortools.so"))
|
151
|
+
end
|
152
|
+
end
|
130
153
|
|
131
154
|
# export
|
132
155
|
$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
|
data/lib/or_tools/comparison.rb
CHANGED
@@ -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
|
data/lib/or_tools/linear_expr.rb
CHANGED
@@ -1,27 +1,73 @@
|
|
1
1
|
module ORTools
|
2
2
|
class LinearExpr
|
3
|
-
def
|
4
|
-
|
5
|
-
|
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
|
-
|
45
|
+
LinearConstraint.new(self - arg, 0.0, 0.0)
|
8
46
|
end
|
9
47
|
end
|
10
48
|
|
11
|
-
def >=(
|
12
|
-
if
|
13
|
-
|
49
|
+
def >=(arg)
|
50
|
+
if arg.is_a?(Numeric)
|
51
|
+
LinearConstraint.new(self, arg, Float::INFINITY)
|
14
52
|
else
|
15
|
-
|
53
|
+
LinearConstraint.new(self - arg, 0.0, Float::INFINITY)
|
16
54
|
end
|
17
55
|
end
|
18
56
|
|
19
|
-
def <=(
|
20
|
-
if
|
21
|
-
|
57
|
+
def <=(arg)
|
58
|
+
if arg.is_a?(Numeric)
|
59
|
+
LinearConstraint.new(self, -Float::INFINITY, arg)
|
22
60
|
else
|
23
|
-
|
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,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
|
data/lib/or_tools/sat_int_var.rb
CHANGED
@@ -24,7 +24,7 @@ module ORTools
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
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)
|
data/lib/or_tools/solver.rb
CHANGED
@@ -1,7 +1,25 @@
|
|
1
1
|
module ORTools
|
2
2
|
class Solver
|
3
3
|
def sum(arr)
|
4
|
-
|
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
|
data/lib/or_tools/version.rb
CHANGED
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.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-03-23 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.3.
|
95
|
+
rubygems_version: 3.3.7
|
91
96
|
signing_key:
|
92
97
|
specification_version: 4
|
93
98
|
summary: Operations research tools for Ruby
|