Program Listing for File ipg.cpp
↰ Return to documentation for file (src/shells/ipg.cpp
)
/* #############################################
* This file is part of
* ZERO
*
* Copyright (c) 2020
* Released under the Creative Commons
* CC BY-NC-SA 4.0 License
*
* Find out more at
* https://github.com/ds4dm/ZERO
* #############################################*/
#include "zero.h"
#include <boost/program_options.hpp>
using namespace std;
namespace po = boost::program_options;
int main(int argc, char **argv) {
string resFile, instanceFile, logFile;
int nThreads = 0, verbosity = 0, algorithm = 0, aggressiveness = 0, objective = 0, LCPalgo = 0;
double timeLimit = -1, devtol = -1;
po::options_description desc("ZERO-IPG: Allowed options");
desc
.add_options()(
"help,h", "Shows this help message")("version,v",
"Shows ZERO version")("input,i",
po::value<string>(
&instanceFile),
"Sets the input "
"path/filename of the "
"instance file (.json "
"appended "
"automatically)")("algorithm"
"m,a",
po::value<
int>(
&algorithm),
"Sets "
"the "
"Algorithm"
"m. "
"0:"
"CutAndPlay")("s"
"o"
"l"
"u"
"t"
"i"
"o"
"n"
","
"s",
po::value<
string>(
&resFile)
->default_value(
"dat/Solution"),
"S"
"e"
"t"
"s"
" "
"t"
"h"
"e"
" "
"o"
"u"
"t"
"p"
"u"
"t"
" "
"p"
"a"
"t"
"h"
"/"
"f"
"i"
"l"
"e"
"n"
"a"
"m"
"e"
" "
"o"
"f"
" "
"t"
"h"
"e"
" "
"s"
"o"
"l"
"u"
"t"
"i"
"o"
"n"
" "
"f"
"i"
"l"
"e"
" "
"("
"."
"j"
"s"
"o"
"n"
" "
"a"
"p"
"p"
"e"
"n"
"d"
"e"
"d"
" "
"a"
"u"
"t"
"o"
"m"
"a"
"t"
"i"
"c"
"a"
"l"
"l"
"y"
")")("log,l",
po::value<
string>(
&logFile)
->default_value(
"dat/"
"Results."
"csv"),
"Sets "
"the "
"output "
"path/"
"filenam"
"e of "
"the "
"csv "
"log "
"file")("timelimit,"
"tl",
po::value<
double>(
&timeLimit)
->default_value(
-1.0),
"Sets the "
"timelimit")("verbosity,ve",
po::value<
int>(
&verbosity)
->default_value(
0),
"Sets the verbosity level for info and warning messages. 0: "
"warning and critical. 1: info. 2: debug. 3: trace")("threads,t",
po::value<
int>(
&nThreads)
->default_value(
1),
"Sets the number of Threads for Gurobi. (int): number of Threads. 0: "
"auto (number of processors)")("devtol,dt",
po::value<
double>(
&devtol)
->default_value(
3e-4),
"Sets the deviation tolerance.")("aggressiveness,aggr",
po::value<
int>(
&aggressiveness)
->default_value(
0),
"Cutting planes aggressiveness (int): -1: NotEvenTry; 0: NoThanks; 1: KeepItCool; 2: Truculent")("objective,o",
po::value<
int>(&objective)
->default_value(
0),
"LCP Objective type (int): 0: Feasibility; 1: Linear; 2: Quadratic")("lcpalgo,l",
po::value<
int>(
&LCPalgo)
->default_value(
0),
"LCP Algorithm type (int): 0: MIP; 1: MINLP; 2: PATH");
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
po::notify(vm);
if (vm.count("help")) {
cout << desc;
return EXIT_SUCCESS;
}
if (vm.count("version") || verbosity >= 2) {
arma::arma_version ver;
int major = 0, minor = 0, technical = 0;
string M, m, p;
ZEROVersion(M, m, p);
LOG_S(INFO) << "ZERO Version: " << M << "." << m << "." << p;
if (vm.count("version"))
return EXIT_SUCCESS;
}
if (instanceFile.empty()) {
cout << "-i [--input] option missing.\n Use with --help for help on list "
"of arguments\n";
return EXIT_SUCCESS;
}
loguru::g_stderr_verbosity = verbosity;
// --------------------------------
// START
// --------------------------------
auto timeStart = std::chrono::high_resolution_clock::now();
try {
GRBEnv env = GRBEnv();
// OPTIONS
//------------
Models::IPG::IPG ipg(&env, instanceFile);
// Num Threads
if (nThreads != 0)
ipg.setNumThreads(nThreads);
// Pure NE
// TimeLimit
ipg.setTimeLimit(timeLimit);
if (devtol > 0)
ipg.setDeviationTolerance(devtol);
// Algorithm
// So far, just one...
ipg.setAlgorithm(Data::IPG::Algorithms::CutAndPlay);
switch (aggressiveness) {
case -1:
ipg.setCutsAggressiveness(Data::IPG::CutsAggressiveness::NotEvenTry);
break;
case 0:
ipg.setCutsAggressiveness(Data::IPG::CutsAggressiveness::NoThanks);
break;
case 1:
ipg.setCutsAggressiveness(Data::IPG::CutsAggressiveness::KeepItCool);
break;
default:
ipg.setCutsAggressiveness(Data::IPG::CutsAggressiveness::Truculent);
}
switch (LCPalgo) {
case 0:
ipg.setLCPAlgorithm(Data::LCP::Algorithms::MIP);
break;
case 1:
ipg.setLCPAlgorithm(Data::LCP::Algorithms::MINLP);
break;
default:
ipg.setLCPAlgorithm(Data::LCP::Algorithms::PATH);
}
if (LCPalgo != 2) {
switch (objective) {
case 0:
ipg.setGameObjective(Data::IPG::Objectives::Feasibility);
break;
case 1:
ipg.setGameObjective(Data::IPG::Objectives::Linear);
break;
default:
ipg.setGameObjective(Data::IPG::Objectives::Quadratic);
}
} else
ipg.setGameObjective(Data::IPG::Objectives::Feasibility);
ipg.findNashEq();
auto timeStop = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> timeDiff = timeStop - timeStart;
double wallClockTime = timeDiff.count();
int realThreads = nThreads > 0 ? env.get(GRB_IntParam_Threads) : nThreads;
// --------------------------------
// WRITING STATISTICS AND SOLUTION
// --------------------------------
auto stat = ipg.getStatistics();
if (!logFile.empty()) {
ifstream existCheck(logFile);
std::ofstream results(logFile, ios::app);
if (!existCheck.good()) {
results << "Instance;Algorithm;LCPAlgo;ObjType;Cuts;Players;isPureNE;"
"Status;"
"NumVar;Time;SocialWelfare;Threads;numIterations;ValueCuts;VPolyCuts;"
"MIPCuts;TotalCuts\n";
}
existCheck.close();
auto cuts = stat.AlgorithmData.Cuts.get();
int totalCuts = 0;
for (const auto &cut : cuts)
totalCuts += cut.second;
results << instanceFile << ";" << std::to_string(stat.AlgorithmData.Algorithm.get()) << ";"
<< std::to_string(stat.AlgorithmData.LCPSolver.get()) << ";"
<< std::to_string(stat.AlgorithmData.Objective.get()) << ";"
<< std::to_string(stat.AlgorithmData.CutAggressiveness.get()) << ";"
<< ipg.getNumPlayers() << ";" << std::to_string(stat.PureNashEquilibrium.get()) << ";"
<< std::to_string(stat.Status.get()) << ";" << stat.NumVar.get() << ";"
<< std::to_string(stat.WallClockTime.get()) << ";"
<< std::to_string(ipg.getSocialWelfare()) << ";"
<< std::to_string(stat.AlgorithmData.Threads.get()) << ";" << stat.NumIterations.get()
<< ";" << cuts.at(0).second << ";" << cuts.at(1).second << ";" << cuts.at(2).second
<< ";" << totalCuts << "\n";
results.close();
}
} catch (ZEROException &e) {
std::cerr << "" << e.what() << "--" << e.more();
}
return EXIT_SUCCESS;
}