test new GCC
This commit is contained in:
98
examples/tests/gcc_test.cc
Normal file
98
examples/tests/gcc_test.cc
Normal file
@@ -0,0 +1,98 @@
|
||||
// Copyright 2011-2012 Google
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "base/hash.h"
|
||||
#include "base/map-util.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/random.h"
|
||||
#include "constraint_solver/constraint_solveri.h"
|
||||
#include "constraint_solver/constraint_solver.h"
|
||||
|
||||
DEFINE_int32(vsize, 5, "Number of variables");
|
||||
DEFINE_int32(csize, 5, "Number of variables");
|
||||
DEFINE_int32(slack, 4, "Slack in cardinalities");
|
||||
DEFINE_int32(seed, 1, "Random seed");
|
||||
|
||||
namespace operations_research {
|
||||
extern Constraint* Gcc(Solver* const solver,
|
||||
const std::vector<IntVar*>& vars,
|
||||
int64 first_domain_value,
|
||||
const std::vector<int>& min_occurrences,
|
||||
const std::vector<int>& max_occurrences);
|
||||
|
||||
int64 TestGcc(int vsize, int csize, int slack, int seed, bool use_gcc) {
|
||||
if (vsize > csize + slack) {
|
||||
LOG(INFO) << "Cannot create problem";
|
||||
return 0;
|
||||
}
|
||||
ACMRandom rgen(seed); // defines a random generator
|
||||
|
||||
std::vector<int> card_min(csize, 0);
|
||||
std::vector<int> card_max(csize, 0);
|
||||
for (int i = 0; i< vsize - slack; ++i) {
|
||||
const int index = rgen.Uniform(csize);
|
||||
card_min[index]++;
|
||||
card_max[index]++;
|
||||
}
|
||||
for (int i = 0; i < slack; ++i) {
|
||||
const int index = rgen.Uniform(csize);
|
||||
card_max[index]++;
|
||||
}
|
||||
|
||||
LOG(INFO) << (use_gcc ? "Gcc constraint:" : "Distribute constraint:");
|
||||
LOG(INFO) << " - num variables = " << vsize;
|
||||
LOG(INFO) << " - num values = " << csize;
|
||||
LOG(INFO) << " - slack = " << slack;
|
||||
LOG(INFO) << " - seed = " << seed;
|
||||
Solver solver("TestGcc");
|
||||
std::vector<IntVar*> vars;
|
||||
solver.MakeIntVarArray(vsize, 0, csize - 1, &vars);
|
||||
Constraint* const gcc = use_gcc ?
|
||||
Gcc(&solver, vars, 0, card_min, card_max) :
|
||||
solver.MakeDistribute(vars, card_min, card_max);
|
||||
solver.AddConstraint(gcc);
|
||||
DecisionBuilder* const db = solver.MakePhase(vars,
|
||||
Solver::CHOOSE_FIRST_UNBOUND,
|
||||
Solver::ASSIGN_MIN_VALUE);
|
||||
|
||||
LOG(INFO) << "Start search";
|
||||
CycleTimer t;
|
||||
t.Start();
|
||||
solver.NewSearch(db);
|
||||
int counter = 0;
|
||||
while(solver.NextSolution()) {
|
||||
counter++;
|
||||
}
|
||||
solver.EndSearch();
|
||||
t.Stop();
|
||||
|
||||
LOG(INFO) << "test time : " << t.GetInUsec() << " micro seconds";
|
||||
LOG(INFO) << "Found " << counter << " solutions";
|
||||
return counter;
|
||||
}
|
||||
} // namespace operations_research
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
google::ParseCommandLineFlags(&argc, &argv, true);
|
||||
CHECK_EQ(operations_research::TestGcc(FLAGS_vsize,
|
||||
FLAGS_csize,
|
||||
FLAGS_slack,
|
||||
FLAGS_seed,
|
||||
false),
|
||||
operations_research::TestGcc(FLAGS_vsize,
|
||||
FLAGS_csize,
|
||||
FLAGS_slack,
|
||||
FLAGS_seed,
|
||||
true));
|
||||
return 0;
|
||||
}
|
||||
@@ -650,6 +650,12 @@ $(OBJ_DIR)/bucket_table_test.$O:$(EX_DIR)/tests/bucket_table_test.cc $(SRC_DIR)/
|
||||
$(BIN_DIR)/bucket_table_test$E: $(CP_DEPS) $(OBJ_DIR)/bucket_table_test.$O
|
||||
$(CCC) $(CFLAGS) $(OBJ_DIR)/bucket_table_test.$O $(CP_LNK) $(LDFLAGS) $(EXEOUT)bucket_table_test$E
|
||||
|
||||
$(OBJ_DIR)/gcc_test.$O:$(EX_DIR)/tests/gcc_test.cc $(SRC_DIR)/constraint_solver/constraint_solver.h
|
||||
$(CCC) $(CFLAGS) -c $(EX_DIR)$Stests/gcc_test.cc $(OBJ_OUT)gcc_test.$O
|
||||
|
||||
$(BIN_DIR)/gcc_test$E: $(CP_DEPS) $(OBJ_DIR)/gcc_test.$O
|
||||
$(CCC) $(CFLAGS) $(OBJ_DIR)/gcc_test.$O $(CP_LNK) $(LDFLAGS) $(EXEOUT)gcc_test$E
|
||||
|
||||
# Linear Programming Examples
|
||||
|
||||
$(OBJ_DIR)/strawberry_fields_with_column_generation.$O: $(EX_DIR)/cpp/strawberry_fields_with_column_generation.cc $(SRC_DIR)/linear_solver/linear_solver.h
|
||||
|
||||
@@ -66,13 +66,42 @@ class GccConstraint : public Constraint {
|
||||
// Two elements before and after the element list will be added
|
||||
// with a weight of 1.
|
||||
PartialSum(int64 offset,
|
||||
int count,
|
||||
int64 count,
|
||||
const std::vector<int64>& elements) :
|
||||
offset_(offset - 3),
|
||||
last_value_(offset + count + 1),
|
||||
sum_(count + 5),
|
||||
ds_(count + 5) {
|
||||
int i, j;
|
||||
int64 i, j;
|
||||
sum_[0] = 0;
|
||||
sum_[1] = 1;
|
||||
sum_[2] = 2;
|
||||
for (i = 2; i < count + 2; i++) {
|
||||
sum_[i + 1] = sum_[i] + elements[i - 2];
|
||||
}
|
||||
sum_[i + 1] = sum_[i] + 1;
|
||||
sum_[i + 2] = sum_[i + 1] + 1;
|
||||
|
||||
i = count + 3;
|
||||
j = i;
|
||||
while (i > 0) {
|
||||
while (sum_[i] == sum_[i-1]) {
|
||||
ds_[i--] = j;
|
||||
}
|
||||
ds_[j] = i--;
|
||||
j = ds_[j];
|
||||
}
|
||||
ds_[j] = 0;
|
||||
}
|
||||
|
||||
PartialSum(int64 offset,
|
||||
int64 count,
|
||||
const std::vector<int>& elements) :
|
||||
offset_(offset - 3),
|
||||
last_value_(offset + count + 1),
|
||||
sum_(count + 5),
|
||||
ds_(count + 5) {
|
||||
int64 i, j;
|
||||
sum_[0] = 0;
|
||||
sum_[1] = 1;
|
||||
sum_[2] = 2;
|
||||
@@ -191,6 +220,57 @@ class GccConstraint : public Constraint {
|
||||
}
|
||||
}
|
||||
|
||||
GccConstraint(Solver* const solver,
|
||||
const std::vector<IntVar*>& vars,
|
||||
bool propagate_value,
|
||||
int64 first_domain_value,
|
||||
int64 last_domain_value,
|
||||
const std::vector<int>& min_occurrences,
|
||||
const std::vector<int>& max_occurrences)
|
||||
: Constraint(solver),
|
||||
variables_(vars),
|
||||
size_(vars.size()),
|
||||
current_level_(1),
|
||||
last_level_(0),
|
||||
propagate_value_(propagate_value),
|
||||
max_occurrences_(last_domain_value - first_domain_value + 1, 0),
|
||||
tree_(2 * size_ + 2),
|
||||
diffs_(2 * size_ + 2),
|
||||
hall_(2 * size_ + 2),
|
||||
stable_intervals_(2 * size_ + 2),
|
||||
potential_stable_sets_(2 * size_ + 2),
|
||||
new_min_(size_),
|
||||
intervals_(size_),
|
||||
sorted_by_min_(size_),
|
||||
sorted_by_max_(size_),
|
||||
bounds_(2 * size_ + 2),
|
||||
active_size_(0),
|
||||
lower_sum_(first_domain_value,
|
||||
last_domain_value - first_domain_value + 1,
|
||||
min_occurrences),
|
||||
upper_sum_(first_domain_value,
|
||||
last_domain_value - first_domain_value + 1,
|
||||
max_occurrences) {
|
||||
int64 i, range;
|
||||
|
||||
range = last_domain_value - first_domain_value + 1;
|
||||
|
||||
last_level_ = -1;
|
||||
|
||||
if (propagate_value_) {
|
||||
for(i = 0; i < range; i++) {
|
||||
max_occurrences_.SetValue(solver,
|
||||
i,
|
||||
max_occurrences[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for(Index i(0); i < size_; i++) {
|
||||
sorted_by_min_[i.value()] = &intervals_[i];
|
||||
sorted_by_max_[i.value()] = &intervals_[i];
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~GccConstraint() {}
|
||||
|
||||
void Post() {
|
||||
@@ -706,5 +786,36 @@ Constraint* NewGCC(Solver* const solver,
|
||||
min_occurrences,
|
||||
max_occurrences));
|
||||
}
|
||||
} // namespace operations_research
|
||||
|
||||
Constraint* Gcc(Solver* const solver,
|
||||
const std::vector<IntVar*>& vars,
|
||||
int64 first_domain_value,
|
||||
const std::vector<int64>& min_occurrences,
|
||||
const std::vector<int64>& max_occurrences) {
|
||||
return solver->RevAlloc(
|
||||
new GccConstraint(
|
||||
solver,
|
||||
vars,
|
||||
true,
|
||||
first_domain_value,
|
||||
first_domain_value + min_occurrences.size(),
|
||||
min_occurrences,
|
||||
max_occurrences));
|
||||
}
|
||||
|
||||
Constraint* Gcc(Solver* const solver,
|
||||
const std::vector<IntVar*>& vars,
|
||||
int64 first_domain_value,
|
||||
const std::vector<int>& min_occurrences,
|
||||
const std::vector<int>& max_occurrences) {
|
||||
return solver->RevAlloc(
|
||||
new GccConstraint(
|
||||
solver,
|
||||
vars,
|
||||
true,
|
||||
first_domain_value,
|
||||
first_domain_value + min_occurrences.size(),
|
||||
min_occurrences,
|
||||
max_occurrences));
|
||||
}
|
||||
} // namespace operations_research
|
||||
|
||||
Reference in New Issue
Block a user