sync most c++ examples

This commit is contained in:
Laurent Perron
2021-01-14 10:48:19 +01:00
parent 692b590128
commit 805b733f98
35 changed files with 499 additions and 189 deletions

View File

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

View File

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

View File

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

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

View File

@@ -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.";

View File

@@ -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.";

View File

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

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

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

View File

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

View File

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

View File

@@ -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();

View File

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

View File

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

View File

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

View File

@@ -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=";
}

View File

@@ -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();

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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();

View File

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

View File

@@ -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();
}

View File

@@ -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=";
}

View File

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

View File

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

View File

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

View File

@@ -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=";

View File

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