or-tools 0.3.3 → 0.3.4
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 +5 -0
- data/NOTICE.txt +1 -1
- data/README.md +35 -1
- data/ext/or-tools/ext.cpp +41 -5
- data/lib/or_tools/cp_solver.rb +7 -3
- data/lib/or_tools/version.rb +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dba74899e2a57b086643657e5093f12e67fd4fcdda7e22c2b533911f9991e43a
|
|
4
|
+
data.tar.gz: 963c0b75f55b4b772ead3a8402ec8bb4b90570c23de1c7dc3a437758e8949af2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a5dc8662ec580c97a905817867346615e2fbb187d5b75d6b2b839a86e7385a20b2ed4f9f4c13ed536079c6141cdd0bf95bfad7ea6408d4eb81d8f0ed09e32a68
|
|
7
|
+
data.tar.gz: 195967d1e662ba05751ff31fbec3c96ebac519cd58a343ca551f9ba6c12304542b7f4127a37f88e99cda6b214d42089df7ed9b5a3134c0ec1eb978ea72a95be4
|
data/CHANGELOG.md
CHANGED
data/NOTICE.txt
CHANGED
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
|
-
[](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
|
|
data/ext/or-tools/ext.cpp
CHANGED
|
@@ -638,18 +638,24 @@ void Init_ext()
|
|
|
638
638
|
self.Minimize(expr);
|
|
639
639
|
});
|
|
640
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
|
+
|
|
641
648
|
define_class_under(rb_mORTools, "CpSolver")
|
|
642
649
|
.define_method(
|
|
643
650
|
"_solve_with_observer",
|
|
644
|
-
*[](Object self, CpModelBuilder& model, Object callback, bool all_solutions) {
|
|
651
|
+
*[](Object self, CpModelBuilder& model, SatParameters& parameters, Object callback, bool all_solutions) {
|
|
645
652
|
operations_research::sat::Model m;
|
|
646
653
|
|
|
647
654
|
if (all_solutions) {
|
|
648
655
|
// set parameters for SearchForAllSolutions
|
|
649
|
-
SatParameters parameters;
|
|
650
656
|
parameters.set_enumerate_all_solutions(true);
|
|
651
|
-
m.Add(NewSatParameters(parameters));
|
|
652
657
|
}
|
|
658
|
+
m.Add(NewSatParameters(parameters));
|
|
653
659
|
|
|
654
660
|
m.Add(NewFeasibleSolutionObserver(
|
|
655
661
|
[callback](const CpSolverResponse& r) {
|
|
@@ -662,8 +668,10 @@ void Init_ext()
|
|
|
662
668
|
})
|
|
663
669
|
.define_method(
|
|
664
670
|
"_solve",
|
|
665
|
-
*[](Object self, CpModelBuilder& model) {
|
|
666
|
-
|
|
671
|
+
*[](Object self, CpModelBuilder& model, SatParameters& parameters) {
|
|
672
|
+
operations_research::sat::Model m;
|
|
673
|
+
m.Add(NewSatParameters(parameters));
|
|
674
|
+
return SolveCpModel(model.Build(), &m);
|
|
667
675
|
})
|
|
668
676
|
.define_method(
|
|
669
677
|
"_solution_integer_value",
|
|
@@ -701,6 +709,8 @@ void Init_ext()
|
|
|
701
709
|
return Symbol("infeasible");
|
|
702
710
|
} else if (status == CpSolverStatus::MODEL_INVALID) {
|
|
703
711
|
return Symbol("model_invalid");
|
|
712
|
+
} else if (status == CpSolverStatus::UNKNOWN) {
|
|
713
|
+
return Symbol("unknown");
|
|
704
714
|
} else {
|
|
705
715
|
throw std::runtime_error("Unknown solver status");
|
|
706
716
|
}
|
|
@@ -806,6 +816,23 @@ void Init_ext()
|
|
|
806
816
|
})
|
|
807
817
|
.define_method("depot", &RoutingModel::GetDepot)
|
|
808
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
|
+
})
|
|
809
836
|
.define_method("vehicle_var", &RoutingModel::VehicleVar)
|
|
810
837
|
.define_method("set_arc_cost_evaluator_of_all_vehicles", &RoutingModel::SetArcCostEvaluatorOfAllVehicles)
|
|
811
838
|
.define_method("set_arc_cost_evaluator_of_vehicle", &RoutingModel::SetArcCostEvaluatorOfVehicle)
|
|
@@ -822,6 +849,15 @@ void Init_ext()
|
|
|
822
849
|
}
|
|
823
850
|
self.AddDimensionWithVehicleCapacity(evaluator_index, slack_max, vehicle_capacities, fix_start_cumul_to_zero, name);
|
|
824
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
|
+
})
|
|
825
861
|
.define_method(
|
|
826
862
|
"add_disjunction",
|
|
827
863
|
*[](RoutingModel& self, Array rb_indices, int64 penalty) {
|
data/lib/or_tools/cp_solver.rb
CHANGED
|
@@ -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
|
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.3.
|
|
4
|
+
version: 0.3.4
|
|
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:
|
|
11
|
+
date: 2021-01-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rice
|
|
@@ -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:
|
|
@@ -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
|
|
@@ -133,8 +133,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
133
133
|
- !ruby/object:Gem::Version
|
|
134
134
|
version: '0'
|
|
135
135
|
requirements: []
|
|
136
|
-
rubygems_version: 3.
|
|
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: []
|