OR-Tools  8.1
fz.cc
Go to the documentation of this file.
1 // Copyright 2010-2018 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 // This is the skeleton for the official flatzinc interpreter. Much
15 // of the funcionalities are fixed (name of parameters, format of the
16 // input): see http://www.minizinc.org/downloads/doc-1.6/flatzinc-spec.pdf
17 
18 #if defined(__GNUC__) // Linux or Mac OS X.
19 #include <signal.h>
20 #endif // __GNUC__
21 
22 #include <csignal>
23 #include <iostream>
24 #include <string>
25 #include <vector>
26 
27 #include "absl/flags/flag.h"
30 #include "ortools/base/logging.h"
32 #include "ortools/base/timer.h"
35 #include "ortools/flatzinc/model.h"
38 
39 ABSL_FLAG(double, time_limit, 0, "time limit in seconds.");
40 ABSL_FLAG(bool, all_solutions, false, "Search for all solutions.");
41 ABSL_FLAG(int, num_solutions, 0,
42  "Maximum number of solution to search for, 0 means unspecified.");
43 ABSL_FLAG(bool, free_search, false,
44  "If false, the solver must follow the defined search."
45  "If true, other search are allowed.");
46 ABSL_FLAG(int, threads, 0, "Number of threads the solver will use.");
47 ABSL_FLAG(bool, presolve, true, "Presolve the model to simplify it.");
48 ABSL_FLAG(bool, statistics, false, "Print solver statistics after search.");
49 ABSL_FLAG(bool, read_from_stdin, false,
50  "Read the FlatZinc from stdin, not from a file.");
51 ABSL_FLAG(int, fz_seed, 0, "Random seed");
52 ABSL_FLAG(std::string, fz_model_name, "stdin",
53  "Define problem name when reading from stdin.");
54 ABSL_FLAG(std::string, params, "", "SatParameters as a text proto.");
55 
56 ABSL_DECLARE_FLAG(bool, log_prefix);
57 
58 namespace operations_research {
59 namespace fz {
60 
61 std::vector<char*> FixAndParseParameters(int* argc, char*** argv) {
62  absl::SetFlag(&FLAGS_log_prefix, false);
63 
64  char all_param[] = "--all_solutions";
65  char free_param[] = "--free_search";
66  char threads_param[] = "--threads";
67  char solutions_param[] = "--num_solutions";
68  char logging_param[] = "--fz_logging";
69  char statistics_param[] = "--statistics";
70  char seed_param[] = "--fz_seed";
71  char verbose_param[] = "--fz_verbose";
72  char debug_param[] = "--fz_debug";
73  char time_param[] = "--time_limit";
74  bool use_time_param = false;
75  for (int i = 1; i < *argc; ++i) {
76  if (strcmp((*argv)[i], "-a") == 0) {
77  (*argv)[i] = all_param;
78  }
79  if (strcmp((*argv)[i], "-f") == 0) {
80  (*argv)[i] = free_param;
81  }
82  if (strcmp((*argv)[i], "-p") == 0) {
83  (*argv)[i] = threads_param;
84  }
85  if (strcmp((*argv)[i], "-n") == 0) {
86  (*argv)[i] = solutions_param;
87  }
88  if (strcmp((*argv)[i], "-l") == 0) {
89  (*argv)[i] = logging_param;
90  }
91  if (strcmp((*argv)[i], "-s") == 0) {
92  (*argv)[i] = statistics_param;
93  }
94  if (strcmp((*argv)[i], "-r") == 0) {
95  (*argv)[i] = seed_param;
96  }
97  if (strcmp((*argv)[i], "-v") == 0) {
98  (*argv)[i] = verbose_param;
99  }
100  if (strcmp((*argv)[i], "-d") == 0) {
101  (*argv)[i] = debug_param;
102  }
103  if (strcmp((*argv)[i], "-t") == 0) {
104  (*argv)[i] = time_param;
105  use_time_param = true;
106  }
107  }
108  const char kUsage[] =
109  "Usage: see flags.\nThis program parses and solve a flatzinc problem.";
110 
111  absl::SetProgramUsageMessage(kUsage);
112  const std::vector<char*> residual_flags =
113  absl::ParseCommandLine(*argc, *argv);
114  google::InitGoogleLogging((*argv)[0]);
115 
116  // Fix time limit if -t was used.
117  if (use_time_param) {
118  absl::SetFlag(&FLAGS_time_limit, absl::GetFlag(FLAGS_time_limit) / 1000.0);
119  }
120  return residual_flags;
121 }
122 
123 Model ParseFlatzincModel(const std::string& input, bool input_is_filename) {
124  WallTimer timer;
125  timer.Start();
126  // Read model.
127  std::string problem_name =
128  input_is_filename ? input : absl::GetFlag(FLAGS_fz_model_name);
129  if (input_is_filename || absl::EndsWith(problem_name, ".fzn")) {
130  CHECK(absl::EndsWith(problem_name, ".fzn"));
131  problem_name.resize(problem_name.size() - 4);
132  const size_t found = problem_name.find_last_of("/\\");
133  if (found != std::string::npos) {
134  problem_name = problem_name.substr(found + 1);
135  }
136  }
137  Model model(problem_name);
138  if (input_is_filename) {
140  } else {
142  }
143 
144  FZLOG << "File " << (input_is_filename ? input : "stdin") << " parsed in "
145  << timer.GetInMs() << " ms" << FZENDL;
146 
147  // Presolve the model.
148  Presolver presolve;
149  FZLOG << "Presolve model" << FZENDL;
150  timer.Reset();
151  timer.Start();
152  presolve.Run(&model);
153  FZLOG << " - done in " << timer.GetInMs() << " ms" << FZENDL;
154 
155  // Print statistics.
156  ModelStatistics stats(model);
157  stats.BuildStatistics();
158  stats.PrintStatistics();
159  return model;
160 }
161 
162 } // namespace fz
163 } // namespace operations_research
164 
165 int main(int argc, char** argv) {
166  // Flatzinc specifications require single dash parameters (-a, -f, -p).
167  // We need to fix parameters before parsing them.
168  const std::vector<char*> residual_flags =
170  // We allow piping model through stdin.
171  std::string input;
172  if (absl::GetFlag(FLAGS_read_from_stdin)) {
173  std::string currentLine;
174  while (std::getline(std::cin, currentLine)) {
175  input.append(currentLine);
176  }
177  } else {
178  if (residual_flags.empty()) {
179  LOG(ERROR) << "Usage: " << argv[0] << " <file>";
180  return EXIT_FAILURE;
181  }
182  input = residual_flags.back();
183  }
184 
187  input, !absl::GetFlag(FLAGS_read_from_stdin));
189  parameters.display_all_solutions = absl::GetFlag(FLAGS_all_solutions);
190  parameters.use_free_search = absl::GetFlag(FLAGS_free_search);
191  parameters.verbose_logging = absl::GetFlag(FLAGS_fz_logging);
192  if (absl::GetFlag(FLAGS_num_solutions) == 0) {
193  absl::SetFlag(&FLAGS_num_solutions,
194  absl::GetFlag(FLAGS_all_solutions) ? kint32max : 1);
195  }
196  parameters.max_number_of_solutions = absl::GetFlag(FLAGS_num_solutions);
197  parameters.random_seed = absl::GetFlag(FLAGS_fz_seed);
198  parameters.display_statistics = absl::GetFlag(FLAGS_statistics);
199  parameters.number_of_threads = absl::GetFlag(FLAGS_threads);
200  parameters.max_time_in_seconds = absl::GetFlag(FLAGS_time_limit);
201 
203  model, parameters, absl::GetFlag(FLAGS_params));
204  return EXIT_SUCCESS;
205 }
integral_types.h
threadpool.h
operations_research::fz::FixAndParseParameters
std::vector< char * > FixAndParseParameters(int *argc, char ***argv)
Definition: fz.cc:61
FZENDL
#define FZENDL
Definition: flatzinc/logging.h:31
main
int main(int argc, char **argv)
Definition: fz.cc:165
LOG
#define LOG(severity)
Definition: base/logging.h:420
ERROR
const int ERROR
Definition: log_severity.h:32
operations_research::fz::FlatzincSatParameters
Definition: cp_model_fz_solver.h:22
model.h
logging.h
operations_research::fz::Model
Definition: flatzinc/model.h:315
operations_research
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
Definition: dense_doubly_linked_list.h:21
ABSL_DECLARE_FLAG
ABSL_DECLARE_FLAG(bool, log_prefix)
operations_research::fz::ParseFlatzincString
bool ParseFlatzincString(const std::string &input, Model *model)
Definition: parser.cc:60
operations_research::fz::Presolver::Run
void Run(Model *model)
Definition: presolve.cc:450
logging.h
ABSL_FLAG
ABSL_FLAG(double, time_limit, 0, "time limit in seconds.")
FZLOG
#define FZLOG
Definition: flatzinc/logging.h:32
WallTimer::Start
void Start()
Definition: timer.h:31
kint32max
static const int32 kint32max
Definition: integral_types.h:59
time_limit
SharedTimeLimit * time_limit
Definition: cp_model_solver.cc:2103
timer.h
WallTimer
Definition: timer.h:23
presolve.h
WallTimer::Reset
void Reset()
Definition: timer.h:26
model
GRBmodel * model
Definition: gurobi_interface.cc:269
WallTimer::GetInMs
int64 GetInMs() const
Definition: timer.h:46
parser.h
input
static int input(yyscan_t yyscanner)
operations_research::fz::ModelStatistics::PrintStatistics
void PrintStatistics() const
Definition: model.cc:920
operations_research::fz::ModelStatistics::BuildStatistics
void BuildStatistics()
Definition: model.cc:933
operations_research::fz::ParseFlatzincModel
Model ParseFlatzincModel(const std::string &input, bool input_is_filename)
Definition: fz.cc:123
operations_research::fz::ParseFlatzincFile
bool ParseFlatzincFile(const std::string &filename, Model *model)
Definition: parser.cc:38
operations_research::sat::SolveFzWithCpModelProto
void SolveFzWithCpModelProto(const fz::Model &fz_model, const fz::FlatzincSatParameters &p, const std::string &sat_params)
Definition: cp_model_fz_solver.cc:982
operations_research::fz::Presolver
Definition: presolve.h:34
CHECK
#define CHECK(condition)
Definition: base/logging.h:495
commandlineflags.h
parameters
SatParameters parameters
Definition: cp_model_fz_solver.cc:108
google::InitGoogleLogging
void InitGoogleLogging(const char *argv0)
Definition: base/logging.cc:1867
operations_research::fz::ModelStatistics
Definition: flatzinc/model.h:390
cp_model_fz_solver.h