sync most c++ examples
This commit is contained in:
@@ -13,6 +13,7 @@ include(GNUInstallDirs)
|
||||
foreach(EXECUTABLE IN ITEMS
|
||||
constraint_programming_cp
|
||||
costas_array_sat
|
||||
cryptarithm_sat
|
||||
cvrp_disjoint_tw
|
||||
cvrptw
|
||||
cvrptw_with_breaks
|
||||
@@ -29,6 +30,7 @@ foreach(EXECUTABLE IN ITEMS
|
||||
linear_assignment_api
|
||||
linear_programming
|
||||
linear_solver_protocol_buffers
|
||||
magic_sequence_sat
|
||||
magic_square_sat
|
||||
max_flow
|
||||
min_cost_flow
|
||||
|
||||
@@ -21,16 +21,18 @@
|
||||
// This example contains two separate implementations. CostasHard()
|
||||
// uses hard constraints, whereas CostasSoft() uses a minimizer to
|
||||
// minimize the number of duplicates.
|
||||
|
||||
#include <ctime>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/flags/flag.h"
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "ortools/base/integral_types.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/base/random.h"
|
||||
#include "ortools/sat/cp_model.h"
|
||||
#include "ortools/sat/model.h"
|
||||
|
||||
@@ -102,11 +104,13 @@ void CostasHard(const int dim) {
|
||||
// Check that the pairwise difference is unique
|
||||
for (int i = 1; i < dim; ++i) {
|
||||
std::vector<IntVar> subset;
|
||||
Domain diff(-dim, dim);
|
||||
Domain difference_domain(-dim, dim);
|
||||
|
||||
for (int j = 0; j < dim - i; ++j) {
|
||||
subset.push_back(cp_model.NewIntVar(diff));
|
||||
cp_model.AddEquality(LinearExpr::Sum({subset[j], vars[j]}), vars[j + i]);
|
||||
IntVar diff = cp_model.NewIntVar(difference_domain);
|
||||
subset.push_back(diff);
|
||||
cp_model.AddEquality(
|
||||
diff, LinearExpr::ScalProd({vars[j + i], vars[j]}, {1, -1}));
|
||||
}
|
||||
|
||||
cp_model.AddAllDifferent(subset);
|
||||
@@ -118,7 +122,7 @@ void CostasHard(const int dim) {
|
||||
}
|
||||
const CpSolverResponse response = SolveCpModel(cp_model.Build(), &model);
|
||||
|
||||
if (response.status() == CpSolverStatus::FEASIBLE) {
|
||||
if (response.status() == CpSolverStatus::OPTIMAL) {
|
||||
std::vector<int64> costas_matrix;
|
||||
std::string output;
|
||||
|
||||
@@ -142,8 +146,8 @@ void CostasBool(const int dim) {
|
||||
CpModelBuilder cp_model;
|
||||
|
||||
// create the variables
|
||||
std::vector<std::vector<BoolVar> > vars(dim);
|
||||
std::vector<std::vector<BoolVar> > transposed_vars(dim);
|
||||
std::vector<std::vector<BoolVar>> vars(dim);
|
||||
std::vector<std::vector<BoolVar>> transposed_vars(dim);
|
||||
for (int i = 0; i < dim; ++i) {
|
||||
for (int j = 0; j < dim; ++j) {
|
||||
const BoolVar var = cp_model.NewBoolVar();
|
||||
@@ -213,8 +217,8 @@ void CostasBoolSoft(const int dim) {
|
||||
CpModelBuilder cp_model;
|
||||
|
||||
// create the variables
|
||||
std::vector<std::vector<BoolVar> > vars(dim);
|
||||
std::vector<std::vector<BoolVar> > transposed_vars(dim);
|
||||
std::vector<std::vector<BoolVar>> vars(dim);
|
||||
std::vector<std::vector<BoolVar>> transposed_vars(dim);
|
||||
for (int i = 0; i < dim; ++i) {
|
||||
for (int j = 0; j < dim; ++j) {
|
||||
const BoolVar var = cp_model.NewBoolVar();
|
||||
@@ -294,7 +298,10 @@ void CostasBoolSoft(const int dim) {
|
||||
} // namespace operations_research
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
absl::SetFlag(&FLAGS_logtostderr, true);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
|
||||
int min = 1;
|
||||
int max = 10;
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "examples/cpp/course_scheduling.h"
|
||||
#include "examples/cpp/course_scheduling.pb.h"
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
|
||||
87
examples/cpp/cryptarithm_sat.cc
Normal file
87
examples/cpp/cryptarithm_sat.cc
Normal file
@@ -0,0 +1,87 @@
|
||||
// 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.
|
||||
|
||||
// Use CP-SAT to solve a simple cryptarithmetic problem: SEND+MORE=MONEY.
|
||||
|
||||
#include "ortools/sat/cp_model.h"
|
||||
|
||||
namespace operations_research {
|
||||
namespace sat {
|
||||
|
||||
void SendMoreMoney() {
|
||||
CpModelBuilder cp_model;
|
||||
|
||||
// Possible domains for variables.
|
||||
Domain all_digits(0, 9);
|
||||
Domain non_zero_digits(1, 9);
|
||||
// Create variables.
|
||||
// Since s is a leading digit, it can't be 0.
|
||||
const IntVar s = cp_model.NewIntVar(non_zero_digits);
|
||||
const IntVar e = cp_model.NewIntVar(all_digits);
|
||||
const IntVar n = cp_model.NewIntVar(all_digits);
|
||||
const IntVar d = cp_model.NewIntVar(all_digits);
|
||||
// Since m is a leading digit, it can't be 0.
|
||||
const IntVar m = cp_model.NewIntVar(non_zero_digits);
|
||||
const IntVar o = cp_model.NewIntVar(all_digits);
|
||||
const IntVar r = cp_model.NewIntVar(all_digits);
|
||||
const IntVar y = cp_model.NewIntVar(all_digits);
|
||||
|
||||
// Create carry variables. c0 is true if the first column of addends carries
|
||||
// a 1, c2 is true if the second column carries a 1, and so on.
|
||||
const BoolVar c0 = cp_model.NewBoolVar();
|
||||
const BoolVar c1 = cp_model.NewBoolVar();
|
||||
const BoolVar c2 = cp_model.NewBoolVar();
|
||||
const BoolVar c3 = cp_model.NewBoolVar();
|
||||
|
||||
// Force all letters to take on different values.
|
||||
cp_model.AddAllDifferent({s, e, n, d, m, o, r, y});
|
||||
|
||||
// Column 0: Force c0 == m.
|
||||
cp_model.AddEquality(c0, m);
|
||||
|
||||
// Column 1: Force c1 + s + m + o == 10*c0.
|
||||
cp_model.AddEquality(LinearExpr::Sum({c1, s, m, o}),
|
||||
LinearExpr::ScalProd({c0}, {10}));
|
||||
|
||||
// Column 2: Force c2 + e + o == n + 10*c1.
|
||||
cp_model.AddEquality(LinearExpr::Sum({c2, e, o}),
|
||||
LinearExpr::ScalProd({n, c1}, {1, 10}));
|
||||
|
||||
// Column 3: Force c3 + n + r == e + 10*c2.
|
||||
cp_model.AddEquality(LinearExpr::Sum({c3, n, r}),
|
||||
LinearExpr::ScalProd({e, c2}, {1, 10}));
|
||||
|
||||
// Column 4: Force d + e == y + 10*c3.
|
||||
cp_model.AddEquality(LinearExpr::Sum({d, e}),
|
||||
LinearExpr::ScalProd({y, c3}, {1, 10}));
|
||||
|
||||
// Declare the model, solve it, and display the results.
|
||||
const CpSolverResponse response = Solve(cp_model.Build());
|
||||
LOG(INFO) << CpSolverResponseStats(response);
|
||||
LOG(INFO) << "s: " << SolutionIntegerValue(response, s);
|
||||
LOG(INFO) << "e: " << SolutionIntegerValue(response, e);
|
||||
LOG(INFO) << "n: " << SolutionIntegerValue(response, n);
|
||||
LOG(INFO) << "d: " << SolutionIntegerValue(response, d);
|
||||
LOG(INFO) << "m: " << SolutionIntegerValue(response, m);
|
||||
LOG(INFO) << "o: " << SolutionIntegerValue(response, o);
|
||||
LOG(INFO) << "r: " << SolutionIntegerValue(response, r);
|
||||
LOG(INFO) << "y: " << SolutionIntegerValue(response, y);
|
||||
}
|
||||
|
||||
} // namespace sat
|
||||
} // namespace operations_research
|
||||
|
||||
int main() {
|
||||
operations_research::sat::SendMoreMoney();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/random/random.h"
|
||||
#include "examples/cpp/cvrptw_lib.h"
|
||||
#include "google/protobuf/text_format.h"
|
||||
@@ -66,6 +68,7 @@ const int64 kMaxNodesPerGroup = 10;
|
||||
const int64 kSameVehicleCost = 1000;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
CHECK_LT(0, absl::GetFlag(FLAGS_vrp_orders))
|
||||
<< "Specify an instance size greater than 0.";
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/random/random.h"
|
||||
#include "examples/cpp/cvrptw_lib.h"
|
||||
#include "google/protobuf/text_format.h"
|
||||
@@ -63,6 +65,7 @@ const int64 kMaxNodesPerGroup = 10;
|
||||
const int64 kSameVehicleCost = 1000;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
CHECK_LT(0, absl::GetFlag(FLAGS_vrp_orders))
|
||||
<< "Specify an instance size greater than 0.";
|
||||
|
||||
@@ -27,20 +27,21 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/random/random.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "examples/cpp/cvrptw_lib.h"
|
||||
#include "google/protobuf/text_format.h"
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "ortools/base/integral_types.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/base/random.h"
|
||||
#include "ortools/constraint_solver/routing.h"
|
||||
#include "ortools/constraint_solver/routing_enums.pb.h"
|
||||
#include "ortools/constraint_solver/routing_index_manager.h"
|
||||
#include "ortools/constraint_solver/routing_parameters.h"
|
||||
#include "ortools/constraint_solver/routing_parameters.pb.h"
|
||||
|
||||
using operations_research::ACMRandom;
|
||||
using operations_research::Assignment;
|
||||
using operations_research::DefaultRoutingSearchParameters;
|
||||
using operations_research::FirstSolutionStrategy;
|
||||
@@ -69,6 +70,7 @@ const char* kTime = "Time";
|
||||
const char* kCapacity = "Capacity";
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
CHECK_LT(0, absl::GetFlag(FLAGS_vrp_orders))
|
||||
<< "Specify an instance size greater than 0.";
|
||||
@@ -76,8 +78,7 @@ int main(int argc, char** argv) {
|
||||
<< "Specify a non-null vehicle fleet size.";
|
||||
// VRP of size absl::GetFlag(FLAGS_vrp_size).
|
||||
// Nodes are indexed from 0 to absl::GetFlag(FLAGS_vrp_orders), the starts and
|
||||
// ends of
|
||||
// the routes are at node 0.
|
||||
// ends of the routes are at node 0.
|
||||
const RoutingIndexManager::NodeIndex kDepot(0);
|
||||
RoutingIndexManager manager(absl::GetFlag(FLAGS_vrp_orders) + 1,
|
||||
absl::GetFlag(FLAGS_vrp_vehicles), kDepot);
|
||||
@@ -117,8 +118,8 @@ int main(int argc, char** argv) {
|
||||
routing.RegisterTransitCallback([&demand, &manager](int64 i, int64 j) {
|
||||
return demand.Demand(manager.IndexToNode(i), manager.IndexToNode(j));
|
||||
}),
|
||||
kNullCapacitySlack, kVehicleCapacity, /*fix_start_cumul_to_zero=*/true,
|
||||
kCapacity);
|
||||
kNullCapacitySlack, kVehicleCapacity,
|
||||
/*fix_start_cumul_to_zero=*/true, kCapacity);
|
||||
|
||||
// Adding time dimension constraints.
|
||||
const int64 kTimePerDemandUnit = 300;
|
||||
@@ -139,11 +140,12 @@ int main(int argc, char** argv) {
|
||||
RoutingDimension* const time_dimension = routing.GetMutableDimension(kTime);
|
||||
|
||||
// Adding time windows.
|
||||
ACMRandom randomizer(
|
||||
std::mt19937 randomizer(
|
||||
GetSeed(absl::GetFlag(FLAGS_vrp_use_deterministic_random_seed)));
|
||||
const int64 kTWDuration = 5 * 3600;
|
||||
for (int order = 1; order < manager.num_nodes(); ++order) {
|
||||
const int64 start = randomizer.Uniform(kHorizon - kTWDuration);
|
||||
const int64 start =
|
||||
absl::Uniform<int32_t>(randomizer, 0, kHorizon - kTWDuration);
|
||||
time_dimension->CumulVar(order)->SetRange(start, start + kTWDuration);
|
||||
routing.AddToAssignment(time_dimension->SlackVar(order));
|
||||
}
|
||||
@@ -173,7 +175,7 @@ int main(int argc, char** argv) {
|
||||
service_times[node] = kTimePerDemandUnit * demand.Demand(index, index);
|
||||
}
|
||||
}
|
||||
const std::vector<std::vector<int> > break_data = {
|
||||
const std::vector<std::vector<int>> break_data = {
|
||||
{/*start_min*/ 11, /*start_max*/ 13, /*duration*/ 2400},
|
||||
{/*start_min*/ 10, /*start_max*/ 15, /*duration*/ 1800},
|
||||
{/*start_min*/ 10, /*start_max*/ 15, /*duration*/ 1800}};
|
||||
|
||||
@@ -21,18 +21,19 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/random/random.h"
|
||||
#include "examples/cpp/cvrptw_lib.h"
|
||||
#include "google/protobuf/text_format.h"
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "ortools/base/integral_types.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/base/random.h"
|
||||
#include "ortools/constraint_solver/routing.h"
|
||||
#include "ortools/constraint_solver/routing_index_manager.h"
|
||||
#include "ortools/constraint_solver/routing_parameters.h"
|
||||
#include "ortools/constraint_solver/routing_parameters.pb.h"
|
||||
|
||||
using operations_research::ACMRandom;
|
||||
using operations_research::Assignment;
|
||||
using operations_research::DefaultRoutingSearchParameters;
|
||||
using operations_research::GetSeed;
|
||||
@@ -65,6 +66,7 @@ bool IsRefuelNode(int64 node) {
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
CHECK_LT(0, absl::GetFlag(FLAGS_vrp_orders))
|
||||
<< "Specify an instance size greater than 0.";
|
||||
@@ -72,8 +74,7 @@ int main(int argc, char** argv) {
|
||||
<< "Specify a non-null vehicle fleet size.";
|
||||
// VRP of size absl::GetFlag(FLAGS_vrp_size).
|
||||
// Nodes are indexed from 0 to absl::GetFlag(FLAGS_vrp_orders), the starts and
|
||||
// ends of
|
||||
// the routes are at node 0.
|
||||
// ends of the routes are at node 0.
|
||||
const RoutingIndexManager::NodeIndex kDepot(0);
|
||||
RoutingIndexManager manager(absl::GetFlag(FLAGS_vrp_orders) + 1,
|
||||
absl::GetFlag(FLAGS_vrp_vehicles), kDepot);
|
||||
@@ -108,8 +109,8 @@ int main(int argc, char** argv) {
|
||||
routing.RegisterTransitCallback([&demand, &manager](int64 i, int64 j) {
|
||||
return demand.Demand(manager.IndexToNode(i), manager.IndexToNode(j));
|
||||
}),
|
||||
kNullCapacitySlack, kVehicleCapacity, /*fix_start_cumul_to_zero=*/true,
|
||||
kCapacity);
|
||||
kNullCapacitySlack, kVehicleCapacity,
|
||||
/*fix_start_cumul_to_zero=*/true, kCapacity);
|
||||
|
||||
// Adding time dimension constraints.
|
||||
const int64 kTimePerDemandUnit = 300;
|
||||
@@ -129,12 +130,17 @@ int main(int argc, char** argv) {
|
||||
kHorizon, kHorizon, /*fix_start_cumul_to_zero=*/true, kTime);
|
||||
const RoutingDimension& time_dimension = routing.GetDimensionOrDie(kTime);
|
||||
// Adding time windows.
|
||||
ACMRandom randomizer(
|
||||
GetSeed(absl::GetFlag(FLAGS_vrp_use_deterministic_random_seed)));
|
||||
// NOTE(user): This randomized test case is quite sensible to the seed:
|
||||
// the generated model can be much easier or harder to solve, depending on
|
||||
// the seed. It turns out that most seeds yield pretty slow/bad solver
|
||||
// performance: I got good performance for about 10% of the seeds.
|
||||
std::mt19937 randomizer(
|
||||
144 + GetSeed(absl::GetFlag(FLAGS_vrp_use_deterministic_random_seed)));
|
||||
const int64 kTWDuration = 5 * 3600;
|
||||
for (int order = 1; order < manager.num_nodes(); ++order) {
|
||||
if (!IsRefuelNode(order)) {
|
||||
const int64 start = randomizer.Uniform(kHorizon - kTWDuration);
|
||||
const int64 start =
|
||||
absl::Uniform<int32_t>(randomizer, 0, kHorizon - kTWDuration);
|
||||
time_dimension.CumulVar(order)->SetRange(start, start + kTWDuration);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,18 +23,19 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/random/random.h"
|
||||
#include "examples/cpp/cvrptw_lib.h"
|
||||
#include "google/protobuf/text_format.h"
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "ortools/base/integral_types.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/base/random.h"
|
||||
#include "ortools/constraint_solver/routing.h"
|
||||
#include "ortools/constraint_solver/routing_index_manager.h"
|
||||
#include "ortools/constraint_solver/routing_parameters.h"
|
||||
#include "ortools/constraint_solver/routing_parameters.pb.h"
|
||||
|
||||
using operations_research::ACMRandom;
|
||||
using operations_research::Assignment;
|
||||
using operations_research::DefaultRoutingSearchParameters;
|
||||
using operations_research::GetSeed;
|
||||
@@ -63,6 +64,7 @@ const char* kTime = "Time";
|
||||
const char* kCapacity = "Capacity";
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
CHECK_LT(0, absl::GetFlag(FLAGS_vrp_orders))
|
||||
<< "Specify an instance size greater than 0.";
|
||||
@@ -70,8 +72,7 @@ int main(int argc, char** argv) {
|
||||
<< "Specify a non-null vehicle fleet size.";
|
||||
// VRP of size absl::GetFlag(FLAGS_vrp_size).
|
||||
// Nodes are indexed from 0 to absl::GetFlag(FLAGS_vrp_orders), the starts and
|
||||
// ends of
|
||||
// the routes are at node 0.
|
||||
// ends of the routes are at node 0.
|
||||
const RoutingIndexManager::NodeIndex kDepot(0);
|
||||
RoutingIndexManager manager(absl::GetFlag(FLAGS_vrp_orders) + 1,
|
||||
absl::GetFlag(FLAGS_vrp_vehicles), kDepot);
|
||||
@@ -106,8 +107,8 @@ int main(int argc, char** argv) {
|
||||
routing.RegisterTransitCallback([&demand, &manager](int64 i, int64 j) {
|
||||
return demand.Demand(manager.IndexToNode(i), manager.IndexToNode(j));
|
||||
}),
|
||||
kNullCapacitySlack, kVehicleCapacity, /*fix_start_cumul_to_zero=*/true,
|
||||
kCapacity);
|
||||
kNullCapacitySlack, kVehicleCapacity,
|
||||
/*fix_start_cumul_to_zero=*/true, kCapacity);
|
||||
|
||||
// Adding time dimension constraints.
|
||||
const int64 kTimePerDemandUnit = 300;
|
||||
@@ -128,11 +129,12 @@ int main(int argc, char** argv) {
|
||||
const RoutingDimension& time_dimension = routing.GetDimensionOrDie(kTime);
|
||||
|
||||
// Adding time windows.
|
||||
ACMRandom randomizer(
|
||||
std::mt19937 randomizer(
|
||||
GetSeed(absl::GetFlag(FLAGS_vrp_use_deterministic_random_seed)));
|
||||
const int64 kTWDuration = 5 * 3600;
|
||||
for (int order = 1; order < manager.num_nodes(); ++order) {
|
||||
const int64 start = randomizer.Uniform(kHorizon - kTWDuration);
|
||||
const int64 start =
|
||||
absl::Uniform<int32_t>(randomizer, 0, kHorizon - kTWDuration);
|
||||
time_dimension.CumulVar(order)->SetRange(start, start + kTWDuration);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,19 +21,20 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/random/random.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "examples/cpp/cvrptw_lib.h"
|
||||
#include "google/protobuf/text_format.h"
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "ortools/base/integral_types.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/base/random.h"
|
||||
#include "ortools/constraint_solver/routing.h"
|
||||
#include "ortools/constraint_solver/routing_index_manager.h"
|
||||
#include "ortools/constraint_solver/routing_parameters.h"
|
||||
#include "ortools/constraint_solver/routing_parameters.pb.h"
|
||||
|
||||
using operations_research::ACMRandom;
|
||||
using operations_research::Assignment;
|
||||
using operations_research::DefaultRoutingSearchParameters;
|
||||
using operations_research::GetSeed;
|
||||
@@ -63,6 +64,7 @@ const char* kTime = "Time";
|
||||
const char* kCapacity = "Capacity";
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
CHECK_LT(0, absl::GetFlag(FLAGS_vrp_stops))
|
||||
<< "Specify an instance size greater than 0.";
|
||||
@@ -109,8 +111,8 @@ int main(int argc, char** argv) {
|
||||
routing.RegisterTransitCallback([&demand, &manager](int64 i, int64 j) {
|
||||
return demand.Demand(manager.IndexToNode(i), manager.IndexToNode(j));
|
||||
}),
|
||||
kNullCapacitySlack, kVehicleCapacity, /*fix_start_cumul_to_zero=*/true,
|
||||
kCapacity);
|
||||
kNullCapacitySlack, kVehicleCapacity,
|
||||
/*fix_start_cumul_to_zero=*/true, kCapacity);
|
||||
|
||||
// Adding time dimension constraints.
|
||||
const int64 kStopTime = 300;
|
||||
@@ -128,11 +130,12 @@ int main(int argc, char** argv) {
|
||||
const RoutingDimension& time_dimension = routing.GetDimensionOrDie(kTime);
|
||||
|
||||
// Adding time windows, for the sake of simplicty same for each stop.
|
||||
ACMRandom randomizer(
|
||||
std::mt19937 randomizer(
|
||||
GetSeed(absl::GetFlag(FLAGS_vrp_use_deterministic_random_seed)));
|
||||
const int64 kTWDuration = 5 * 3600;
|
||||
for (int stop = 0; stop < absl::GetFlag(FLAGS_vrp_stops); ++stop) {
|
||||
const int64 start = randomizer.Uniform(kHorizon - kTWDuration);
|
||||
const int64 start =
|
||||
absl::Uniform<int32_t>(randomizer, 0, kHorizon - kTWDuration);
|
||||
for (int stop_order = 0;
|
||||
stop_order < absl::GetFlag(FLAGS_vrp_orders_per_stop); ++stop_order) {
|
||||
const int order =
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "examples/cpp/parse_dimacs_assignment.h"
|
||||
#include "examples/cpp/print_dimacs_assignment.h"
|
||||
@@ -186,7 +188,7 @@ int main(int argc, char* argv[]) {
|
||||
} else {
|
||||
usage = absl::StrFormat(kUsageTemplate, argv[0]);
|
||||
}
|
||||
absl::SetProgramUsageMessage(usage);
|
||||
google::InitGoogleLogging(usage.c_str());
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
|
||||
if (argc < 2) {
|
||||
|
||||
@@ -30,8 +30,11 @@
|
||||
// search operators and local search filters.
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/random/random.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
@@ -722,21 +725,20 @@ void SolveDobble(int num_cards, int num_symbols, int num_symbols_per_card) {
|
||||
filters.push_back(solver.RevAlloc(new DobbleFilter(
|
||||
all_card_symbol_vars, num_cards, num_symbols, num_symbols_per_card)));
|
||||
}
|
||||
|
||||
LocalSearchFilterManager* ls_manager =
|
||||
solver.RevAlloc(new LocalSearchFilterManager(std::move(filters)));
|
||||
// Main decision builder that regroups the first solution decision
|
||||
// builder and the combination of local search operators and
|
||||
// filters.
|
||||
LocalSearchFilterManager* filter_manager =
|
||||
solver.RevAlloc(new LocalSearchFilterManager(filters));
|
||||
DecisionBuilder* const final_db = solver.MakeLocalSearchPhase(
|
||||
all_card_symbol_vars, build_db,
|
||||
solver.MakeLocalSearchPhaseParameters(
|
||||
objective_var, solver.ConcatenateOperators(operators, true),
|
||||
nullptr, // Sub decision builder, not needed here.
|
||||
nullptr, // Limit the search for improving move, we will stop
|
||||
// the exploration of the local search at the first
|
||||
// improving solution (first accept).
|
||||
filter_manager));
|
||||
// the exploration of the local search at the first
|
||||
// improving solution (first accept).
|
||||
ls_manager));
|
||||
|
||||
std::vector<SearchMonitor*> monitors;
|
||||
// Optimize var search monitor.
|
||||
@@ -748,8 +750,8 @@ void SolveDobble(int num_cards, int num_symbols, int num_symbols_per_card) {
|
||||
monitors.push_back(log);
|
||||
|
||||
// Search limit.
|
||||
SearchLimit* const time_limit = solver.MakeLimit(
|
||||
absl::GetFlag(FLAGS_time_limit_in_ms), kint64max, kint64max, kint64max);
|
||||
SearchLimit* const time_limit = solver.MakeTimeLimit(
|
||||
absl::Milliseconds(absl::GetFlag(FLAGS_time_limit_in_ms)));
|
||||
monitors.push_back(time_limit);
|
||||
|
||||
// And solve!
|
||||
@@ -758,6 +760,7 @@ void SolveDobble(int num_cards, int num_symbols, int num_symbols_per_card) {
|
||||
} // namespace operations_research
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
// These constants comes directly from the dobble game.
|
||||
// There are actually 55 cards, but we can create up to 57 cards.
|
||||
|
||||
@@ -11,7 +11,10 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include <cstdlib>
|
||||
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/graph/ebert_graph.h"
|
||||
#include "ortools/graph/max_flow.h"
|
||||
@@ -81,6 +84,7 @@ void MaxFeasibleFlow() {
|
||||
} // namespace operations_research
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
operations_research::MinCostFlowOn4x4Matrix();
|
||||
operations_research::MaxFeasibleFlow();
|
||||
|
||||
@@ -51,6 +51,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "examples/cpp/fap_model_printer.h"
|
||||
#include "examples/cpp/fap_parser.h"
|
||||
#include "examples/cpp/fap_utilities.h"
|
||||
@@ -331,7 +333,7 @@ bool ConstraintImpactComparator(FapConstraint constraint1,
|
||||
}
|
||||
|
||||
int64 ValueEvaluator(
|
||||
absl::flat_hash_map<int64, std::pair<int64, int64> >* value_evaluator_map,
|
||||
absl::flat_hash_map<int64, std::pair<int64, int64>>* value_evaluator_map,
|
||||
int64 variable_index, int64 value) {
|
||||
CHECK(value_evaluator_map != nullptr);
|
||||
// Evaluate the choice. Smaller ranking denotes a better choice.
|
||||
@@ -344,7 +346,7 @@ int64 ValueEvaluator(
|
||||
}
|
||||
|
||||
// Update the history of assigned values and their rankings of each variable.
|
||||
absl::flat_hash_map<int64, std::pair<int64, int64> >::iterator it;
|
||||
absl::flat_hash_map<int64, std::pair<int64, int64>>::iterator it;
|
||||
int64 new_value = value;
|
||||
int64 new_ranking = ranking;
|
||||
if ((it = value_evaluator_map->find(variable_index)) !=
|
||||
@@ -489,8 +491,8 @@ void CreateAdditionalMonitors(OptimizeVar* const objective, Solver* solver,
|
||||
if (absl::GetFlag(FLAGS_time_limit_in_ms) != 0) {
|
||||
LOG(INFO) << "Adding time limit of "
|
||||
<< absl::GetFlag(FLAGS_time_limit_in_ms) << " ms.";
|
||||
SearchLimit* const limit = solver->MakeLimit(
|
||||
absl::GetFlag(FLAGS_time_limit_in_ms), kint64max, kint64max, kint64max);
|
||||
SearchLimit* const limit = solver->MakeTimeLimit(
|
||||
absl::Milliseconds(absl::GetFlag(FLAGS_time_limit_in_ms)));
|
||||
monitors->push_back(limit);
|
||||
}
|
||||
|
||||
@@ -581,7 +583,7 @@ void HardFapSolver(const std::map<int, FapVariable>& data_variables,
|
||||
ChooseVariableStrategy(&variable_strategy);
|
||||
// Choose the value selection strategy.
|
||||
DecisionBuilder* db;
|
||||
absl::flat_hash_map<int64, std::pair<int64, int64> > history;
|
||||
absl::flat_hash_map<int64, std::pair<int64, int64>> history;
|
||||
if (absl::GetFlag(FLAGS_value_evaluator) == "value_evaluator") {
|
||||
LOG(INFO) << "Using ValueEvaluator for value selection strategy.";
|
||||
Solver::IndexEvaluator2 index_evaluator2 = [&history](int64 var,
|
||||
@@ -856,6 +858,7 @@ void SolveProblem(const std::map<int, FapVariable>& variables,
|
||||
} // namespace operations_research
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
|
||||
CHECK(!absl::GetFlag(FLAGS_directory).empty())
|
||||
|
||||
@@ -26,8 +26,11 @@
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "absl/flags/flag.h"
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "google/protobuf/text_format.h"
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "ortools/base/integral_types.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/sat/cp_model.h"
|
||||
@@ -97,8 +100,8 @@ void GolombRuler(int size) {
|
||||
if (response.status() == CpSolverStatus::OPTIMAL) {
|
||||
const int64 result = SolutionIntegerValue(response, ticks.back());
|
||||
const int64 num_failures = response.num_conflicts();
|
||||
printf("N = %d, optimal length = %lld (conflicts:%lld, time=%f s)\n", size,
|
||||
result, num_failures, response.wall_time());
|
||||
absl::PrintF("N = %d, optimal length = %d (conflicts:%d, time=%f s)\n",
|
||||
size, result, num_failures, response.wall_time());
|
||||
if (size - 1 < kKnownSolutions) {
|
||||
CHECK_EQ(result, kBestSolutions[size - 1]);
|
||||
}
|
||||
@@ -116,7 +119,10 @@ void GolombRuler(int size) {
|
||||
} // namespace operations_research
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
absl::SetFlag(&FLAGS_logtostderr, true);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
|
||||
if (absl::GetFlag(FLAGS_size) != 0) {
|
||||
operations_research::sat::GolombRuler(absl::GetFlag(FLAGS_size));
|
||||
} else {
|
||||
|
||||
@@ -13,12 +13,15 @@
|
||||
|
||||
// Integer programming example that shows how to use the API.
|
||||
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/strings/match.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/linear_solver/linear_solver.h"
|
||||
|
||||
namespace operations_research {
|
||||
void RunIntegerProgrammingExample(const std::string& solver_id) {
|
||||
void RunIntegerProgrammingExample(absl::string_view solver_id) {
|
||||
LOG(INFO) << "---- Integer programming example with " << solver_id << " ----";
|
||||
|
||||
MPSolver::OptimizationProblemType problem_type;
|
||||
@@ -87,9 +90,7 @@ void RunAllExamples() {
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::SetFlag(&FLAGS_logtostderr, true);
|
||||
absl::SetFlag(&FLAGS_log_prefix, false);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
operations_research::RunAllExamples();
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
#include <vector>
|
||||
|
||||
#include "absl/flags/flag.h"
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/strings/match.h"
|
||||
#include "absl/strings/str_join.h"
|
||||
#include "google/protobuf/text_format.h"
|
||||
#include "google/protobuf/wrappers.pb.h"
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/base/timer.h"
|
||||
#include "ortools/data/jobshop_scheduling.pb.h"
|
||||
@@ -747,7 +748,9 @@ void Solve(const JsspInputProblem& problem) {
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
absl::SetFlag(&FLAGS_logtostderr, true);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
|
||||
if (absl::GetFlag(FLAGS_input).empty()) {
|
||||
LOG(FATAL) << "Please supply a data file with --input=";
|
||||
}
|
||||
|
||||
@@ -11,7 +11,10 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include <cstdlib>
|
||||
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/graph/ebert_graph.h"
|
||||
#include "ortools/graph/linear_assignment.h"
|
||||
@@ -46,7 +49,7 @@ void AssignmentOn4x4Matrix() {
|
||||
|
||||
void AnotherAssignment() {
|
||||
LOG(INFO) << "Another assignment on 4x4 matrix";
|
||||
std::vector<std::vector<int> > matrice(
|
||||
std::vector<std::vector<int>> matrice(
|
||||
{{8, 7, 9, 9}, {5, 2, 7, 8}, {6, 1, 4, 9}, {2, 3, 2, 6}});
|
||||
const int kSize = matrice.size();
|
||||
ForwardStarGraph graph(2 * kSize, kSize * kSize);
|
||||
@@ -66,6 +69,7 @@ void AnotherAssignment() {
|
||||
} // namespace operations_research
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
operations_research::AssignmentOn4x4Matrix();
|
||||
operations_research::AnotherAssignment();
|
||||
|
||||
@@ -13,13 +13,20 @@
|
||||
|
||||
// Linear programming example that shows how to use the API.
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include "absl/flags/flag.h"
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/strings/match.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/linear_solver/linear_solver.h"
|
||||
#include "ortools/linear_solver/linear_solver.pb.h"
|
||||
|
||||
namespace operations_research {
|
||||
void RunLinearProgrammingExample(const std::string& solver_id) {
|
||||
void RunLinearProgrammingExample(absl::string_view solver_id) {
|
||||
LOG(INFO) << "---- Linear programming example with " << solver_id << " ----";
|
||||
MPSolver::OptimizationProblemType problem_type;
|
||||
if (!MPSolver::ParseSolverType(solver_id, &problem_type)) {
|
||||
@@ -112,9 +119,8 @@ void RunAllExamples() {
|
||||
} // namespace operations_research
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
absl::SetFlag(&FLAGS_alsologtostderr, true);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::SetFlag(&FLAGS_logtostderr, true);
|
||||
absl::SetFlag(&FLAGS_log_prefix, false);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
operations_research::RunAllExamples();
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/linear_solver/linear_solver.h"
|
||||
#include "ortools/linear_solver/linear_solver.pb.h"
|
||||
@@ -99,6 +100,7 @@ void RunAllExamples() {
|
||||
} // namespace operations_research
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
operations_research::RunAllExamples();
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
98
examples/cpp/magic_sequence_sat.cc
Normal file
98
examples/cpp/magic_sequence_sat.cc
Normal file
@@ -0,0 +1,98 @@
|
||||
// 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.
|
||||
|
||||
// Magic sequence problem
|
||||
//
|
||||
// Compute a sequence of numbers such that the number of occurrences of i
|
||||
// in the sequence is equal to the value of the ith number.
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "absl/flags/flag.h"
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "ortools/base/integral_types.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/sat/cp_model.h"
|
||||
|
||||
ABSL_FLAG(int, size, 50, "Size of the problem.");
|
||||
ABSL_FLAG(std::string, params, "log_search_progress:true,num_search_workers:8",
|
||||
"Sat parameters.");
|
||||
|
||||
namespace operations_research {
|
||||
namespace sat {
|
||||
|
||||
void MagicSequence(int size) {
|
||||
CHECK_GE(size, 1);
|
||||
CpModelBuilder cp_model;
|
||||
|
||||
std::vector<std::vector<BoolVar>> var_domains(size);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
for (int j = 0; j < size; ++j) {
|
||||
var_domains[i].push_back(cp_model.NewBoolVar());
|
||||
}
|
||||
}
|
||||
|
||||
// Domain constraint on each position.
|
||||
for (int i = 0; i < size; ++i) {
|
||||
cp_model.AddEquality(LinearExpr::BooleanSum(var_domains[i]), 1);
|
||||
}
|
||||
|
||||
// The number of variables equal to j shall be the value of vars[j].
|
||||
std::vector<int64> values(size);
|
||||
std::iota(values.begin(), values.end(), 0); // [0, 1, 2, .., size - 1]
|
||||
std::vector<BoolVar> vars_equal_to_j;
|
||||
|
||||
for (int j = 0; j < size; ++j) {
|
||||
vars_equal_to_j.clear();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
vars_equal_to_j.push_back(var_domains[i][j]);
|
||||
}
|
||||
cp_model.AddEquality(LinearExpr::BooleanScalProd(var_domains[j], values),
|
||||
LinearExpr::BooleanSum(vars_equal_to_j));
|
||||
}
|
||||
|
||||
const CpSolverResponse response =
|
||||
SolveWithParameters(cp_model.Build(), absl::GetFlag(FLAGS_params));
|
||||
|
||||
if (response.status() == CpSolverStatus::OPTIMAL ||
|
||||
response.status() == CpSolverStatus::FEASIBLE) {
|
||||
std::string output = "[";
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (i != 0) {
|
||||
output.append(", ");
|
||||
}
|
||||
for (int j = 0; j < size; ++j) {
|
||||
if (SolutionBooleanValue(response, var_domains[i][j])) {
|
||||
absl::StrAppendFormat(&output, "%d", j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
output.append("]");
|
||||
LOG(INFO) << "Solution = " << output;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sat
|
||||
} // namespace operations_research
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
absl::SetFlag(&FLAGS_logtostderr, true);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
|
||||
operations_research::sat::MagicSequence(absl::GetFlag(FLAGS_size));
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -14,13 +14,18 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/flags/flag.h"
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "ortools/base/integral_types.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/sat/cp_model.h"
|
||||
#include "ortools/sat/model.h"
|
||||
|
||||
ABSL_FLAG(int, size, 7, "Size of the magic square");
|
||||
ABSL_FLAG(std::string, params, "", "Sat paramters");
|
||||
ABSL_FLAG(std::string, params, "", "Sat parameters");
|
||||
|
||||
namespace operations_research {
|
||||
namespace sat {
|
||||
@@ -94,7 +99,9 @@ void MagicSquare(int size) {
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
absl::SetFlag(&FLAGS_logtostderr, true);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
|
||||
operations_research::sat::MagicSquare(absl::GetFlag(FLAGS_size));
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/strings/match.h"
|
||||
#include "google/protobuf/descriptor.h"
|
||||
@@ -74,8 +76,8 @@ void ReadGlopParameters(GlopParameters* parameters) {
|
||||
<< absl::GetFlag(FLAGS_params);
|
||||
}
|
||||
if (absl::GetFlag(FLAGS_mps_verbose_result)) {
|
||||
printf("GlopParameters {\n%s}\n",
|
||||
FullProtocolMessageAsString(*parameters, 1).c_str());
|
||||
absl::PrintF("GlopParameters {\n%s}\n",
|
||||
FullProtocolMessageAsString(*parameters, 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +108,7 @@ int main(int argc, char* argv[]) {
|
||||
MPModelProtoToLinearProgram(model_proto, &linear_program);
|
||||
}
|
||||
if (absl::GetFlag(FLAGS_mps_dump_problem)) {
|
||||
printf("%s", linear_program.Dump().c_str());
|
||||
absl::PrintF("%s", linear_program.Dump());
|
||||
}
|
||||
|
||||
// Create the solver with the correct parameters.
|
||||
@@ -126,29 +128,29 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
if (absl::GetFlag(FLAGS_mps_terse_result)) {
|
||||
if (absl::GetFlag(FLAGS_mps_display_full_path)) {
|
||||
printf("%s,", file_name.c_str());
|
||||
absl::PrintF("%s,", file_name);
|
||||
}
|
||||
printf("%s,", linear_program.name().c_str());
|
||||
absl::PrintF("%s,", linear_program.name());
|
||||
if (absl::GetFlag(FLAGS_mps_solve)) {
|
||||
printf("%15.15e,%s,%-6.4g,", objective_value, status_string.c_str(),
|
||||
solving_time_in_sec);
|
||||
absl::PrintF("%15.15e,%s,%-6.4g,", objective_value, status_string,
|
||||
solving_time_in_sec);
|
||||
}
|
||||
printf("%s,%s\n", linear_program.GetProblemStats().c_str(),
|
||||
linear_program.GetNonZeroStats().c_str());
|
||||
absl::PrintF("%s,%s\n", linear_program.GetProblemStats(),
|
||||
linear_program.GetNonZeroStats());
|
||||
}
|
||||
|
||||
if (absl::GetFlag(FLAGS_mps_verbose_result)) {
|
||||
if (absl::GetFlag(FLAGS_mps_display_full_path)) {
|
||||
printf("%-45s: %s\n", "File path", file_name.c_str());
|
||||
absl::PrintF("%-45s: %s\n", "File path", file_name);
|
||||
}
|
||||
printf("%-45s: %s\n", "Problem name", linear_program.name().c_str());
|
||||
absl::PrintF("%-45s: %s\n", "Problem name", linear_program.name());
|
||||
if (absl::GetFlag(FLAGS_mps_solve)) {
|
||||
printf("%-45s: %15.15e\n", "Objective value", objective_value);
|
||||
printf("%-45s: %s\n", "Problem status", status_string.c_str());
|
||||
printf("%-45s: %-6.4g\n", "Solving time", solving_time_in_sec);
|
||||
absl::PrintF("%-45s: %15.15e\n", "Objective value", objective_value);
|
||||
absl::PrintF("%-45s: %s\n", "Problem status", status_string);
|
||||
absl::PrintF("%-45s: %-6.4g\n", "Solving time", solving_time_in_sec);
|
||||
}
|
||||
printf("%s%s", linear_program.GetPrettyProblemStats().c_str(),
|
||||
linear_program.GetPrettyNonZeroStats().c_str());
|
||||
absl::PrintF("%s%s", linear_program.GetPrettyProblemStats(),
|
||||
linear_program.GetPrettyNonZeroStats());
|
||||
}
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "absl/flags/flag.h"
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/sat/cp_model.h"
|
||||
@@ -108,6 +110,7 @@ void MultiKnapsackSat(int scaling, const std::string& params) {
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
absl::SetFlag(&FLAGS_logtostderr, true);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
operations_research::sat::MultiKnapsackSat(absl::GetFlag(FLAGS_size),
|
||||
absl::GetFlag(FLAGS_params));
|
||||
|
||||
@@ -26,19 +26,21 @@
|
||||
// A random problem generator is also included.
|
||||
|
||||
#include <atomic>
|
||||
#include <random>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/container/flat_hash_set.h"
|
||||
#include "absl/flags/flag.h"
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/random/uniform_int_distribution.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "ortools/base/hash.h"
|
||||
#include "ortools/base/integral_types.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/base/map_util.h"
|
||||
#include "ortools/base/random.h"
|
||||
#include "ortools/graph/shortestpaths.h"
|
||||
#include "ortools/sat/cp_model.h"
|
||||
#include "ortools/sat/model.h"
|
||||
@@ -128,7 +130,7 @@ class NetworkRoutingData {
|
||||
void AddDemand(int source, int destination, int traffic) {
|
||||
all_demands_[std::make_pair(source, destination)] = traffic;
|
||||
}
|
||||
void set_name(const std::string& name) { name_ = name; }
|
||||
void set_name(absl::string_view name) { name_ = name; }
|
||||
void set_max_capacity(int max_capacity) { max_capacity_ = max_capacity; }
|
||||
void set_fixed_charge_cost(int cost) { fixed_charge_cost_ = cost; }
|
||||
|
||||
@@ -137,8 +139,8 @@ class NetworkRoutingData {
|
||||
int num_nodes_;
|
||||
int max_capacity_;
|
||||
int fixed_charge_cost_;
|
||||
std::unordered_map<std::pair<int, int>, int> all_arcs_;
|
||||
std::unordered_map<std::pair<int, int>, int> all_demands_;
|
||||
std::map<std::pair<int, int>, int> all_arcs_;
|
||||
std::map<std::pair<int, int>, int> all_demands_;
|
||||
};
|
||||
|
||||
// ----- Data Generation -----
|
||||
@@ -156,15 +158,32 @@ class NetworkRoutingData {
|
||||
// fixed cost of 'fixed_charge_cost'.
|
||||
class NetworkRoutingDataBuilder {
|
||||
public:
|
||||
NetworkRoutingDataBuilder() : random_(0) {}
|
||||
|
||||
void BuildModelFromParameters(int num_clients, int num_backbones,
|
||||
int num_demands, int traffic_min,
|
||||
int traffic_max, int min_client_degree,
|
||||
int max_client_degree, int min_backbone_degree,
|
||||
int max_backbone_degree, int max_capacity,
|
||||
int fixed_charge_cost, int seed,
|
||||
NetworkRoutingData* const data) {
|
||||
NetworkRoutingDataBuilder(int num_clients, int num_backbones, int num_demands,
|
||||
int traffic_min, int traffic_max,
|
||||
int min_client_degree, int max_client_degree,
|
||||
int min_backbone_degree, int max_backbone_degree,
|
||||
int max_capacity, int fixed_charge_cost)
|
||||
: num_clients_(num_clients),
|
||||
num_backbones_(num_backbones),
|
||||
num_demands_(num_demands),
|
||||
traffic_min_(traffic_min),
|
||||
traffic_max_(traffic_max),
|
||||
min_client_degree_(min_client_degree),
|
||||
max_client_degree_(max_client_degree),
|
||||
min_backbone_degree_(min_backbone_degree),
|
||||
max_backbone_degree_(max_backbone_degree),
|
||||
max_capacity_(max_capacity),
|
||||
fixed_charge_cost_(fixed_charge_cost),
|
||||
rand_gen_(0),
|
||||
uniform_backbones_(0, num_backbones_ - 1),
|
||||
uniform_clients_(0, num_clients_ - 1),
|
||||
uniform_demands_(0, num_demands_ - 1),
|
||||
uniform_traffic_(traffic_min, traffic_max),
|
||||
uniform_client_degree_(min_client_degree_, max_client_degree_),
|
||||
uniform_backbone_degree_(min_backbone_degree_, max_backbone_degree_),
|
||||
uniform_source_(num_clients_ == 0 ? 0 : num_backbones_,
|
||||
num_clients_ == 0 ? num_backbones - 1
|
||||
: num_clients_ + num_backbones_ - 1) {
|
||||
CHECK_GE(num_backbones, 1);
|
||||
CHECK_GE(num_clients, 0);
|
||||
CHECK_GE(num_demands, 1);
|
||||
@@ -180,16 +199,14 @@ class NetworkRoutingDataBuilder {
|
||||
CHECK_LE(max_client_degree, num_backbones);
|
||||
CHECK_LE(max_backbone_degree, num_backbones);
|
||||
CHECK_GE(max_capacity, 1);
|
||||
}
|
||||
|
||||
const int size = num_backbones + num_clients;
|
||||
void Build(int seed, NetworkRoutingData* const data) {
|
||||
const int size = num_backbones_ + num_clients_;
|
||||
InitData(size, seed);
|
||||
BuildGraph(num_clients, num_backbones, min_client_degree, max_client_degree,
|
||||
min_backbone_degree, max_backbone_degree);
|
||||
CreateDemands(num_clients, num_backbones, num_demands, traffic_min,
|
||||
traffic_max, data);
|
||||
FillData(num_clients, num_backbones, num_demands, traffic_min, traffic_max,
|
||||
min_client_degree, max_client_degree, min_backbone_degree,
|
||||
max_backbone_degree, max_capacity, fixed_charge_cost, seed, data);
|
||||
BuildGraph();
|
||||
CreateDemands(data);
|
||||
FillData(seed, data);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -201,58 +218,57 @@ class NetworkRoutingDataBuilder {
|
||||
}
|
||||
degrees_.clear();
|
||||
degrees_.resize(size, 0);
|
||||
random_.Reset(seed);
|
||||
rand_gen_.seed(seed);
|
||||
}
|
||||
|
||||
void BuildGraph(int num_clients, int num_backbones, int min_client_degree,
|
||||
int max_client_degree, int min_backbone_degree,
|
||||
int max_backbone_degree) {
|
||||
const int size = num_backbones + num_clients;
|
||||
void BuildGraph() {
|
||||
const int size = num_backbones_ + num_clients_;
|
||||
|
||||
// First we create the backbone nodes.
|
||||
for (int i = 1; i < num_backbones; ++i) {
|
||||
int j = random_.Uniform(i);
|
||||
for (int i = 1; i < num_backbones_; ++i) {
|
||||
absl::uniform_int_distribution<int> source(0, i - 1);
|
||||
const int j = source(rand_gen_);
|
||||
CHECK_LT(j, i);
|
||||
AddEdge(i, j);
|
||||
}
|
||||
|
||||
std::unordered_set<int> to_complete;
|
||||
std::unordered_set<int> not_full;
|
||||
for (int i = 0; i < num_backbones; ++i) {
|
||||
if (degrees_[i] < min_backbone_degree) {
|
||||
std::set<int> to_complete;
|
||||
std::set<int> not_full;
|
||||
for (int i = 0; i < num_backbones_; ++i) {
|
||||
if (degrees_[i] < min_backbone_degree_) {
|
||||
to_complete.insert(i);
|
||||
}
|
||||
if (degrees_[i] < max_backbone_degree) {
|
||||
if (degrees_[i] < max_backbone_degree_) {
|
||||
not_full.insert(i);
|
||||
}
|
||||
}
|
||||
while (!to_complete.empty() && not_full.size() > 1) {
|
||||
const int node1 = *(to_complete.begin());
|
||||
int node2 = node1;
|
||||
while (node2 == node1 || degrees_[node2] >= max_backbone_degree) {
|
||||
node2 = random_.Uniform(num_backbones);
|
||||
while (node2 == node1 || degrees_[node2] >= max_backbone_degree_) {
|
||||
node2 = uniform_backbones_(rand_gen_);
|
||||
}
|
||||
AddEdge(node1, node2);
|
||||
if (degrees_[node1] >= min_backbone_degree) {
|
||||
if (degrees_[node1] >= min_backbone_degree_) {
|
||||
to_complete.erase(node1);
|
||||
}
|
||||
if (degrees_[node2] >= min_backbone_degree) {
|
||||
if (degrees_[node2] >= min_backbone_degree_) {
|
||||
to_complete.erase(node2);
|
||||
}
|
||||
if (degrees_[node1] >= max_backbone_degree) {
|
||||
if (degrees_[node1] >= max_backbone_degree_) {
|
||||
not_full.erase(node1);
|
||||
}
|
||||
if (degrees_[node2] >= max_backbone_degree) {
|
||||
if (degrees_[node2] >= max_backbone_degree_) {
|
||||
not_full.erase(node2);
|
||||
}
|
||||
}
|
||||
|
||||
// Then create the client nodes connected to the backbone nodes.
|
||||
// If num_client is 0, then backbone nodes are also client nodes.
|
||||
for (int i = num_backbones; i < size; ++i) {
|
||||
const int degree = RandomInInterval(min_client_degree, max_client_degree);
|
||||
for (int i = num_backbones_; i < size; ++i) {
|
||||
const int degree = uniform_client_degree_(rand_gen_);
|
||||
while (degrees_[i] < degree) {
|
||||
const int j = random_.Uniform(num_backbones);
|
||||
const int j = uniform_backbones_(rand_gen_);
|
||||
if (!network_[i][j]) {
|
||||
AddEdge(i, j);
|
||||
}
|
||||
@@ -260,33 +276,26 @@ class NetworkRoutingDataBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
void CreateDemands(int num_clients, int num_backbones, int num_demands,
|
||||
int traffic_min, int traffic_max,
|
||||
NetworkRoutingData* const data) {
|
||||
while (data->num_demands() < num_demands) {
|
||||
const int source = RandomClient(num_clients, num_backbones);
|
||||
void CreateDemands(NetworkRoutingData* const data) {
|
||||
while (data->num_demands() < num_demands_) {
|
||||
const int source = uniform_source_(rand_gen_);
|
||||
int dest = source;
|
||||
while (dest == source) {
|
||||
dest = RandomClient(num_clients, num_backbones);
|
||||
dest = uniform_source_(rand_gen_);
|
||||
}
|
||||
const int traffic = RandomInInterval(traffic_min, traffic_max);
|
||||
const int traffic = uniform_traffic_(rand_gen_);
|
||||
data->AddDemand(source, dest, traffic);
|
||||
}
|
||||
}
|
||||
|
||||
void FillData(int num_clients, int num_backbones, int num_demands,
|
||||
int traffic_min, int traffic_max, int min_client_degree,
|
||||
int max_client_degree, int min_backbone_degree,
|
||||
int max_backbone_degree, int max_capacity,
|
||||
int fixed_charge_cost, int seed,
|
||||
NetworkRoutingData* const data) {
|
||||
const int size = num_backbones + num_clients;
|
||||
void FillData(int seed, NetworkRoutingData* const data) {
|
||||
const int size = num_backbones_ + num_clients_;
|
||||
|
||||
const std::string name = absl::StrFormat(
|
||||
"mp_c%i_b%i_d%i.t%i-%i.cd%i-%i.bd%i-%i.mc%i.fc%i.s%i", num_clients,
|
||||
num_backbones, num_demands, traffic_min, traffic_max, min_client_degree,
|
||||
max_client_degree, min_backbone_degree, max_backbone_degree,
|
||||
max_capacity, fixed_charge_cost, seed);
|
||||
"mp_c%i_b%i_d%i.t%i-%i.cd%i-%i.bd%i-%i.mc%i.fc%i.s%i", num_clients_,
|
||||
num_backbones_, num_demands_, traffic_min_, traffic_max_,
|
||||
min_client_degree_, max_client_degree_, min_backbone_degree_,
|
||||
max_backbone_degree_, max_capacity_, fixed_charge_cost_, seed);
|
||||
data->set_name(name);
|
||||
|
||||
data->set_num_nodes(size);
|
||||
@@ -294,13 +303,13 @@ class NetworkRoutingDataBuilder {
|
||||
for (int i = 0; i < size - 1; ++i) {
|
||||
for (int j = i + 1; j < size; ++j) {
|
||||
if (network_[i][j]) {
|
||||
data->AddArc(i, j, max_capacity);
|
||||
data->AddArc(i, j, max_capacity_);
|
||||
num_arcs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
data->set_max_capacity(max_capacity);
|
||||
data->set_fixed_charge_cost(fixed_charge_cost);
|
||||
data->set_max_capacity(max_capacity_);
|
||||
data->set_fixed_charge_cost(fixed_charge_cost_);
|
||||
}
|
||||
|
||||
void AddEdge(int i, int j) {
|
||||
@@ -310,19 +319,28 @@ class NetworkRoutingDataBuilder {
|
||||
network_[j][i] = true;
|
||||
}
|
||||
|
||||
int RandomInInterval(int interval_min, int interval_max) {
|
||||
CHECK_LE(interval_min, interval_max);
|
||||
return random_.Uniform(interval_max - interval_min + 1) + interval_min;
|
||||
}
|
||||
const int num_clients_;
|
||||
const int num_backbones_;
|
||||
const int num_demands_;
|
||||
const int traffic_min_;
|
||||
const int traffic_max_;
|
||||
const int min_client_degree_;
|
||||
const int max_client_degree_;
|
||||
const int min_backbone_degree_;
|
||||
const int max_backbone_degree_;
|
||||
const int max_capacity_;
|
||||
const int fixed_charge_cost_;
|
||||
|
||||
int RandomClient(int num_clients, int num_backbones) {
|
||||
return (num_clients == 0) ? random_.Uniform(num_backbones)
|
||||
: random_.Uniform(num_clients) + num_backbones;
|
||||
}
|
||||
|
||||
std::vector<std::vector<bool> > network_;
|
||||
std::vector<std::vector<bool>> network_;
|
||||
std::vector<int> degrees_;
|
||||
MTRandom random_;
|
||||
std::mt19937 rand_gen_;
|
||||
absl::uniform_int_distribution<int> uniform_backbones_;
|
||||
absl::uniform_int_distribution<int> uniform_clients_;
|
||||
absl::uniform_int_distribution<int> uniform_demands_;
|
||||
absl::uniform_int_distribution<int> uniform_traffic_;
|
||||
absl::uniform_int_distribution<int> uniform_client_degree_;
|
||||
absl::uniform_int_distribution<int> uniform_backbone_degree_;
|
||||
absl::uniform_int_distribution<int> uniform_source_;
|
||||
};
|
||||
|
||||
// ---------- Solving the Problem ----------
|
||||
@@ -341,7 +359,7 @@ struct Demand {
|
||||
|
||||
class NetworkRoutingSolver {
|
||||
public:
|
||||
typedef std::unordered_set<int> OnePath;
|
||||
typedef absl::flat_hash_set<int> OnePath;
|
||||
|
||||
NetworkRoutingSolver() : num_nodes_(-1) {}
|
||||
|
||||
@@ -553,7 +571,7 @@ class NetworkRoutingSolver {
|
||||
|
||||
// ----- Build Model -----
|
||||
CpModelBuilder cp_model;
|
||||
std::vector<std::vector<IntVar> > path_vars(num_demands);
|
||||
std::vector<std::vector<IntVar>> path_vars(num_demands);
|
||||
|
||||
// Node - Graph Constraint.
|
||||
for (int demand_index = 0; demand_index < num_demands; ++demand_index) {
|
||||
@@ -628,7 +646,6 @@ class NetworkRoutingSolver {
|
||||
int num_solutions = 0;
|
||||
model.Add(NewFeasibleSolutionObserver([&](const CpSolverResponse& r) {
|
||||
LOG(INFO) << "Solution " << num_solutions;
|
||||
const double objective_value = r.objective_value();
|
||||
const double percent = SolutionIntegerValue(r, max_usage_cost) / 10.0;
|
||||
int num_non_comfortable_arcs = 0;
|
||||
for (const BoolVar comfort : comfortable_traffic_vars) {
|
||||
@@ -651,31 +668,34 @@ class NetworkRoutingSolver {
|
||||
private:
|
||||
int count_arcs() const { return arcs_data_.size() / 2; }
|
||||
|
||||
std::vector<std::vector<int64> > arcs_data_;
|
||||
std::vector<std::vector<int64>> arcs_data_;
|
||||
std::vector<int> arc_capacity_;
|
||||
std::vector<Demand> demands_array_;
|
||||
int num_nodes_;
|
||||
std::vector<int64> all_min_path_lengths_;
|
||||
std::vector<std::vector<int> > capacity_;
|
||||
std::vector<std::vector<OnePath> > all_paths_;
|
||||
std::vector<std::vector<int>> capacity_;
|
||||
std::vector<std::vector<OnePath>> all_paths_;
|
||||
};
|
||||
|
||||
} // namespace sat
|
||||
} // namespace operations_research
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
absl::SetFlag(&FLAGS_logtostderr, true);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
|
||||
operations_research::sat::NetworkRoutingData data;
|
||||
operations_research::sat::NetworkRoutingDataBuilder builder;
|
||||
builder.BuildModelFromParameters(
|
||||
operations_research::sat::NetworkRoutingDataBuilder builder(
|
||||
absl::GetFlag(FLAGS_clients), absl::GetFlag(FLAGS_backbones),
|
||||
absl::GetFlag(FLAGS_demands), absl::GetFlag(FLAGS_traffic_min),
|
||||
absl::GetFlag(FLAGS_traffic_max), absl::GetFlag(FLAGS_min_client_degree),
|
||||
absl::GetFlag(FLAGS_max_client_degree),
|
||||
absl::GetFlag(FLAGS_min_backbone_degree),
|
||||
absl::GetFlag(FLAGS_max_backbone_degree),
|
||||
absl::GetFlag(FLAGS_max_capacity), absl::GetFlag(FLAGS_fixed_charge_cost),
|
||||
absl::GetFlag(FLAGS_seed), &data);
|
||||
absl::GetFlag(FLAGS_max_capacity),
|
||||
absl::GetFlag(FLAGS_fixed_charge_cost));
|
||||
builder.Build(absl::GetFlag(FLAGS_seed), &data);
|
||||
operations_research::sat::NetworkRoutingSolver solver;
|
||||
solver.Init(data, absl::GetFlag(FLAGS_extra_hops),
|
||||
absl::GetFlag(FLAGS_max_paths));
|
||||
|
||||
@@ -58,7 +58,7 @@ class OpbReader {
|
||||
// Since the problem name is not stored in the cnf format, we infer it from
|
||||
// the file name.
|
||||
static std::string ExtractProblemName(const std::string& filename) {
|
||||
const int found = filename.find_last_of("/");
|
||||
const int found = filename.find_last_of('/');
|
||||
const std::string problem_name =
|
||||
found != std::string::npos ? filename.substr(found + 1) : filename;
|
||||
return problem_name;
|
||||
|
||||
@@ -36,9 +36,14 @@
|
||||
// Reads data in the format defined by Li & Lim
|
||||
// (https://www.sintef.no/projectweb/top/pdptw/li-lim-benchmark/documentation/).
|
||||
|
||||
#include <cmath>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/flags/flag.h"
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/strings/numbers.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/str_split.h"
|
||||
#include "google/protobuf/text_format.h"
|
||||
@@ -134,7 +139,7 @@ std::vector<IntVar*> GetTabuVars(std::vector<IntVar*> existing_vars,
|
||||
return vars;
|
||||
}
|
||||
|
||||
// Outputs a solution to the current model in a std::string.
|
||||
// Outputs a solution to the current model in a string.
|
||||
std::string VerboseOutput(const RoutingModel& routing,
|
||||
const RoutingIndexManager& manager,
|
||||
const Assignment& assignment,
|
||||
@@ -185,8 +190,7 @@ std::string VerboseOutput(const RoutingModel& routing,
|
||||
|
||||
namespace {
|
||||
// An inefficient but convenient method to parse a whitespace-separated list
|
||||
// of integers. Returns true iff the input std::string was entirely valid and
|
||||
// parsed.
|
||||
// of integers. Returns true iff the input string was entirely valid and parsed.
|
||||
bool SafeParseInt64Array(const std::string& str,
|
||||
std::vector<int64>* parsed_int) {
|
||||
std::istringstream input(str);
|
||||
@@ -390,6 +394,7 @@ bool LoadAndSolve(const std::string& pdp_file,
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
absl::SetFlag(&FLAGS_logtostderr, true);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
operations_research::RoutingModelParameters model_parameters =
|
||||
operations_research::DefaultRoutingModelParameters();
|
||||
|
||||
@@ -37,6 +37,12 @@ class LinearSumAssignment;
|
||||
// description, outputs the problem in DIMACS format in the output file.
|
||||
// For a description of the format, see
|
||||
// http://lpsolve.sourceforge.net/5.5/DIMACS_asn.htm
|
||||
template <typename GraphType>
|
||||
void PrintDimacsAssignmentProblem(
|
||||
const LinearSumAssignment<GraphType>& assignment,
|
||||
const TailArrayManager<GraphType>& tail_array_manager,
|
||||
const std::string& output_filename);
|
||||
|
||||
template <typename GraphType>
|
||||
void PrintDimacsAssignmentProblem(
|
||||
const LinearSumAssignment<GraphType>& assignment,
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "absl/flags/flag.h"
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/strings/match.h"
|
||||
@@ -443,9 +445,9 @@ int main(int argc, char** argv) {
|
||||
// By default, we want to show how the solver progress. Note that this needs
|
||||
// to be set before InitGoogle() which has the nice side-effect of allowing
|
||||
// the user to override it.
|
||||
absl::SetProgramUsageMessage(kUsage);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::SetFlag(&FLAGS_vmodule, "cp_model_solver=1");
|
||||
gflags::SetUsageMessage(kUsage);
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
absl::SetFlag(&FLAGS_alsologtostderr, true);
|
||||
return operations_research::sat::Run();
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "absl/flags/flag.h"
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/strings/numbers.h"
|
||||
#include "absl/strings/str_split.h"
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
@@ -303,7 +305,9 @@ void LoadAndSolve(const std::string& file_name) {
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
absl::SetFlag(&FLAGS_logtostderr, true);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
|
||||
if (absl::GetFlag(FLAGS_input).empty()) {
|
||||
LOG(FATAL) << "Please supply a data file with --input=";
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/strings/match.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
// We also introduces a variable at_home[d][i] which is true if team i
|
||||
// plays any opponent at home on day d.
|
||||
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/str_join.h"
|
||||
@@ -323,8 +325,8 @@ static const char kUsage[] =
|
||||
"There is no output besides the debug LOGs of the solver.";
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::SetFlag(&FLAGS_logtostderr, true);
|
||||
google::InitGoogleLogging(kUsage);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
CHECK_EQ(0, absl::GetFlag(FLAGS_num_teams) % 2)
|
||||
<< "The number of teams must be even";
|
||||
|
||||
@@ -59,6 +59,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "ortools/base/logging.h"
|
||||
@@ -241,8 +243,8 @@ const int kInstanceCount = 10;
|
||||
|
||||
class Box {
|
||||
public:
|
||||
static const int kAreaCost = 1;
|
||||
static const int kFixedCost = 10;
|
||||
static constexpr int kAreaCost = 1;
|
||||
static constexpr int kFixedCost = 10;
|
||||
|
||||
Box() {}
|
||||
Box(int x_min, int x_max, int y_min, int y_max)
|
||||
@@ -602,6 +604,7 @@ int main(int argc, char** argv) {
|
||||
usage += " --colgen_max_iterations <n> max columns to generate\n";
|
||||
usage += " --colgen_complete generate all columns at start\n";
|
||||
|
||||
google::InitGoogleLogging(usage.c_str());
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
|
||||
operations_research::MPSolver::OptimizationProblemType solver_type;
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "absl/flags/flag.h"
|
||||
#include "absl/flags/parse.h"
|
||||
#include "absl/flags/usage.h"
|
||||
#include "absl/strings/match.h"
|
||||
#include "absl/strings/numbers.h"
|
||||
#include "absl/strings/str_join.h"
|
||||
@@ -253,6 +255,7 @@ void ParseAndSolve() {
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
absl::SetFlag(&FLAGS_logtostderr, true);
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
absl::ParseCommandLine(argc, argv);
|
||||
if (absl::GetFlag(FLAGS_input).empty()) {
|
||||
LOG(FATAL) << "Please supply a data file with --input=";
|
||||
|
||||
@@ -483,6 +483,7 @@ test_cc_contrib: ;
|
||||
.PHONY: test_cc_cpp # Build and Run all C++ Examples (located in ortools/examples/cpp)
|
||||
test_cc_cpp: \
|
||||
rcc_costas_array_sat \
|
||||
rcc_cryptarithm_sat \
|
||||
rcc_cvrp_disjoint_tw \
|
||||
rcc_cvrptw \
|
||||
rcc_cvrptw_with_breaks \
|
||||
@@ -492,6 +493,7 @@ test_cc_cpp: \
|
||||
rcc_flow_api \
|
||||
rcc_linear_assignment_api \
|
||||
rcc_linear_solver_protocol_buffers \
|
||||
rcc_magic_sequence_sat \
|
||||
rcc_magic_square_sat \
|
||||
rcc_nqueens \
|
||||
rcc_random_tsp \
|
||||
|
||||
Reference in New Issue
Block a user