Skip to content

Commit b39479a

Browse files
committed
Merge branch 'master' into valgrind
2 parents aded9f8 + 26e5c6d commit b39479a

27 files changed

+528
-213
lines changed

.github/workflows/build.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@ jobs:
77
fail-fast: false
88
matrix:
99
include:
10-
- ruby: 3.3
10+
- ruby: "4.0"
1111
os: ubuntu-24.04
12+
# - ruby: 3.4
13+
# os: ubuntu-24.04
14+
# - ruby: 3.3
15+
# os: macos-26
1216
# - ruby: 3.2
1317
# os: ubuntu-22.04
1418
# - ruby: 3.1
15-
# os: ubuntu-20.04
16-
# - ruby: 3.2
17-
# os: macos-14
18-
# - ruby: 3.1
19-
# os: macos-13
19+
# os: macos-15-intel
2020
steps:
21-
- uses: actions/checkout@v4
21+
- uses: actions/checkout@v5
2222
- uses: ruby/setup-ruby@v1
2323
with:
2424
ruby-version: ${{ matrix.ruby }}

CHANGELOG.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,43 @@
1+
## 0.17.0 (2026-01-12)
2+
3+
- Updated OR-Tools to 9.15
4+
5+
## 0.16.3 (2026-01-05)
6+
7+
- Fixed errors with Rice 4.9
8+
9+
## 0.16.2 (2026-01-02)
10+
11+
- Fixed error with Rice 4.8
12+
13+
## 0.16.1 (2025-10-26)
14+
15+
- Added `add_allowed_assignments` and `add_forbidden_assignments` methods to `CpModel`
16+
- Fixed error with Rice 4.7
17+
18+
## 0.16.0 (2025-06-19)
19+
20+
- Updated OR-Tools to 9.14
21+
22+
## 0.15.1 (2025-06-18)
23+
24+
- Fixed error with Rice 4.6
25+
26+
## 0.15.0 (2025-02-17)
27+
28+
- Updated OR-Tools to 9.12
29+
- Removed `pickup_positions` and `pickup_index_pairs` (use `pickup_position` instead)
30+
- Removed `delivery_positions` and `delivery_index_pairs` (use `delivery_position` instead)
31+
32+
## 0.14.2 (2025-02-10)
33+
34+
- Fixed error with Rice 4.5
35+
36+
## 0.14.1 (2024-12-04)
37+
38+
- Added support for parameters to `Solver`
39+
- Fixed error with `inspect` for `MathOpt` variables
40+
141
## 0.14.0 (2024-10-22)
242

343
- Added experimental support for `MathOpt`

Gemfile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@ gemspec
44

55
gem "rake"
66
gem "rake-compiler"
7-
gem "minitest", ">= 5"
8-
gem "ruby_memcheck"
7+
gem "minitest"
8+
gem "ruby_memcheck", require: false
9+
10+
# https://github.com/ruby/openssl/issues/952
11+
gem "openssl" if RUBY_PLATFORM =~ /darwin/

NOTICE.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
Copyright 2010-2021 Google LLC
2-
Copyright 2020-2022 Andrew Kane
1+
Copyright 2010-2025 Google LLC
2+
Copyright 2020-2026 Andrew Kane
33

44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,15 @@ Specify people and their availabililty
9393
people = [
9494
{
9595
availability: [
96-
{starts_at: Time.parse("2020-01-01 08:00:00"), ends_at: Time.parse("2020-01-01 16:00:00")},
97-
{starts_at: Time.parse("2020-01-02 08:00:00"), ends_at: Time.parse("2020-01-02 16:00:00")}
96+
{starts_at: Time.parse("2025-01-01 08:00:00"), ends_at: Time.parse("2025-01-01 16:00:00")},
97+
{starts_at: Time.parse("2025-01-02 08:00:00"), ends_at: Time.parse("2025-01-02 16:00:00")}
9898
],
9999
max_hours: 40 # optional, applies to entire scheduling period
100100
},
101101
{
102102
availability: [
103-
{starts_at: Time.parse("2020-01-01 08:00:00"), ends_at: Time.parse("2020-01-01 16:00:00")},
104-
{starts_at: Time.parse("2020-01-03 08:00:00"), ends_at: Time.parse("2020-01-03 16:00:00")}
103+
{starts_at: Time.parse("2025-01-01 08:00:00"), ends_at: Time.parse("2025-01-01 16:00:00")},
104+
{starts_at: Time.parse("2025-01-03 08:00:00"), ends_at: Time.parse("2025-01-03 16:00:00")}
105105
],
106106
max_hours: 20
107107
}
@@ -112,9 +112,9 @@ Specify shifts
112112

113113
```ruby
114114
shifts = [
115-
{starts_at: Time.parse("2020-01-01 08:00:00"), ends_at: Time.parse("2020-01-01 16:00:00")},
116-
{starts_at: Time.parse("2020-01-02 08:00:00"), ends_at: Time.parse("2020-01-02 16:00:00")},
117-
{starts_at: Time.parse("2020-01-03 08:00:00"), ends_at: Time.parse("2020-01-03 16:00:00")}
115+
{starts_at: Time.parse("2025-01-01 08:00:00"), ends_at: Time.parse("2025-01-01 16:00:00")},
116+
{starts_at: Time.parse("2025-01-02 08:00:00"), ends_at: Time.parse("2025-01-02 16:00:00")},
117+
{starts_at: Time.parse("2025-01-03 08:00:00"), ends_at: Time.parse("2025-01-03 16:00:00")}
118118
]
119119
```
120120

Rakefile

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,26 @@ require "rake/testtask"
33
require "rake/extensiontask"
44
require "ruby_memcheck"
55

6-
task default: :test
76
test_config = lambda do |t|
8-
t.libs << "test"
97
t.pattern = "test/**/*_test.rb"
108
end
11-
Rake::TestTask.new(:test, &test_config)
9+
Rake::TestTask.new(&test_config)
1210

1311
namespace :test do
1412
RubyMemcheck::TestTask.new(:valgrind, &test_config)
1513
end
1614

15+
task default: :test
16+
1717
Rake::ExtensionTask.new("or-tools") do |ext|
1818
ext.name = "ext"
1919
ext.lib_dir = "lib/or_tools"
2020
end
2121

2222
task :remove_ext do
23-
path = "lib/or_tools/ext.bundle"
24-
File.unlink(path) if File.exist?(path)
23+
Dir["lib/or_tools/ext.{bundle,so}"].each do |path|
24+
File.unlink(path)
25+
end
2526
end
2627

2728
Rake::Task["build"].enhance [:remove_ext]
@@ -31,8 +32,17 @@ task :update do
3132
require "open-uri"
3233
require "tmpdir"
3334

34-
version = "9.11.4210"
35-
distributions = ["arm64_macOS-14.6.1", "x86_64_macOS-14.6.1", "amd64_ubuntu-24.04", "amd64_ubuntu-22.04", "amd64_ubuntu-20.04", "amd64_debian-11", "amd64_debian-12", "amd64_archlinux"]
35+
version = "9.15.6755"
36+
distributions = [
37+
"arm64_macOS-26.2",
38+
"x86_64_macOS-26.2",
39+
"amd64_ubuntu-24.04",
40+
"amd64_ubuntu-22.04",
41+
"amd64_ubuntu-20.04",
42+
"amd64_debian-12",
43+
"amd64_debian-11",
44+
"amd64_archlinux"
45+
]
3646

3747
short_version = version.split(".").first(2).join(".")
3848
distributions.each do |dist|
@@ -48,3 +58,5 @@ task :update do
4858
puts "#{dist}: #{Digest::SHA256.file(dest).hexdigest}"
4959
end
5060
end
61+
62+
CLEAN.add("tmp/or-tools")

ext/or-tools/assignment.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include <ortools/graph/assignment.h>
2-
3-
#include "ext.h"
2+
#include <rice/rice.hpp>
3+
#include <rice/stl.hpp>
44

55
using operations_research::SimpleLinearSumAssignment;
66

ext/or-tools/bin_packing.cpp

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,44 @@
1-
#include <ortools/algorithms/knapsack_solver.h>
1+
#include <string>
2+
#include <vector>
23

3-
#include "ext.h"
4+
#include <ortools/algorithms/knapsack_solver.h>
5+
#include <rice/rice.hpp>
6+
#include <rice/stl.hpp>
47

58
using operations_research::KnapsackSolver;
69

710
using Rice::Array;
811
using Rice::Object;
912
using Rice::Symbol;
1013

11-
namespace Rice::detail
12-
{
14+
namespace Rice::detail {
1315
template<>
14-
struct Type<KnapsackSolver::SolverType>
15-
{
16-
static bool verify()
17-
{
18-
return true;
19-
}
16+
struct Type<KnapsackSolver::SolverType> {
17+
static bool verify() { return true; }
2018
};
2119

2220
template<>
23-
class From_Ruby<KnapsackSolver::SolverType>
24-
{
21+
class From_Ruby<KnapsackSolver::SolverType> {
2522
public:
26-
KnapsackSolver::SolverType convert(VALUE x)
27-
{
23+
From_Ruby() = default;
24+
25+
explicit From_Ruby(Arg* arg) : arg_(arg) { }
26+
27+
double is_convertible(VALUE value) { return Convertible::Exact; }
28+
29+
KnapsackSolver::SolverType convert(VALUE x) {
2830
auto s = Symbol(x).str();
2931
if (s == "branch_and_bound") {
3032
return KnapsackSolver::KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER;
3133
} else {
3234
throw std::runtime_error("Unknown solver type: " + s);
3335
}
3436
}
37+
38+
private:
39+
Arg* arg_ = nullptr;
3540
};
36-
}
41+
} // namespace Rice::detail
3742

3843
void init_bin_packing(Rice::Module& m) {
3944
Rice::define_class_under<KnapsackSolver>(m, "KnapsackSolver")

ext/or-tools/constraint.cpp

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1+
#include <string>
2+
#include <vector>
3+
14
#include <google/protobuf/text_format.h>
25
#include <ortools/sat/cp_model.h>
3-
4-
#include "ext.h"
6+
#include <rice/rice.hpp>
7+
#include <rice/stl.hpp>
58

69
using operations_research::Domain;
710
using operations_research::sat::BoolVar;
811
using operations_research::sat::Constraint;
12+
using operations_research::sat::TableConstraint;
913
using operations_research::sat::CpModelBuilder;
1014
using operations_research::sat::CpSolverResponse;
1115
using operations_research::sat::CpSolverStatus;
@@ -27,23 +31,22 @@ using Rice::Symbol;
2731
Class rb_cBoolVar;
2832
Class rb_cSatIntVar;
2933

30-
namespace Rice::detail
31-
{
34+
namespace Rice::detail {
3235
template<>
33-
struct Type<LinearExpr>
34-
{
35-
static bool verify()
36-
{
37-
return true;
38-
}
36+
struct Type<LinearExpr> {
37+
static bool verify() { return true; }
3938
};
4039

4140
template<>
42-
class From_Ruby<LinearExpr>
43-
{
41+
class From_Ruby<LinearExpr> {
4442
public:
45-
LinearExpr convert(VALUE v)
46-
{
43+
From_Ruby() = default;
44+
45+
explicit From_Ruby(Arg* arg) : arg_(arg) { }
46+
47+
double is_convertible(VALUE value) { return Convertible::Exact; }
48+
49+
LinearExpr convert(VALUE v) {
4750
LinearExpr expr;
4851

4952
Rice::Object utils = Rice::define_module("ORTools").const_get("Utils");
@@ -64,12 +67,16 @@ namespace Rice::detail
6467

6568
return expr;
6669
}
70+
71+
private:
72+
Arg* arg_ = nullptr;
6773
};
68-
}
74+
} // namespace Rice::detail
6975

7076
void init_constraint(Rice::Module& m) {
7177
Rice::define_class_under<Domain>(m, "Domain")
7278
.define_constructor(Rice::Constructor<Domain, int64_t, int64_t>())
79+
.define_singleton_function("from_values", &Domain::FromValues)
7380
.define_method("min", &Domain::Min)
7481
.define_method("max", &Domain::Max);
7582

@@ -104,6 +111,13 @@ void init_constraint(Rice::Module& m) {
104111
}
105112
});
106113

114+
Rice::define_class_under<TableConstraint, Constraint>(m, "SatTableConstraint")
115+
.define_method(
116+
"add_tuple",
117+
[](TableConstraint& self, std::vector<int64_t> tuple) {
118+
self.AddTuple(tuple);
119+
});
120+
107121
rb_cBoolVar = Rice::define_class_under<BoolVar>(m, "SatBoolVar")
108122
.define_method("name", &BoolVar::Name)
109123
.define_method("index", &BoolVar::index)
@@ -252,6 +266,16 @@ void init_constraint(Rice::Module& m) {
252266
[](CpModelBuilder& self, std::vector<IntVar> vars) {
253267
return self.AddAllDifferent(vars);
254268
})
269+
.define_method(
270+
"add_allowed_assignments",
271+
[](CpModelBuilder& self, std::vector<LinearExpr> expressions) {
272+
return self.AddAllowedAssignments(expressions);
273+
})
274+
.define_method(
275+
"add_forbidden_assignments",
276+
[](CpModelBuilder& self, std::vector<LinearExpr> expressions) {
277+
return self.AddForbiddenAssignments(expressions);
278+
})
255279
.define_method(
256280
"add_inverse_constraint",
257281
[](CpModelBuilder& self, std::vector<IntVar> variables, std::vector<IntVar> inverse_variables) {
@@ -392,7 +416,7 @@ void init_constraint(Rice::Module& m) {
392416
auto a = Array();
393417
auto assumptions = self.sufficient_assumptions_for_infeasibility();
394418
for (const auto& v : assumptions) {
395-
a.push(v);
419+
a.push(v, false);
396420
}
397421
return a;
398422
});

ext/or-tools/ext.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include <ortools/base/version.h>
22
#include <ortools/init/init.h>
3-
4-
#include "ext.h"
3+
#include <rice/rice.hpp>
4+
#include <rice/stl.hpp>
55

66
using operations_research::CppBridge;
77
using operations_research::CppFlags;
@@ -15,8 +15,7 @@ void init_network_flows(Rice::Module& m);
1515
void init_routing(Rice::Module& m);
1616

1717
extern "C"
18-
void Init_ext()
19-
{
18+
void Init_ext() {
2019
auto m = Rice::define_module("ORTools");
2120

2221
m.define_singleton_function("lib_version", &operations_research::OrToolsVersionString);

0 commit comments

Comments
 (0)