test new GCC

This commit is contained in:
lperron@google.com
2012-05-10 14:24:50 +00:00
parent b201199021
commit 7669beb5b6
3 changed files with 218 additions and 3 deletions

View 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;
}

View File

@@ -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

View File

@@ -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