2 #include <boost/log/core.hpp> 3 #include <boost/log/expressions.hpp> 4 #include <boost/log/trivial.hpp> 5 #include <boost/program_options.hpp> 8 #include <gurobi_c++.h> 13 namespace logging = boost::log;
17 int main(
int argc,
char **argv) {
18 string resFile, instanceFile =
"", logFile;
19 int writeLevel, nThreads, verbosity, bigM, algorithm, aggressiveness, add{0},
24 po::options_description desc(
"EPEC: Allowed options");
25 desc.add_options()(
"help,h",
"Shows this help message")(
"version,v",
26 "Shows EPEC version")(
27 "input,i", po::value<string>(&instanceFile),
28 "Sets the input path/filename of the instance file (.json appended " 30 "pure,p", po::value<bool>(&pure)->default_value(
false),
31 "Controls whether the algorithm should seek for a pure NE or not. If " 32 "algorithm is combinatorialPNE, this is automatically true.")(
33 "recover,r", po::value<int>(&recover)->default_value(0),
34 "If innerApproximation is used along with pureNE, which strategy should " 35 "be used to retrive a pure NE. 0: incrementalEnumeration, " 36 "1:combinatorialPNE")(
"algorithm,a", po::value<int>(&algorithm),
37 "Sets the algorithm. 0: fullEnumeration, " 38 "1:innerApproximation, 2:combinatorialPNE")(
39 "solution,s", po::value<string>(&resFile)->default_value(
"dat/Solution"),
40 "Sets the output path/filename of the solution file (.json appended " 42 "log,l", po::value<string>(&logFile)->default_value(
"dat/Results.csv"),
43 "Sets the output path/filename of the csv log file")(
44 "timelimit,tl", po::value<double>(&timeLimit)->default_value(-1.0),
45 "Sets the timelimit for solving the Nash Equilibrium model")(
46 "writelevel,w", po::value<int>(&writeLevel)->default_value(0),
47 "Sets the writeLevel param. 0: only Json. 1: only human-readable. 2: " 48 "both")(
"message,m", po::value<int>(&verbosity)->default_value(0),
49 "Sets the verbosity level for info and warning messages. 0: " 50 "warning and critical. 1: info. 2: debug. 3: trace")(
51 "bigM", po::value<int>(&bigM)->default_value(0),
52 "Replaces indicator constraints with bigM.")(
53 "threads,t", po::value<int>(&nThreads)->default_value(1),
54 "Sets the number of Threads for Gurobi. (int): number of threads. 0: " 55 "auto (number of processors)")(
56 "aggr,ag", po::value<int>(&aggressiveness)->default_value(1),
57 "Sets the aggressiveness for the innerApproximation, namely the number " 58 "of random polyhedra added if no deviation is found. (int)")(
59 "bound,bo", po::value<bool>(&bound)->default_value(
false),
60 "Decides whether primal variables should be bounded or not.")(
61 "boundBigM,bbm", po::value<double>(&boundBigM)->default_value(1e5),
62 "Set the bounding bigM related to the parameter --bound")(
63 "add,ad", po::value<int>(&add)->default_value(0),
64 "Sets the EPECAddPolyMethod for the innerApproximation. 0: sequential. " 65 "1: reverse_sequential. 2:random.");
68 po::store(po::parse_command_line(argc, argv, desc), vm);
69 po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
72 if (vm.count(
"help")) {
76 if (instanceFile ==
"") {
77 cout <<
"-i [--input] option missing.\n Use with --help for help on list " 83 logging::core::get()->set_filter(logging::trivial::severity >
84 logging::trivial::info);
87 logging::core::get()->set_filter(logging::trivial::severity >=
88 logging::trivial::info);
91 logging::core::get()->set_filter(logging::trivial::severity >=
92 logging::trivial::debug);
95 logging::core::get()->set_filter(logging::trivial::severity >=
96 logging::trivial::trace);
99 BOOST_LOG_TRIVIAL(warning)
100 <<
"Invalid option for --message (-m). Setting default value: 0";
102 logging::core::get()->set_filter(logging::trivial::severity >
103 logging::trivial::info);
106 if (verbosity >= 2) {
107 arma::arma_version ver;
108 int major, minor, technical;
109 GRBversion(&major, &minor, &technical);
110 BOOST_LOG_TRIVIAL(info) <<
"Dependencies:";
111 BOOST_LOG_TRIVIAL(info) <<
"\tARMAdillo: " << ver.as_string();
112 BOOST_LOG_TRIVIAL(info)
114 BOOST_LOG_TRIVIAL(info) <<
"\tBoost: " <<
to_string(BOOST_VERSION / 100000)
115 <<
"." <<
to_string(BOOST_VERSION / 100 % 1000);
122 cerr <<
"Error: instance is empty\n";
129 auto time_start = std::chrono::high_resolution_clock::now();
130 GRBEnv env = GRBEnv();
157 if (aggressiveness != 1)
183 for (
unsigned int j = 0; j < Instance.
Countries.size(); ++j)
190 }
catch (
string &s) {
191 std::cerr <<
"Error while finding Nash equilibrium: " << s <<
'\n';
193 }
catch (exception &e) {
194 std::cerr <<
"Error while finding Nash equilibrium: " << e.what() <<
'\n';
197 auto time_stop = std::chrono::high_resolution_clock::now();
198 std::chrono::duration<double> time_diff = time_stop - time_start;
199 double WallClockTime = time_diff.count();
200 int realThreads = nThreads > 0 ? env.get(GRB_IntParam_Threads) : nThreads;
208 ifstream existCheck(logFile);
209 std::ofstream results(logFile, ios::app);
211 if (!existCheck.good()) {
212 results <<
"Instance;Algorithm;Countries;Followers;isPureNE;RequiredPureNE;" 214 "numFeasiblePolyhedra;" 215 "numVar;numConstraints;numNonZero;ClockTime" 216 "(s);Threads;Indicators;numInnerIterations;lostIntermediateEq;" 218 "AddPolyMethod;numericalIssuesEncountered;bound;boundBigM;" 219 "recoveryStrategy\n";
225 ostream_iterator<int>(PolyT,
" "));
229 for (
auto &Countrie : Instance.
Countries)
230 results <<
" " << Countrie.n_followers;
235 <<
";" << stat.
numNonZero <<
";" << WallClockTime <<
";" 246 results <<
";-;-;-;-;-;-;-;-";
bool pureNE
True if the equilibrium is a pure NE.
std::vector< unsigned int > feasiblePolyhedra
void setAggressiveness(unsigned int a)
string to_string(const Game::EPECsolveStatus st)
void setBoundBigM(double val)
bool getBoundPrimals() const
int main(int argc, char **argv)
void writeSolution(const int writeLevel, std::string filename) const
std::vector< Models::LeadAllPar > Countries
LeadAllPar vector.
void setIndicators(bool val)
int numNonZero
matrix of findNashEq model
bool getIndicators() const
int numVar
Number of variables in findNashEq model.
void finalize()
Finalizes the creation of a Game::EPEC object.
void setNumThreads(unsigned int t)
Stores statistics for a (solved) EPEC instance.
Game::EPECsolveStatus status
void setTimeLimit(double val)
Game::EPECalgorithm getAlgorithm() const
arma::sp_mat TransportationCosts
Transportation costs matrix.
void setAddPolyMethod(Game::EPECAddPolyMethod add)
Stores a single Instance.
Solution found for the instance.
unsigned int getAggressiveness() const
void setRecoverStrategy(Game::EPECRecoverStrategy strategy)
EPEC & addTranspCosts(const arma::sp_mat &costs)
Adds intercountry transportation costs matrix.
double getBoundBigM() const
Game::EPECRecoverStrategy getRecoverStrategy() const
bool numericalIssuesEncountered
Time limit reached, nash equilibrium not found.
void setBoundPrimals(bool val)
int numConstraints
Number of constraints in findNashEq model.
Game::EPECAddPolyMethod getAddPolyMethod() const
EPEC & addCountry(LeadAllPar Params, const unsigned int addnlLeadVars=0)
Models a Standard Nash-Cournot game within a country
void setAlgorithm(Game::EPECalgorithm algorithm)
const EPECStatistics getStatistics() const
Get the EPECStatistics object for the current instance.