- Currently not implemented... Add abseil patch - Add patches/absl-config.cmake Makefile: Add abseil-cpp on unix - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake Makefile: Add abseil-cpp on windows - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake CMake: Add abseil-cpp - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake port to absl: C++ Part - Fix warning with the use of ABSL_MUST_USE_RESULT > The macro must appear as the very first part of a function declaration or definition: ... Note: past advice was to place the macro after the argument list. src: dependencies/sources/abseil-cpp-master/absl/base/attributes.h:418 - Rename enum after windows clash - Remove non compact table constraints - Change index type from int64 to int in routing library - Fix file_nonport compilation on windows - Fix another naming conflict with windows (NO_ERROR is a macro) - Cleanup hash containers; work on sat internals - Add optional_boolean sub-proto Sync cpp examples with internal code - reenable issue173 after reducing number of loops port to absl: Python Part - Add back cp_model.INT32_MIN|MAX for examples Update Python examples - Add random_tsp.py - Run words_square example - Run magic_square in python tests port to absl: Java Part - Fix compilation of the new routing parameters in java - Protect some code from SWIG parsing Update Java Examples port to absl: .Net Part Update .Net examples work on sat internals; Add C++ CP-SAT CpModelBuilder API; update sample code and recipes to use the new API; sync with internal code Remove VS 2015 in Appveyor-CI - abseil-cpp does not support VS 2015... improve tables upgrade C++ sat examples to use the new API; work on sat internals update license dates rewrite jobshop_ft06_distance.py to use the CP-SAT solver rename last example revert last commit more work on SAT internals fix
263 lines
8.7 KiB
C++
263 lines
8.7 KiB
C++
// Copyright 2010-2018 Google LLC
|
|
// 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 <cstddef>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "absl/container/flat_hash_map.h"
|
|
#include "absl/container/flat_hash_set.h"
|
|
#include "ortools/base/integral_types.h"
|
|
#include "ortools/base/logging.h"
|
|
#include "ortools/base/macros.h"
|
|
#include "ortools/base/map_util.h"
|
|
#include "ortools/base/stl_util.h"
|
|
#include "ortools/constraint_solver/constraint_solver.h"
|
|
#include "ortools/constraint_solver/constraint_solveri.h"
|
|
|
|
namespace operations_research {
|
|
// ---------- ArgumentHolder ----------
|
|
|
|
const std::string& ArgumentHolder::TypeName() const { return type_name_; }
|
|
|
|
void ArgumentHolder::SetTypeName(const std::string& type_name) {
|
|
type_name_ = type_name;
|
|
}
|
|
|
|
void ArgumentHolder::SetIntegerArgument(const std::string& arg_name,
|
|
int64 value) {
|
|
integer_argument_[arg_name] = value;
|
|
}
|
|
|
|
void ArgumentHolder::SetIntegerArrayArgument(const std::string& arg_name,
|
|
const std::vector<int64>& values) {
|
|
integer_array_argument_[arg_name] = values;
|
|
}
|
|
|
|
void ArgumentHolder::SetIntegerMatrixArgument(const std::string& arg_name,
|
|
const IntTupleSet& values) {
|
|
std::pair<std::string, IntTupleSet> to_insert =
|
|
std::make_pair(arg_name, values);
|
|
matrix_argument_.insert(to_insert);
|
|
}
|
|
|
|
void ArgumentHolder::SetIntegerExpressionArgument(const std::string& arg_name,
|
|
IntExpr* const expr) {
|
|
integer_expression_argument_[arg_name] = expr;
|
|
}
|
|
|
|
void ArgumentHolder::SetIntegerVariableArrayArgument(
|
|
const std::string& arg_name, const std::vector<IntVar*>& vars) {
|
|
integer_variable_array_argument_[arg_name] = vars;
|
|
}
|
|
|
|
void ArgumentHolder::SetIntervalArgument(const std::string& arg_name,
|
|
IntervalVar* const var) {
|
|
interval_argument_[arg_name] = var;
|
|
}
|
|
|
|
void ArgumentHolder::SetIntervalArrayArgument(
|
|
const std::string& arg_name, const std::vector<IntervalVar*>& vars) {
|
|
interval_array_argument_[arg_name] = vars;
|
|
}
|
|
|
|
void ArgumentHolder::SetSequenceArgument(const std::string& arg_name,
|
|
SequenceVar* const var) {
|
|
sequence_argument_[arg_name] = var;
|
|
}
|
|
|
|
void ArgumentHolder::SetSequenceArrayArgument(
|
|
const std::string& arg_name, const std::vector<SequenceVar*>& vars) {
|
|
sequence_array_argument_[arg_name] = vars;
|
|
}
|
|
|
|
bool ArgumentHolder::HasIntegerExpressionArgument(
|
|
const std::string& arg_name) const {
|
|
return gtl::ContainsKey(integer_expression_argument_, arg_name);
|
|
}
|
|
|
|
bool ArgumentHolder::HasIntegerVariableArrayArgument(
|
|
const std::string& arg_name) const {
|
|
return gtl::ContainsKey(integer_variable_array_argument_, arg_name);
|
|
}
|
|
|
|
int64 ArgumentHolder::FindIntegerArgumentWithDefault(
|
|
const std::string& arg_name, int64 def) const {
|
|
return gtl::FindWithDefault(integer_argument_, arg_name, def);
|
|
}
|
|
|
|
int64 ArgumentHolder::FindIntegerArgumentOrDie(
|
|
const std::string& arg_name) const {
|
|
return gtl::FindOrDie(integer_argument_, arg_name);
|
|
}
|
|
|
|
const std::vector<int64>& ArgumentHolder::FindIntegerArrayArgumentOrDie(
|
|
const std::string& arg_name) const {
|
|
return gtl::FindOrDie(integer_array_argument_, arg_name);
|
|
}
|
|
|
|
IntExpr* ArgumentHolder::FindIntegerExpressionArgumentOrDie(
|
|
const std::string& arg_name) const {
|
|
return gtl::FindOrDie(integer_expression_argument_, arg_name);
|
|
}
|
|
|
|
const std::vector<IntVar*>&
|
|
ArgumentHolder::FindIntegerVariableArrayArgumentOrDie(
|
|
const std::string& arg_name) const {
|
|
return gtl::FindOrDie(integer_variable_array_argument_, arg_name);
|
|
}
|
|
|
|
const IntTupleSet& ArgumentHolder::FindIntegerMatrixArgumentOrDie(
|
|
const std::string& arg_name) const {
|
|
return gtl::FindOrDie(matrix_argument_, arg_name);
|
|
}
|
|
|
|
// ---------- ModelParser ---------
|
|
|
|
ModelParser::ModelParser() {}
|
|
|
|
ModelParser::~ModelParser() { CHECK(holders_.empty()); }
|
|
|
|
void ModelParser::BeginVisitModel(const std::string& solver_name) {
|
|
PushArgumentHolder();
|
|
}
|
|
|
|
void ModelParser::EndVisitModel(const std::string& solver_name) {
|
|
PopArgumentHolder();
|
|
}
|
|
|
|
void ModelParser::BeginVisitConstraint(const std::string& type_name,
|
|
const Constraint* const constraint) {
|
|
PushArgumentHolder();
|
|
}
|
|
|
|
void ModelParser::EndVisitConstraint(const std::string& type_name,
|
|
const Constraint* const constraint) {
|
|
// Constraint parsing is usually done here.
|
|
PopArgumentHolder();
|
|
}
|
|
|
|
void ModelParser::BeginVisitIntegerExpression(const std::string& type_name,
|
|
const IntExpr* const expr) {
|
|
PushArgumentHolder();
|
|
}
|
|
|
|
void ModelParser::EndVisitIntegerExpression(const std::string& type_name,
|
|
const IntExpr* const expr) {
|
|
// Expression parsing is usually done here.
|
|
PopArgumentHolder();
|
|
}
|
|
|
|
void ModelParser::VisitIntegerVariable(const IntVar* const variable,
|
|
IntExpr* const delegate) {
|
|
// Usual place for parsing.
|
|
}
|
|
|
|
void ModelParser::VisitIntegerVariable(const IntVar* const variable,
|
|
const std::string& operation,
|
|
int64 value, IntVar* const delegate) {
|
|
delegate->Accept(this);
|
|
// Usual place for parsing.
|
|
}
|
|
|
|
void ModelParser::VisitIntervalVariable(const IntervalVar* const variable,
|
|
const std::string& operation,
|
|
int64 value,
|
|
IntervalVar* const delegate) {
|
|
if (delegate != nullptr) {
|
|
delegate->Accept(this);
|
|
}
|
|
// Usual place for parsing.
|
|
}
|
|
|
|
void ModelParser::VisitSequenceVariable(const SequenceVar* const variable) {
|
|
// Usual place for parsing.
|
|
}
|
|
|
|
// Integer arguments
|
|
void ModelParser::VisitIntegerArgument(const std::string& arg_name,
|
|
int64 value) {
|
|
Top()->SetIntegerArgument(arg_name, value);
|
|
}
|
|
|
|
void ModelParser::VisitIntegerArrayArgument(const std::string& arg_name,
|
|
const std::vector<int64>& values) {
|
|
Top()->SetIntegerArrayArgument(arg_name, values);
|
|
}
|
|
|
|
void ModelParser::VisitIntegerMatrixArgument(const std::string& arg_name,
|
|
const IntTupleSet& values) {
|
|
Top()->SetIntegerMatrixArgument(arg_name, values);
|
|
}
|
|
|
|
// Variables.
|
|
void ModelParser::VisitIntegerExpressionArgument(const std::string& arg_name,
|
|
IntExpr* const argument) {
|
|
Top()->SetIntegerExpressionArgument(arg_name, argument);
|
|
argument->Accept(this);
|
|
}
|
|
|
|
void ModelParser::VisitIntegerVariableArrayArgument(
|
|
const std::string& arg_name, const std::vector<IntVar*>& arguments) {
|
|
Top()->SetIntegerVariableArrayArgument(arg_name, arguments);
|
|
for (int i = 0; i < arguments.size(); ++i) {
|
|
arguments[i]->Accept(this);
|
|
}
|
|
}
|
|
|
|
// Visit interval argument.
|
|
void ModelParser::VisitIntervalArgument(const std::string& arg_name,
|
|
IntervalVar* const argument) {
|
|
Top()->SetIntervalArgument(arg_name, argument);
|
|
argument->Accept(this);
|
|
}
|
|
|
|
void ModelParser::VisitIntervalArrayArgument(
|
|
const std::string& arg_name, const std::vector<IntervalVar*>& arguments) {
|
|
Top()->SetIntervalArrayArgument(arg_name, arguments);
|
|
for (int i = 0; i < arguments.size(); ++i) {
|
|
arguments[i]->Accept(this);
|
|
}
|
|
}
|
|
|
|
// Visit sequence argument.
|
|
void ModelParser::VisitSequenceArgument(const std::string& arg_name,
|
|
SequenceVar* const argument) {
|
|
Top()->SetSequenceArgument(arg_name, argument);
|
|
argument->Accept(this);
|
|
}
|
|
|
|
void ModelParser::VisitSequenceArrayArgument(
|
|
const std::string& arg_name, const std::vector<SequenceVar*>& arguments) {
|
|
Top()->SetSequenceArrayArgument(arg_name, arguments);
|
|
for (int i = 0; i < arguments.size(); ++i) {
|
|
arguments[i]->Accept(this);
|
|
}
|
|
}
|
|
|
|
void ModelParser::PushArgumentHolder() {
|
|
holders_.push_back(new ArgumentHolder);
|
|
}
|
|
|
|
void ModelParser::PopArgumentHolder() {
|
|
CHECK(!holders_.empty());
|
|
delete holders_.back();
|
|
holders_.pop_back();
|
|
}
|
|
|
|
ArgumentHolder* ModelParser::Top() const {
|
|
CHECK(!holders_.empty());
|
|
return holders_.back();
|
|
}
|
|
} // namespace operations_research
|