17#include "absl/flags/flag.h"
18#include "absl/log/check.h"
19#include "absl/strings/match.h"
20#include "absl/strings/str_join.h"
21#include "absl/strings/string_view.h"
22#include "absl/time/time.h"
33 "REQUIRED: Input file format. Either proto, proto_bin, OrlibRail, "
34 "OrlibScp or FimiDat.");
36ABSL_FLAG(std::string, hint_sol,
"",
"Input file name for solution.");
37ABSL_FLAG(std::string, hint_fmt,
"",
"Input file format for solution.");
40 "If non-empty, write the returned solution to the given file.");
42 "If out is non-empty, use the given format for the output.");
44 "If non-empty, write the set cover model to the given file. ");
46ABSL_FLAG(
bool, generate,
false,
"Generate a new model from the input model.");
48 "Number of elements wanted in the new generated model.");
50 "Number of subsets wanted in the new generated model.");
51ABSL_FLAG(
float, row_scale, 1.0,
"Row scale for the new generated model.");
53 "Column scale for the new generated model.");
54ABSL_FLAG(
float, cost_scale, 1.0,
"Cost scale for the new generated model.");
56ABSL_FLAG(std::string, generation,
"",
"First-solution generation method.");
57ABSL_FLAG(std::string, improvement,
"",
"Solution improvement method.");
59 "Number of threads to use by the underlying solver.");
62ABSL_FLAG(
bool, stats,
false,
"Log stats about the model.");
68 LOG(INFO) <<
", " << name <<
", num_elements, " << model->
num_elements()
70 LOG(INFO) <<
", " << name <<
", num_nonzeros, " << model->
num_nonzeros()
71 <<
", fill rate, " << model->
FillRate();
72 LOG(INFO) <<
", " << name <<
", cost, "
75 LOG(INFO) <<
", " << name <<
", num_rows, " << model->
num_elements()
77 LOG(INFO) <<
", " << name <<
", row size deciles, "
79 LOG(INFO) <<
", " << name <<
", row delta byte size stats, "
81 LOG(INFO) <<
", " << name <<
", num_columns, " << model->
num_subsets()
83 LOG(INFO) <<
", " << name <<
", column size deciles, "
85 LOG(INFO) <<
", " << name <<
", column delta byte size stats, "
88 for (
const ElementIndex element : model->
ElementRange()) {
89 if (model->
rows()[element].size() == 1) {
93 BaseInt num_singleton_columns = 0;
94 for (
const SubsetIndex subset : model->
SubsetRange()) {
95 if (model->
columns()[subset].size() == 1) {
96 ++num_singleton_columns;
99 LOG(INFO) <<
", " << name <<
", num_singleton_rows, " << num_singleton_rows
100 <<
", num_singleton_columns, " << num_singleton_columns;
105 LOG(INFO) <<
", " << name <<
", " << algo <<
", cost, " << cost
106 <<
", solution_cardinality, " << solution_cardinality <<
", "
107 << absl::ToInt64Microseconds(timer.
GetDuration()) <<
"e-6, s";
126 if (format_name.empty()) {
128 }
else if (absl::EqualsIgnoreCase(format_name,
"OrlibScp")) {
130 }
else if (absl::EqualsIgnoreCase(format_name,
"OrlibRail")) {
132 }
else if (absl::EqualsIgnoreCase(format_name,
"FimiDat")) {
134 }
else if (absl::EqualsIgnoreCase(format_name,
"proto")) {
136 }
else if (absl::EqualsIgnoreCase(format_name,
"proto_bin")) {
138 }
else if (absl::EqualsIgnoreCase(format_name,
"txt")) {
141 LOG(FATAL) <<
"Unsupported input format: " << format_name;
146 switch (input_format) {
158 LOG(FATAL) <<
"Unsupported input format: "
159 <<
static_cast<int>(input_format);
165 switch (input_format) {
173 LOG(FATAL) <<
"Unsupported input format: "
174 <<
static_cast<int>(input_format);
180 LOG(INFO) <<
"Writing model to " << output_file;
181 switch (output_format) {
195 LOG(FATAL) <<
"Unsupported output format: "
196 <<
static_cast<int>(output_format);
201 absl::string_view output_file,
FileFormat output_format) {
202 switch (output_format) {
215 LOG(FATAL) <<
"Unsupported output format: "
216 <<
static_cast<int>(output_format);
228 inv.
trace().size(), timer);
233 const auto&
input = absl::GetFlag(FLAGS_input);
234 const auto& input_format =
ParseFileFormat(absl::GetFlag(FLAGS_input_fmt));
235 const auto& output = absl::GetFlag(FLAGS_output);
236 const auto& output_format =
ParseFileFormat(absl::GetFlag(FLAGS_output_fmt));
238 LOG(FATAL) <<
"No input file specified.";
241 LOG(FATAL) <<
"Input format cannot be empty.";
244 LOG(FATAL) <<
"Output format cannot be empty.";
247 if (absl::GetFlag(FLAGS_generate)) {
250 model, absl::GetFlag(FLAGS_num_elements_wanted),
251 absl::GetFlag(FLAGS_num_subsets_wanted), absl::GetFlag(FLAGS_row_scale),
252 absl::GetFlag(FLAGS_column_scale), absl::GetFlag(FLAGS_cost_scale));
254 if (!output.empty()) {
260 auto problem = output.empty() ?
input : output;
261 if (absl::GetFlag(FLAGS_stats)) {
264 if (absl::GetFlag(FLAGS_solve)) {
265 LOG(INFO) <<
"Solving " << problem;
272int main(
int argc,
char** argv) {
absl::Duration GetDuration() const
void Start()
When Start() is called multiple times, only the most recent is used.
const std::vector< SetCoverDecision > & trace() const
Returns the vector of the decisions which have led to the current solution.
bool CheckConsistency(ConsistencyLevel consistency) const
Checks the consistency of the invariant at the given consistency level.
Cost cost() const
Returns the cost of current solution.
Main class for describing a weighted set-covering problem.
static SetCoverModel GenerateRandomModelFrom(const SetCoverModel &seed_model, BaseInt num_elements, BaseInt num_subsets, double row_scale, double column_scale, double cost_scale)
Stats ComputeColumnStats()
Computes basic statistics on columns and returns a Stats structure.
std::vector< int64_t > ComputeRowDeciles() const
Computes deciles on rows and returns a vector of deciles.
util_intops::StrongIntRange< ElementIndex > ElementRange() const
Stats ComputeCostStats()
Computes basic statistics on costs and returns a Stats structure.
Stats ComputeRowStats()
Computes basic statistics on rows and returns a Stats structure.
const SparseRowView & rows() const
Row view of the set covering problem.
int64_t num_nonzeros() const
Current number of nonzeros in the matrix.
BaseInt num_elements() const
util_intops::StrongIntRange< SubsetIndex > SubsetRange() const
Access to the ranges of subsets and elements.
Stats ComputeColumnDeltaSizeStats() const
Stats ComputeRowDeltaSizeStats() const
void CreateSparseRowView()
std::vector< int64_t > ComputeColumnDeciles() const
Computes deciles on columns and returns a vector of deciles.
const SparseColumnView & columns() const
Column view of the set covering problem.
BaseInt num_subsets() const
void InitGoogle(const char *usage, int *argc, char ***argv, bool deprecated)
In SWIG mode, we don't want anything besides these top-level includes.
SetCoverModel ReadOrlibScp(absl::string_view filename)
This is a row-based format where the elements are 1-indexed.
void WriteSetCoverProto(const SetCoverModel &model, absl::string_view filename, bool binary)
SetCoverModel ReadSetCoverProto(absl::string_view filename, bool binary)
SetCoverModel ReadModel(absl::string_view input_file, FileFormat input_format)
void WriteSetCoverSolutionProto(const SetCoverModel &model, const SubsetBoolVector &solution, absl::string_view filename, bool binary)
Select next search node to expand Select next item_i to add this new search node to the search Generate a new search node where item_i is not in the knapsack Check validity of this new partial solution(using propagators) - If valid
void LogStats(std::string name, SetCoverModel *model)
SetCoverInvariant::ConsistencyLevel CL
SubsetBoolVector ReadSetCoverSolutionText(absl::string_view filename)
void WriteSetCoverSolutionText(const SetCoverModel &model, const SubsetBoolVector &solution, absl::string_view filename)
SetCoverInvariant RunLazyElementDegree(std::string name, SetCoverModel *model)
FileFormat ParseFileFormat(const std::string &format_name)
SetCoverModel ReadOrlibRail(absl::string_view filename)
This is a column-based format where the elements are 1-indexed.
util_intops::StrongVector< SubsetIndex, bool > SubsetBoolVector
SubsetBoolVector ReadSolution(absl::string_view input_file, FileFormat input_format)
void WriteModel(const SetCoverModel &model, const std::string &output_file, FileFormat output_format)
void WriteOrlibScp(const SetCoverModel &model, absl::string_view filename)
void WriteOrlibRail(const SetCoverModel &model, absl::string_view filename)
Beware the fact that elements written are converted to 1-indexed.
SubsetBoolVector ReadSetCoverSolutionProto(absl::string_view filename, bool binary)
void LogCostAndTiming(std::string name, std::string algo, double cost, BaseInt solution_cardinality, const WallTimer &timer)
SetCoverModel ReadFimiDat(absl::string_view filename)
void WriteSolution(const SetCoverModel &model, const SubsetBoolVector &solution, absl::string_view output_file, FileFormat output_format)
static int input(yyscan_t yyscanner)
int main(int argc, char **argv)
ABSL_FLAG(std::string, input, "", "REQUIRED: Input file name.")
std::string DebugString() const