1 // Copyright 2011-2012 Google
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 #include "ortools/constraint_solver/constraint_solver.h"
15 
16 namespace operations_research {
17 
18 class ForbiddenIntervalTestSimpleReductionOnBothSide : public DecisionBuilder {
19  public:
ForbiddenIntervalTestSimpleReductionOnBothSide(IntVar * const var)20   ForbiddenIntervalTestSimpleReductionOnBothSide(IntVar* const var)
21       : var_(var) {}
~ForbiddenIntervalTestSimpleReductionOnBothSide()22   ~ForbiddenIntervalTestSimpleReductionOnBothSide() override {}
23 
Next(Solver * const s)24   Decision* Next(Solver* const s) override {
25     CHECK_EQ(101, var_->Min());
26     CHECK_EQ(899, var_->Max());
27     return NULL;
28   }
29 
30  private:
31   IntVar* const var_;
32 };
33 
34 class ForbiddenIntervalTestMultipleReductionsOnMin : public DecisionBuilder {
35  public:
ForbiddenIntervalTestMultipleReductionsOnMin(IntVar * const var)36   ForbiddenIntervalTestMultipleReductionsOnMin(IntVar* const var) : var_(var) {}
~ForbiddenIntervalTestMultipleReductionsOnMin()37   ~ForbiddenIntervalTestMultipleReductionsOnMin() override {}
38 
Next(Solver * const s)39   Decision* Next(Solver* const s) override {
40     CHECK_EQ(0, var_->Min());
41     CHECK_EQ(1000, var_->Max());
42     var_->SetMin(5);
43     CHECK_EQ(5, var_->Min());
44     CHECK_EQ(1000, var_->Max());
45     var_->SetMax(995);
46     CHECK_EQ(5, var_->Min());
47     CHECK_EQ(995, var_->Max());
48     var_->SetMin(10);
49     CHECK_EQ(21, var_->Min());
50     CHECK_EQ(995, var_->Max());
51     var_->SetMin(30);
52     CHECK_EQ(30, var_->Min());
53     CHECK_EQ(995, var_->Max());
54     var_->SetMin(505);
55     CHECK_EQ(511, var_->Min());
56     CHECK_EQ(995, var_->Max());
57     var_->SetMin(600);
58     CHECK_EQ(600, var_->Min());
59     CHECK_EQ(995, var_->Max());
60     var_->SetMin(900);
61     CHECK_EQ(901, var_->Min());
62     CHECK_EQ(995, var_->Max());
63     return NULL;
64   }
65 
66  private:
67   IntVar* const var_;
68 };
69 
70 class ForbiddenIntervalTestMultipleReductionsOnMax : public DecisionBuilder {
71  public:
ForbiddenIntervalTestMultipleReductionsOnMax(IntVar * const var)72   ForbiddenIntervalTestMultipleReductionsOnMax(IntVar* const var) : var_(var) {}
~ForbiddenIntervalTestMultipleReductionsOnMax()73   ~ForbiddenIntervalTestMultipleReductionsOnMax() override {}
74 
Next(Solver * const s)75   Decision* Next(Solver* const s) override {
76     CHECK_EQ(0, var_->Min());
77     CHECK_EQ(1000, var_->Max());
78     var_->SetMin(5);
79     CHECK_EQ(5, var_->Min());
80     CHECK_EQ(1000, var_->Max());
81     var_->SetMax(995);
82     CHECK_EQ(5, var_->Min());
83     CHECK_EQ(995, var_->Max());
84     var_->SetMax(900);
85     CHECK_EQ(5, var_->Min());
86     CHECK_EQ(799, var_->Max());
87     var_->SetMax(750);
88     CHECK_EQ(5, var_->Min());
89     CHECK_EQ(750, var_->Max());
90     var_->SetMax(505);
91     CHECK_EQ(5, var_->Min());
92     CHECK_EQ(499, var_->Max());
93     var_->SetMax(300);
94     CHECK_EQ(5, var_->Min());
95     CHECK_EQ(300, var_->Max());
96     var_->SetMax(20);
97     CHECK_EQ(5, var_->Min());
98     CHECK_EQ(9, var_->Max());
99     return NULL;
100   }
101 
102  private:
103   IntVar* const var_;
104 };
105 
106 class ForbiddenIntervalTest {
107  public:
SetUp(std::vector<int64_t> & starts,std::vector<int64_t> & ends)108   void SetUp(std::vector<int64_t>& starts, std::vector<int64_t>& ends) {
109     solver_.reset(new Solver("ForbiddenIntervalTest"));
110     var_ = solver_->MakeIntVar(0, 1000, "var");
111     CHECK_EQ(starts.size(), ends.size());
112     for (std::size_t i = 0; i < starts.size(); ++i) {
113       var_->RemoveInterval(starts[i], ends[i]);
114     }
115   }
116 
117   std::unique_ptr<Solver> solver_;
118   IntVar* var_;
119 
TestSimpleReductionOnBothSide()120   void TestSimpleReductionOnBothSide() {
121     std::cout << "TestSimpleReductionOnBothSide" << std::endl;
122     std::vector<int64_t> starts = {0, 900};
123     std::vector<int64_t> ends = {100, 1000};
124     SetUp(starts, ends);
125     CHECK(solver_->Solve(solver_->RevAlloc(
126         new ForbiddenIntervalTestSimpleReductionOnBothSide(var_))));
127     std::cout << "  .. done" << std::endl;
128   }
129 
TestMultipleReductionsOnMin()130   void TestMultipleReductionsOnMin() {
131     std::cout << "TestMultipleReductionsOnMin" << std::endl;
132     std::vector<int64_t> starts = {10, 500, 800};
133     std::vector<int64_t> ends = {20, 510, 900};
134     SetUp(starts, ends);
135     CHECK(solver_->Solve(solver_->RevAlloc(
136         new ForbiddenIntervalTestMultipleReductionsOnMin(var_))));
137     std::cout << "  .. done" << std::endl;
138   }
139 
TestMultipleReductionsOnMax()140   void TestMultipleReductionsOnMax() {
141     std::cout << "TestMultipleReductionsOnMax" << std::endl;
142     std::vector<int64_t> starts = {10, 500, 800};
143     std::vector<int64_t> ends = {20, 510, 900};
144     SetUp(starts, ends);
145     CHECK(solver_->Solve(solver_->RevAlloc(
146         new ForbiddenIntervalTestMultipleReductionsOnMax(var_))));
147     std::cout << "  .. done" << std::endl;
148   }
149 };
150 }  // namespace operations_research
151 
main(int argc,char ** argv)152 int main(int argc, char** argv) {
153   absl::ParseCommandLine(argc, argv);
154   operations_research::ForbiddenIntervalTest forbidden_intervals_test;
155   forbidden_intervals_test.TestSimpleReductionOnBothSide();
156   forbidden_intervals_test.TestMultipleReductionsOnMin();
157   forbidden_intervals_test.TestMultipleReductionsOnMax();
158   return 0;
159 }
160