4 #include <boost/log/trivial.hpp> 5 #include <boost/program_options.hpp> 6 #include <gurobi_c++.h> 11 #include <rapidjson/document.h> 12 #include <rapidjson/istreamwrapper.h> 13 #include <rapidjson/prettywriter.h> 14 #include <rapidjson/stringbuffer.h> 23 ost << std::left << std::setw(50);
26 ost << std::right << std::setprecision(2) << std::setw(16) << std::fixed;
35 ost <<
"Follower Parameters: " <<
'\n';
36 ost <<
"********************" <<
'\n';
42 << Models::prn::label <<
"Quadratic costs" 47 << Models::prn::label <<
"Production capacities" 51 << (a < 0 ? std::numeric_limits<double>::infinity() : a);
53 << Models::prn::label <<
"Tax Caps" 57 << (a < 0 ? std::numeric_limits<double>::infinity() : a);
63 ost <<
"Demand Parameters: " <<
'\n';
64 ost <<
"******************" <<
'\n';
65 ost <<
"Price\t\t =\t\t " << P.
alpha <<
"\t-\t" << P.
beta <<
" x Quantity" 71 ost <<
"Leader Parameters: " <<
'\n';
72 ost <<
"******************" <<
'\n';
74 ost << Models::prn::label <<
"Export Limit" 76 << (P.
export_limit < 0 ? std::numeric_limits<double>::infinity()
79 ost << Models::prn::label <<
"Import Limit" 81 << (P.
import_limit < 0 ? std::numeric_limits<double>::infinity()
84 ost << Models::prn::label <<
"Price limit" 86 << (P.
price_limit < 0 ? std::numeric_limits<double>::infinity()
93 ost <<
"EPEC Instance: " <<
'\n';
94 ost <<
"******************" <<
'\n';
103 ost <<
"***************************" 105 ost <<
"Leader Complete Description" 107 ost <<
"***************************" 110 ost << Models::prn::label <<
"Number of followers" 117 ost <<
"***************************" 126 ost <<
"Models::LeaderVars::FollowerStart";
129 ost <<
"Models::LeaderVars::NetImport";
132 ost <<
"Models::LeaderVars::NetExport";
135 ost <<
"Models::LeaderVars::CountryImport";
138 ost <<
"Models::LeaderVars::Caps";
141 ost <<
"Models::LeaderVars::Tax";
144 ost <<
"Models::LeaderVars::TaxQuad";
147 ost <<
"Models::LeaderVars::DualVar";
150 ost <<
"Models::LeaderVars::ConvHullDummy";
153 ost <<
"Models::LeaderVars::End";
156 cerr <<
"Incorrect argument to ostream& operator<<(ostream& ost, const " 164 std::vector<double> cq, cl, cap, ec, tc;
165 std::vector<std::string> nm;
182 nm.insert(nm.end(), F1.
names.begin(), F1.
names.end());
183 nm.insert(nm.end(), F2.
names.begin(), F2.
names.end());
201 if (Params.n_followers == 0)
202 throw "Error in EPEC::ParamValid(). 0 Followers?";
203 if (Params.FollowerParam.costs_lin.size() != Params.n_followers ||
204 Params.FollowerParam.costs_quad.size() != Params.n_followers ||
205 Params.FollowerParam.capacities.size() != Params.n_followers ||
206 Params.FollowerParam.tax_caps.size() != Params.n_followers ||
207 Params.FollowerParam.emission_costs.size() != Params.n_followers)
208 throw "Error in EPEC::ParamValid(). Size Mismatch";
209 if (Params.DemandParam.alpha <= 0 || Params.DemandParam.beta <= 0)
210 throw "Error in EPEC::ParamValid(). Invalid demand curve params";
212 if (Params.name ==
"")
213 throw "Error in EPEC::ParamValid(). Country name empty";
215 for (
const auto &p : this->AllLeadPars)
216 if (Params.name.compare(p.name) == 0)
217 throw "Error in EPEC::ParamValid(). Country name repetition";
223 const unsigned int follower,
235 const unsigned int LeadVars =
237 arma::sp_mat Q(1, 1), C(1, LeadVars + Params.n_followers - 1);
241 arma::vec c(1), b(1);
251 Q(0, 0) = Params.FollowerParam.costs_quad.at(follower) +
252 2 * Params.DemandParam.beta;
253 c(0) = Params.FollowerParam.costs_lin.at(follower) - Params.DemandParam.alpha;
256 Ctemp.cols(0, Params.n_followers - 1)
257 .fill(Params.DemandParam
259 Ctemp(0, Params.n_followers) = -Params.DemandParam.beta;
263 Ctemp(0, (Params.n_followers - 1) + 2 + Params.n_followers + follower) =
266 Ctemp(0, (Params.n_followers - 1) + 2 + Params.n_followers + 0) =
269 Ctemp(0, (Params.n_followers - 1) + 2 + Params.n_followers + 0) =
270 Params.FollowerParam.emission_costs.at(
278 b(0) = Params.FollowerParam.capacities.at(follower);
280 Foll->set(std::move(Q), std::move(C), std::move(A), std::move(B),
281 std::move(c), std::move(b));
290 const unsigned int import_lim_cons,
291 const unsigned int export_lim_cons,
293 const unsigned int price_lim_cons,
323 if (activeTaxCaps > 0) {
327 for (
unsigned int follower = 0; follower < this->taxVars; follower++) {
328 if (Params.FollowerParam.tax_caps.at(follower) >= 0) {
331 LeadRHS(follower) = Params.FollowerParam.tax_caps.at(follower);
337 for (
unsigned int i = 0; i < Params.n_followers; i++)
338 LeadCons.at(Params.n_followers, i) = -1;
343 if (import_lim_cons) {
344 LeadCons(activeTaxCaps + import_lim_cons,
346 LeadCons(activeTaxCaps + import_lim_cons,
348 LeadRHS(activeTaxCaps + import_lim_cons) = Params.LeaderParam.import_limit;
352 if (export_lim_cons) {
353 LeadCons(activeTaxCaps + import_lim_cons + export_lim_cons,
355 LeadCons(activeTaxCaps + import_lim_cons + export_lim_cons,
357 LeadRHS(activeTaxCaps + import_lim_cons + export_lim_cons) =
358 Params.LeaderParam.export_limit;
361 if (price_lim_cons) {
362 for (
unsigned int i = 0; i < Params.n_followers; i++)
363 LeadCons.at(activeTaxCaps + price_lim_cons + import_lim_cons +
365 i) = -Params.DemandParam.beta;
367 activeTaxCaps + price_lim_cons + import_lim_cons + export_lim_cons,
370 activeTaxCaps + price_lim_cons + import_lim_cons + export_lim_cons,
372 LeadRHS.at(activeTaxCaps + price_lim_cons + import_lim_cons +
374 Params.LeaderParam.price_limit - Params.DemandParam.alpha;
377 if (Params.LeaderParam.tax_revenue) {
381 unsigned int standardTax = 1;
382 unsigned int carbonTax = 0;
390 for (
unsigned int i = 0; i < Params.n_followers; i++) {
391 double t_cap = (Params.FollowerParam.tax_caps.at(i * standardTax) >= 0
392 ? Params.FollowerParam.tax_caps.at(i * standardTax)
394 double carbonCorrection =
395 (carbonTax == 1) ? Params.FollowerParam.emission_costs.at(i) : 1;
397 LeadCons.at(activeTaxCaps + price_lim_cons + import_lim_cons +
398 export_lim_cons + i * 3 + 1,
400 LeadCons.at(activeTaxCaps + price_lim_cons + import_lim_cons +
401 export_lim_cons + i * 3 + 1,
403 Params.FollowerParam.capacities.at(i) * carbonCorrection;
404 LeadCons.at(activeTaxCaps + price_lim_cons + import_lim_cons +
405 export_lim_cons + i * 3 + 1,
407 t_cap * carbonCorrection;
408 LeadRHS.at(activeTaxCaps + price_lim_cons + import_lim_cons +
409 export_lim_cons + i * 3 + 1) =
410 t_cap * Params.FollowerParam.capacities.at(i) * carbonCorrection;
413 LeadCons.at(activeTaxCaps + price_lim_cons + import_lim_cons +
414 export_lim_cons + i * 3 + 2,
416 LeadCons.at(activeTaxCaps + price_lim_cons + import_lim_cons +
417 export_lim_cons + i * 3 + 2,
419 Params.FollowerParam.capacities.at(i) * carbonCorrection;
420 LeadRHS.at(activeTaxCaps + price_lim_cons + import_lim_cons +
421 export_lim_cons + i * 3 + 2) = 0;
424 LeadCons.at(activeTaxCaps + price_lim_cons + import_lim_cons +
425 export_lim_cons + i * 3 + 3,
427 LeadCons.at(activeTaxCaps + price_lim_cons + import_lim_cons +
428 export_lim_cons + i * 3 + 3,
430 t_cap * carbonCorrection;
431 LeadRHS.at(activeTaxCaps + price_lim_cons + import_lim_cons +
432 export_lim_cons + i * 3 + 3) = 0;
435 BOOST_LOG_TRIVIAL(trace) <<
"********** Price Limit constraint: " 437 BOOST_LOG_TRIVIAL(trace) <<
"********** Import Limit constraint: " 439 BOOST_LOG_TRIVIAL(trace) <<
"********** Export Limit constraint: " 441 BOOST_LOG_TRIVIAL(trace) <<
"********** Tax Limit constraints: " 442 << activeTaxCaps <<
"\n\t";
446 const unsigned int addnlLeadVars)
487 "Error in Models::EPEC::addCountry: EPEC object finalized. Call " 488 "EPEC::unlock() to unlock this object first and then edit.");
490 bool noError =
false;
492 noError = this->ParamValid(Params);
493 }
catch (
const char *e) {
494 cerr <<
"Error in Models::EPEC::addCountry: " << e <<
'\n';
496 cerr <<
"String: Error in Models::EPEC::addCountry: " << e <<
'\n';
497 }
catch (exception &e) {
498 cerr <<
"Exception: Error in Models::EPEC::addCountry: " << e.what()
507 BOOST_LOG_TRIVIAL(trace)
508 <<
"Country " << Params.
name <<
" has a standard tax paradigm.";
512 BOOST_LOG_TRIVIAL(trace)
513 <<
"Country " << Params.
name <<
" has a single tax paradigm.";
515 BOOST_LOG_TRIVIAL(trace)
516 <<
"Country " << Params.
name <<
" has a carbon tax paradigm.";
521 const unsigned int LeadVars =
537 BOOST_LOG_TRIVIAL(info)
538 <<
"Country " << Params.
name <<
" has tax revenue in the objective.";
543 short int import_lim_cons{0}, export_lim_cons{0}, price_lim_cons{0};
550 unsigned int activeTaxCaps = 0;
556 [](
double i) {
return i >= 0; });
562 [](
double i) {
return i >= 0; });
563 if (activeTaxCaps >= 0) {
567 BOOST_LOG_TRIVIAL(warning)
568 <<
"Tax caps are not equal within a non-standard tax framework. " 569 "Using the first value as tax limit.";
575 arma::sp_mat LeadCons(import_lim_cons +
584 import_lim_cons + export_lim_cons + price_lim_cons + activeTaxCaps +
588 vector<shared_ptr<Game::QP_Param>> Players{};
591 for (
unsigned int follower = 0; follower < Params.
n_followers; follower++) {
592 auto Foll = make_shared<Game::QP_Param>(this->env);
593 this->make_LL_QP(Params, follower, Foll.get(), Loc);
594 Players.push_back(Foll);
597 this->make_LL_LeadCons(LeadCons, LeadRHS, Params, Loc, import_lim_cons,
598 export_lim_cons, price_lim_cons, activeTaxCaps);
599 }
catch (
const char *e) {
603 cerr <<
"String in Models::EPEC::addCountry : " << e <<
'\n';
605 }
catch (GRBException &e) {
606 cerr <<
"GRBException in Models::EPEC::addCountry : " << e.getErrorCode()
607 <<
": " << e.getMessage() <<
'\n';
609 }
catch (exception &e) {
610 cerr <<
"Exception in Models::EPEC::addCountry : " << e.what() <<
'\n';
616 arma::vec MCRHS(0, arma::fill::zeros);
619 auto N = std::make_shared<Game::NashGame>(this->env, Players, MC, MCRHS,
620 LeadVars, LeadCons, LeadRHS);
621 this->name2nos[Params.
name] = this->countries_LL.size();
622 this->countries_LL.push_back(N);
628 this->Locations.push_back(Loc);
630 this->EPEC::LocEnds.push_back(&this->Locations.back().at(LeaderVars::End));
631 this->EPEC::convexHullVariables.push_back(0);
633 this->LeadConses.push_back(N->RewriteLeadCons());
634 this->AllLeadPars.push_back(Params);
640 const arma::sp_mat &costs
651 "Error in Models::EPEC::addTranspCosts: EPEC object finalized. Call " 652 "EPEC::unlock() to unlock this object first and then edit.");
654 if (this->getNcountries() != costs.n_rows ||
655 this->getNcountries() != costs.n_cols)
656 throw string(
"Error in EPEC::addTranspCosts. Invalid size of Q");
658 this->TranspCosts = arma::sp_mat(costs);
659 this->TranspCosts.diag()
661 }
catch (
const char *e) {
665 cerr <<
"String in Models::EPEC::addTranspCosts : " << e <<
'\n';
667 }
catch (GRBException &e) {
668 cerr <<
"GRBException in Models::EPEC::addTranspCosts : " 669 << e.getErrorCode() <<
": " << e.getMessage() <<
'\n';
671 }
catch (exception &e) {
672 cerr <<
"Exception in Models::EPEC::addTranspCosts : " << e.what() <<
'\n';
692 this->nImportMarkets = vector<unsigned int>(this->getNcountries());
693 for (
unsigned int i = 0; i < this->getNcountries(); i++)
694 this->add_Leaders_tradebalance_constraints(i);
695 }
catch (
const char *e) {
699 cerr <<
"String in Models::EPEC::prefinalize : " << e <<
'\n';
701 }
catch (GRBException &e) {
702 cerr <<
"GRBException in Models::EPEC::prefinalize : " << e.getErrorCode()
703 <<
": " << e.getMessage() <<
'\n';
705 }
catch (exception &e) {
706 cerr <<
"Exception in Models::EPEC::prefinalize : " << e.what() <<
'\n';
722 if (i >= this->countries_LL.size())
723 throw string(
"Error in Models::EPEC::add_Leaders_tradebalance_constraints. " 726 LeadLocs &Loc = this->Locations.at(i);
728 for (
auto val = TranspCosts.begin_col(i);
val != TranspCosts.end_col(i);
732 this->nImportMarkets.at(i) = (nImp);
743 a.subvec(Loc.at(LeaderVars::CountryImport),
744 Loc.at(LeaderVars::CountryImport + 1) - 1)
768 if (!this->finalized)
769 throw string(
"Error in Models::EPEC::make_MC_cons: This function can be " 770 "run only AFTER calling finalize()");
772 const arma::sp_mat &TrCo = this->TranspCosts;
774 MCRHS.zeros(this->getNcountries());
775 MCLHS.zeros(this->getNcountries(), this->getnVarinEPEC());
777 if (this->getNcountries() > 1) {
778 for (
unsigned int i = 0; i < this->getNcountries(); ++i) {
779 MCLHS(i, this->getPosition(i, LeaderVars::NetExport)) = 1;
780 for (
auto val = TrCo.begin_row(i);
val != TrCo.end_row(i); ++
val) {
781 const unsigned int j =
783 unsigned int count{0};
785 for (
auto val2 = TrCo.begin_col(j); val2 != TrCo.end_col(j); ++val2)
808 if (i >= this->getNcountries())
809 throw string(
"Error in Models::EPEC::add_Leaders_tradebalance_constraints. " 812 const arma::sp_mat &TrCo = this->TranspCosts;
813 const unsigned int nEPECvars = this->getnVarinEPEC();
814 const unsigned int nThisMCvars = 1;
815 arma::sp_mat C(nThisMCvars, nEPECvars - nThisMCvars);
819 for (
auto val = TrCo.begin_row(i);
val != TrCo.end_row(i); ++
val) {
820 const unsigned int j =
val.col();
822 unsigned int count{0};
824 for (
auto val2 = TrCo.begin_col(j); val2 != TrCo.end_col(j); ++val2)
835 (j >= i ? nThisMCvars : 0)) = 1;
838 this->MC_QP.at(i) = std::make_shared<Game::QP_Param>(this->env);
841 this->MC_QP.at(i).get()->set(arma::sp_mat{1, 1},
843 arma::sp_mat{0, nEPECvars - nThisMCvars},
844 arma::sp_mat{0, nThisMCvars},
848 }
catch (
const char *e) {
852 cerr <<
"String in Models::EPEC::make_MC_leader : " << e <<
'\n';
854 }
catch (GRBException &e) {
855 cerr <<
"GRBException in Models::EPEC::make_MC_leader : " 856 << e.getErrorCode() <<
": " << e.getMessage() <<
'\n';
858 }
catch (exception &e) {
859 cerr <<
"Exception in Models::EPEC::make_MC_leader : " << e.what() <<
'\n';
867 const bool chkcountries_LL,
874 const bool chknImportMarkets,
880 const bool chkLeadObjec
888 if (!chkAllLeadPars && AllLeadPars.size() != this->getNcountries())
890 if (!chkcountries_LL && countries_LL.size() != this->getNcountries())
892 if (!chkMC_QP && MC_QP.size() != this->getNcountries())
894 if (!chkLeadConses && LeadConses.size() != this->getNcountries())
896 if (!chkLeadRHSes && LeadRHSes.size() != this->getNcountries())
898 if (!chknImportMarkets && nImportMarkets.size() != this->getNcountries())
900 if (!chkLocations && Locations.size() != this->getNcountries())
902 if (!chkLeaderLocations && LeaderLocations.size() != this->getNcountries())
904 if (!chkLeaderLocations && this->getnVarinEPEC() == 0)
906 if (!chkLeadObjec && LeadObjec.size() != this->getNcountries())
917 if (countryCount >= this->getNcountries())
918 throw string(
"Error in Models::EPEC::getPosition: Bad Country Count");
919 return this->LeaderLocations.at(countryCount) +
920 this->Locations.at(countryCount).at(var);
930 return this->getPosition(name2nos.at(countryName), var);
939 return this->countries_LL.at(i).get();
951 this->finalized =
false;
965 const unsigned int nEPECvars = this->getnVarinEPEC();
966 const unsigned int nThisCountryvars =
968 const LeadAllPar &Params = this->AllLeadPars.at(i);
969 const arma::sp_mat &TrCo = this->TranspCosts;
970 const LeadLocs &Loc = this->Locations.at(i);
972 QP_obj.
Q.zeros(nThisCountryvars, nThisCountryvars);
973 QP_obj.
c.zeros(nThisCountryvars);
974 QP_obj.
C.zeros(nThisCountryvars, nEPECvars - nThisCountryvars);
983 count < this->taxVars; j++, count++)
987 if (this->getNcountries() > 1) {
995 nThisCountryvars + i) = -1;
998 unsigned int count{0};
999 for (
auto val = TrCo.begin_col(i);
val != TrCo.end_col(i); ++
val, ++count) {
1004 this->getPosition(this->getNcountries() - 1,
1006 nThisCountryvars +
val.row()) = 1;
1014 const arma::vec &x)
const {
1023 for (
unsigned int i = 0; i < this->getNcountries(); ++i) {
1024 LeadLocs &Loc = this->Locations.at(i);
1029 this->convexHullVariables.at(i));
1034 const unsigned int val,
const bool startnext)
1039 LeaderVars start_rl = startnext ? start + 1 : start;
1048 const unsigned int val,
const bool startnext)
1053 LeaderVars start_rl = startnext ? start + 1 : start;
1069 return static_cast<LeaderVars>(
static_cast<int>(a) + b);
1072 string to_string(
const GRBConstr &cons,
const GRBModel &model) {
1073 const GRBVar *vars = model.getVars();
1074 const int nVars = model.get(GRB_IntAttr_NumVars);
1076 oss << cons.get(GRB_StringAttr_ConstrName) <<
":\t\t";
1077 constexpr
double eps = 1e-5;
1079 for (
int i = 0; i < nVars; ++i) {
1080 double coeff = model.getCoeff(cons, vars[i]);
1081 if (abs(coeff) > eps) {
1082 char sign = (coeff > eps) ?
'+' :
' ';
1083 oss << sign << coeff <<
to_string(vars[i]) <<
"\t";
1087 oss << cons.get(GRB_CharAttr_Sense) <<
"\t" << cons.get(GRB_DoubleAttr_RHS);
1092 string name = var.get(GRB_StringAttr_VarName);
1093 return name.empty() ?
"unNamedvar" : name;
1097 bool append)
const {
1099 file.open(filename, append ? ios::app : ios::out);
1100 const LeadAllPar &Params = this->AllLeadPars.at(i);
1101 file <<
"**************************************************\n";
1102 file <<
"COUNTRY: " << Params.
name <<
'\n';
1103 file <<
"- - - - - - - - - - - - - - - - - - - - - - - - - \n";
1105 file <<
"**************************************************\n\n\n\n\n";
1112 file.open(filename, ios::app);
1113 file <<
"\n\n\n\n\n";
1114 file <<
"##################################################\n";
1115 file <<
"############### COUNTRY PARAMETERS ###############\n";
1116 file <<
"##################################################\n";
1118 for (
unsigned int i = 0; i < this->getNcountries(); ++i)
1119 this->write(filename, i, (append || i));
1123 const arma::vec z)
const {
1130 PrettyWriter<StringBuffer> writer(s);
1131 writer.StartObject();
1133 writer.StartObject();
1134 writer.Key(
"isPureEquilibrium");
1135 writer.Bool(this->isPureStrategy());
1136 writer.Key(
"nCountries");
1137 writer.Uint(this->getNcountries());
1138 writer.Key(
"nFollowers");
1139 writer.StartArray();
1140 for (
unsigned i = 0; i < this->getNcountries(); i++)
1141 writer.Uint(this->AllLeadPars.at(i).n_followers);
1143 writer.Key(
"Countries");
1144 writer.StartArray();
1145 for (
unsigned i = 0; i < this->getNcountries(); i++) {
1146 writer.StartObject();
1147 writer.Key(
"FollowerStart");
1149 writer.Key(
"NetImport");
1151 writer.Key(
"NetExport");
1153 writer.Key(
"CountryImport");
1159 if (this->AllLeadPars.at(i).LeaderParam.tax_revenue) {
1160 writer.Key(
"QuadraticTax");
1163 writer.Key(
"DualVar");
1165 writer.Key(
"ConvHullDummy");
1169 writer.Key(
"ShadowPrice");
1177 writer.Key(
"Solution");
1178 writer.StartObject();
1180 writer.StartArray();
1181 for (
unsigned i = 0; i < x.size(); i++)
1182 writer.Double(x.at(i));
1185 writer.StartArray();
1186 for (
unsigned i = 0; i < z.size(); i++)
1187 writer.Double(z.at(i));
1191 ofstream file(filename +
".json");
1192 file << s.GetString();
1199 ifstream ifs(filename +
".json");
1201 IStreamWrapper isw(ifs);
1205 const Value &x = d[
"Solution"].GetObject()[
"x"];
1209 new_x.zeros(x.GetArray().Size());
1212 for (SizeType i = 0; i < this->getnVarinEPEC(); i++)
1213 new_x.at(i) = x[i].GetDouble();
1218 this->warmstart(new_x);
1219 }
catch (exception &e) {
1220 cerr <<
"Exception in Models::readSolutionJSON : cannot read instance " 1222 << e.what() <<
'\n';
1226 <<
"Exception in Models::readSolutionJSON: cannot read instance file." 1231 cerr <<
"Exception in Models::readSolutionJSON : file instance not found." 1244 if (writeLevel == 1 || writeLevel == 2) {
1245 this->WriteCountry(0, filename +
".txt", this->sol_x,
false);
1246 for (
unsigned int ell = 1; ell < this->getNcountries(); ++ell)
1247 this->WriteCountry(ell, filename +
".txt", this->sol_x,
true);
1248 this->write(filename +
".txt",
true);
1250 if (writeLevel == 2 || writeLevel == 0)
1251 this->writeSolutionJSON(filename, this->sol_x, this->sol_z);
1253 cerr <<
"Error in Models::EPEC::writeSolution: no solution to write." 1265 PrettyWriter<StringBuffer> writer(s);
1266 writer.StartObject();
1267 writer.Key(
"nCountries");
1268 writer.Uint(this->Countries.size());
1269 writer.Key(
"Countries");
1270 writer.StartArray();
1271 for (
unsigned i = 0; i < this->Countries.size(); i++) {
1272 writer.StartObject();
1274 writer.Key(
"nFollowers");
1275 writer.Uint(this->Countries.at(i).n_followers);
1278 string currName = this->Countries.at(i).name;
1279 char nameArray[currName.length() + 1];
1280 strcpy(nameArray, currName.c_str());
1281 writer.String(nameArray);
1283 writer.Key(
"DemandParam");
1284 writer.StartObject();
1285 writer.Key(
"Alpha");
1286 writer.Double(this->Countries.at(i).DemandParam.alpha);
1288 writer.Double(this->Countries.at(i).DemandParam.beta);
1291 writer.Key(
"TransportationCosts");
1292 writer.StartArray();
1293 for (
unsigned j = 0; j < this->Countries.size(); j++)
1294 writer.Double(this->TransportationCosts(i, j));
1297 writer.Key(
"LeaderParam");
1298 writer.StartObject();
1299 writer.Key(
"ImportLimit");
1300 writer.Double(this->Countries.at(i).LeaderParam.import_limit);
1301 writer.Key(
"ExportLimit");
1302 writer.Double(this->Countries.at(i).LeaderParam.export_limit);
1303 writer.Key(
"PriceLimit");
1304 writer.Double(this->Countries.at(i).LeaderParam.price_limit);
1305 writer.Key(
"TaxRevenue");
1306 writer.Bool(this->Countries.at(i).LeaderParam.tax_revenue);
1307 writer.Key(
"TaxationType");
1308 switch (this->Countries.at(i).LeaderParam.tax_type) {
1320 writer.Key(
"Followers");
1321 writer.StartObject();
1323 writer.Key(
"Names");
1324 writer.StartArray();
1325 for (
unsigned j = 0; j < this->Countries.at(i).n_followers; j++) {
1326 string currName = this->Countries.at(i).FollowerParam.names.at(j);
1327 char nameArray[currName.length() + 1];
1328 strcpy(nameArray, currName.c_str());
1329 writer.String(nameArray);
1333 writer.Key(
"Capacities");
1334 writer.StartArray();
1335 for (
unsigned j = 0; j < this->Countries.at(i).n_followers; j++)
1336 writer.Double(this->Countries.at(i).FollowerParam.capacities.at(j));
1339 writer.Key(
"LinearCosts");
1340 writer.StartArray();
1341 for (
unsigned j = 0; j < this->Countries.at(i).n_followers; j++)
1342 writer.Double(this->Countries.at(i).FollowerParam.costs_lin.at(j));
1345 writer.Key(
"QuadraticCosts");
1346 writer.StartArray();
1347 for (
unsigned j = 0; j < this->Countries.at(i).n_followers; j++)
1348 writer.Double(this->Countries.at(i).FollowerParam.costs_quad.at(j));
1351 writer.Key(
"EmissionCosts");
1352 writer.StartArray();
1353 for (
unsigned j = 0; j < this->Countries.at(i).n_followers; j++)
1354 writer.Double(this->Countries.at(i).FollowerParam.emission_costs.at(j));
1357 writer.Key(
"TaxCaps");
1358 writer.StartArray();
1359 for (
unsigned j = 0; j < this->Countries.at(i).n_followers; j++)
1360 writer.Double(this->Countries.at(i).FollowerParam.tax_caps.at(j));
1369 ofstream file(filename +
".json");
1370 file << s.GetString();
1380 ifstream ifs(filename +
".json");
1382 IStreamWrapper isw(ifs);
1386 vector<Models::LeadAllPar> LAP = {};
1387 int nCountries = d[
"nCountries"].GetInt();
1389 TrCo.zeros(nCountries, nCountries);
1390 for (
int j = 0; j < nCountries; ++j) {
1391 const Value &c = d[
"Countries"].GetArray()[j].GetObject();
1394 const Value &cap = c[
"Followers"][
"Capacities"];
1395 for (SizeType i = 0; i < cap.GetArray().Size(); i++) {
1398 const Value &lc = c[
"Followers"][
"LinearCosts"];
1399 for (SizeType i = 0; i < lc.GetArray().Size(); i++) {
1400 FP.
costs_lin.push_back(lc[i].GetDouble());
1402 const Value &qc = c[
"Followers"][
"QuadraticCosts"];
1403 for (SizeType i = 0; i < qc.GetArray().Size(); i++) {
1406 const Value &ec = c[
"Followers"][
"EmissionCosts"];
1407 for (SizeType i = 0; i < ec.GetArray().Size(); i++) {
1410 const Value &tc = c[
"Followers"][
"TaxCaps"];
1411 for (SizeType i = 0; i < tc.GetArray().Size(); i++) {
1412 FP.
tax_caps.push_back(tc[i].GetDouble());
1414 const Value &nm = c[
"Followers"][
"Names"];
1415 for (SizeType i = 0; i < nm.GetArray().Size(); i++) {
1416 FP.
names.push_back(nm[i].GetString());
1418 for (SizeType i = 0; i < c[
"TransportationCosts"].GetArray().Size();
1420 TrCo.at(j, i) = c[
"TransportationCosts"].GetArray()[i].GetDouble();
1422 bool tax_revenue =
false;
1423 if (c[
"LeaderParam"].HasMember(
"TaxRevenue")) {
1424 tax_revenue = c[
"LeaderParam"].GetObject()[
"TaxRevenue"].GetBool();
1426 unsigned int tax_type = 0;
1427 if (c[
"LeaderParam"].HasMember(
"TaxationType")) {
1428 tax_type = c[
"LeaderParam"].GetObject()[
"TaxationType"].GetInt();
1431 FP.
capacities.size(), c[
"Name"].GetString(), FP,
1432 {c[
"DemandParam"].GetObject()[
"Alpha"].GetDouble(),
1433 c[
"DemandParam"].GetObject()[
"Beta"].GetDouble()},
1434 {c[
"LeaderParam"].GetObject()[
"ImportLimit"].GetDouble(),
1435 c[
"LeaderParam"].GetObject()[
"ExportLimit"].GetDouble(),
1436 c[
"LeaderParam"].GetObject()[
"PriceLimit"].GetDouble(),
1437 tax_revenue, tax_type}));
1440 this->Countries = LAP;
1441 this->TransportationCosts = TrCo;
1442 }
catch (exception &e) {
1443 cerr <<
"Exception in Models::load : cannot read instance file." 1444 << e.what() <<
'\n';
1447 cerr <<
"Exception in Models::load : cannot read instance file." <<
'\n';
1451 cerr <<
"Exception in Models::load : file instance not found." <<
'\n';
1457 const arma::vec x,
const bool append)
const {
1462 file.open(filename, append ? ios::app : ios::out);
1464 const LeadAllPar &Params = this->AllLeadPars.at(i);
1465 file <<
"**************************************************\n";
1466 file <<
"COUNTRY: " << Params.
name <<
'\n';
1467 file <<
"**************************************************\n\n";
1469 unsigned int foll_prod;
1473 for (
unsigned int j = 0; j < Params.
n_followers; ++j)
1474 prod += x.at(foll_prod + j);
1477 double exportPrice{x.at(
1485 file <<
"PureStrategy:" << this->isPureStrategy(i) <<
"\n";
1486 file << Models::prn::label <<
"Domestic production" 1488 if (Export >=
import)
1489 file << Models::prn::label <<
"Net exports" 1492 file << Models::prn::label <<
"Net imports" 1494 file << Models::prn::label <<
"Export price" 1496 file << Models::prn::label <<
" -> Total Export" 1498 file << Models::prn::label <<
" -> Total Import" 1500 file << Models::prn::label <<
"Domestic consumed quantity" 1501 <<
":" << Models::prn::val <<
import - Export + prod <<
"\n";
1502 file << Models::prn::label <<
"Domestic price" 1503 <<
":" << Models::prn::val
1511 file <<
"- - - - - - - - - - - - - - - - - - - - - - - - - \n";
1512 file <<
"FOLLOWER DETAILS:\n";
1513 for (
unsigned int j = 0; j < Params.
n_followers; ++j)
1514 this->WriteFollower(i, j, filename, x);
1521 const string filename,
1522 const arma::vec x)
const {
1524 file.open(filename, ios::app);
1527 const LeadAllPar &Params = this->AllLeadPars.at(i);
1528 unsigned int foll_prod, foll_tax, foll_lim, foll_taxQ;
1546 tax = x.at(foll_tax + j);
1548 tax = x.at(foll_tax);
1549 const double q = x.at(foll_prod + j);
1552 taxQ = q > 0 ? x.at(foll_taxQ + j) / q : x.at(foll_taxQ + j);
1553 const double lim = x.at(foll_lim + j);
1557 file << Models::prn::label <<
"Quantity produced" 1560 file << Models::prn::label <<
"Capacity of production" 1563 file << Models::prn::label <<
"Limit on production" 1566 file << Models::prn::label <<
"Tax imposed" 1570 file <<
" per unit emission; " << tax <<
" per unit energy";
1574 file << Models::prn::label <<
"Tax imposed (Q)" 1579 file << Models::prn::label <<
" -Production cost function" 1581 <<
"\t C(q) = (" << lin <<
" + " << tax <<
")*q + 0.5*" << quad
1583 << Models::prn::label <<
" " 1586 file << Models::prn::label <<
" -Marginal cost of production" 1588 file << Models::prn::label <<
"Emission cost" 1596 auto country = this->get_LowerLevelNash(i);
1597 LCP CountryLCP(this->env, *country);
1599 auto model = CountryLCP.
LCPasMIP(
true);
1600 model->write(
"dat/CountryLCP_" +
to_string(i) +
".lp");
1601 model->write(
"dat/CountryLCP_" +
to_string(i) +
".sol");
Models::FollPar operator+(const Models::FollPar &F1, const Models::FollPar &F2)
Stores the parameters of the follower in a country model.
Class to handle parameterized quadratic programs(QP)
string to_string(const GRBConstr &cons, const GRBModel &model)
void make_MC_cons(arma::sp_mat &MCLHS, arma::vec &MCRHS) const override
Returns leader's Market clearing constraints in matrix form.
void make_MC_leader(const unsigned int i)
Makes the market clearing constraint for country i.
unsigned int n_followers
Number of followers in the country.
void WriteFollower(const unsigned int i, const unsigned int j, const std::string filename, const arma::vec x) const
void writeSolution(const int writeLevel, std::string filename) const
std::vector< Models::LeadAllPar > Countries
LeadAllPar vector.
double price_limit
Government does not want the price to exceed this limit.
void write(std::string filename, bool append=true) const
std::vector< double > costs_lin
bool dataCheck(const bool chkAllLeadPars=true, const bool chkcountriesLL=true, const bool chkMC_QP=true, const bool chkLeadConses=true, const bool chkLeadRHSes=true, const bool chknImportMarkets=true, const bool chkLocations=true, const bool chkLeaderLocations=true, const bool chkLeadObjec=true) const
struct LeadAllPar LeadAllPar
Stores the parameters of the leader in a country model.
void testLCP(const unsigned int i)
unsigned int getPosition(const unsigned int countryCount, const LeaderVars var=LeaderVars::FollowerStart) const
Gets position of a variable in a country.
Models::DemPar DemandParam
A struct to hold Demand Parameters.
std::map< LeaderVars, unsigned int > LeadLocs
void make_LL_LeadCons(arma::sp_mat &LeadCons, arma::vec &LeadRHS, const LeadAllPar &Param, const Models::LeadLocs &Loc={}, const unsigned int import_lim_cons=1, const unsigned int export_lim_cons=1, const unsigned int price_lim_cons=1, const unsigned int activeTaxCaps=0) const noexcept
Makes the leader constraint matrix and RHS.
EPEC & unlock()
Unlocks an EPEC model.
std::vector< double > costs_quad
Stores the parameters of a country model.
void writeSolutionJSON(std::string filename, const arma::vec x, const arma::vec z) const
void increaseVal(LeadLocs &L, const LeaderVars start, const unsigned int val, const bool startnext=true)
std::vector< double > capacities
unsigned int getNduals() const
Gets the number of dual variables in the problem.
std::vector< double > tax_caps
Individual tax caps for each follower.
void load(std::string filename)
Reads the EPECInstance from a file.
std::string name
Country Name.
arma::sp_mat TransportationCosts
Transportation costs matrix.
Models::LeadPar LeaderParam
A struct to hold Leader Parameters.
void decreaseVal(LeadLocs &L, const LeaderVars start, const unsigned int val, const bool startnext=true)
Models::FollPar FollowerParam
A struct to hold Follower Parameters.
Stores a single Instance.
Class to handle and solve linear complementarity problems.
Solution found for the instance.
void WriteCountry(const unsigned int i, const std::string filename, const arma::vec x, const bool append=true) const
std::vector< std::string > names
Optional Names for the Followers.
std::unique_ptr< GRBModel > Respond(const std::string name, const arma::vec &x) const
std::unique_ptr< GRBModel > LCPasMIP(std::vector< unsigned int > FixEq={}, std::vector< unsigned int > FixVar={}, bool solve=false)
virtual void updateLocs() override
EPEC & addTranspCosts(const arma::sp_mat &costs)
Adds intercountry transportation costs matrix.
void add_Leaders_tradebalance_constraints(const unsigned int i)
Adds leaders' trade balance constraints for import-exports.
void make_obj_leader(const unsigned int i, Game::QP_objective &QP_obj) final
void readSolutionJSON(const std::string filename)
std::unique_ptr< GRBModel > Respond(const unsigned int i, const arma::vec &x) const
LeaderVars operator+(Models::LeaderVars a, int b)
struct to handle the objective params of MP_Param/QP_Param
NashGame & addDummy(unsigned int par=0, int position=-1)
Add dummy variables in a NashGame object.
Game::NashGame * get_LowerLevelNash(const unsigned int i) const
Returns a non-owning pointer to the i -th country's lower level NashGame.
bool ParamValid(const LeadAllPar &Param) const
Checks the Validity of Models::LeadAllPar object.
void make_LL_QP(const LeadAllPar &Params, const unsigned int follower, Game::QP_Param *Foll, const LeadLocs &Loc) const noexcept
Makes the lower level quadratic program object for each follower.
std::vector< double > emission_costs
void save(std::string filename)
Writes the EPECInstance from a file.
Stores the parameters of the demand curve in a country model.
Class to model Nash-cournot games with each player playing a QP.
NashGame & addLeadCons(const arma::vec &a, double b)
Adds Leader constraint to a NashGame object.
void write(const std::string filename, const unsigned int i, bool append=true) const
EPEC & addCountry(LeadAllPar Params, const unsigned int addnlLeadVars=0)
Models a Standard Nash-Cournot game within a country
std::ostream & operator<<(std::ostream &ost, const FollPar P)
virtual void prefinalize() override
Empty function - optionally reimplementable in derived class.