diff --git a/CHANGES.mp.md b/CHANGES.mp.md index bbe4dacc8..1a8d2345a 100644 --- a/CHANGES.mp.md +++ b/CHANGES.mp.md @@ -3,6 +3,8 @@ Summary of recent updates to the AMPL MP Library ## unreleased +- Option tech:writemodel:index to choose the iteration + when solver model is exported. - SCIP (and any solver with linear objective and non-linear constraints): improve reformulation of QP objectives. diff --git a/include/mp/backend-std.h b/include/mp/backend-std.h index 094f93735..5174ce48d 100644 --- a/include/mp/backend-std.h +++ b/include/mp/backend-std.h @@ -173,7 +173,7 @@ class StdBackend : /// Redefine this if you want some extensions /// to be written after solving instead. /// This is for compatibility wiht ASL drivers - /// where 'writeprob' was used for native-format model + /// where 'writeprob' was used both for native-format model /// and solution output #218. virtual std::set NativeResultExtensions() const { return {".sol", ".ilp", ".mst", ".hnt", ".bas", ".json"}; } @@ -276,9 +276,11 @@ class StdBackend : auto get_sol = [this]() { return GetSolution(); }; - int i=0; + int i_solve=0; while (GetMM().PrepareSolveIteration(get_stt, get_sol)) { - // ExportModel({"/tmp/model" + std::to_string(++i) + ".lp"}); + if (++i_solve==storedOptions_.writemodel_index_ + && exportFileMode() > 0) + ExportModel(export_file_names()); Solve(); } } @@ -808,6 +810,7 @@ class StdBackend : /// For write prob std::vector export_files_; + int writemodel_index_ = 0; std::vector just_export_files_; /// For write sol std::vector export_sol_files_; @@ -936,12 +939,22 @@ class StdBackend : } if (IMPL_HAS_STD_FEATURE(WRITE_PROBLEM)) { - AddListOption("tech:writemodel writeprob writemodel tech:exportfile", + AddListOption("tech:writemodel tech:writeprob writeprob writemodel tech:exportfile", "Specifies files where to export the model before " "solving (repeat the option for several files.) " - "File name extensions can be ``.lp[.7z]``, ``.mps``, etc.", + "File name extensions can be ``.lp[.7z]``, ``.mps``, etc." + "\n" + "To write a model during iterative solve (e.g., with obj:multi=2), " + "use tech:writemodel:index.", storedOptions_.export_files_); + AddStoredOption("tech:writemodel:index tech:writeprob:index writeprobindex writemodelindex", + "During iterative solve (e.g., with obj:multi=2), " + "the iteration before which to write solver model. " + "0 means before iteration is initialized; positive value - " + "before solving that iteration. Default 0.", + storedOptions_.writemodel_index_); + AddListOption("tech:writemodelonly justwriteprob justwritemodel", "Specifies files where to export the model, no solving " "(option can be repeated.) " diff --git a/include/mp/flat/constr_2_expr.h b/include/mp/flat/constr_2_expr.h index 8c7b929de..bcccd2479 100644 --- a/include/mp/flat/constr_2_expr.h +++ b/include/mp/flat/constr_2_expr.h @@ -415,11 +415,15 @@ class Constraints2Expr { lt_out_vars.reserve(nvars); result.reserve(ltin.size() - nvars); int v=0; + double c=0.0; for (size_t i=0; i x0, ArrayRef sparsity) { SCIP_CCALL( SCIPaddSolFree(getSCIP(), &solution, &keep) ); } +void ScipBackend::DoWriteProblem(const std::string& name) { + ExportModel(name); +} } // namespace mp diff --git a/solvers/scipmp/scipmpbackend.h b/solvers/scipmp/scipmpbackend.h index 46b93d17c..e1bc9a601 100644 --- a/solvers/scipmp/scipmpbackend.h +++ b/solvers/scipmp/scipmpbackend.h @@ -81,6 +81,12 @@ class ScipBackend : void AddMIPStart(ArrayRef x0, ArrayRef sparsity) override; + /** + * EXPORT PROBLEM + **/ + ALLOW_STD_FEATURE(WRITE_PROBLEM, true) + void DoWriteProblem(const std::string& name) override; + /** * Get MIP Gap @@ -157,7 +163,7 @@ class ScipBackend : private: /// These options are stored in the class struct Options { - std::string exportFile_, logFile_, paramRead_; + std::string logFile_, paramRead_; int concurrent_ = 0; int heuristics_ = 0; int cuts_ = 0; diff --git a/test/end2end/cases/categorized/fast/multi_obj/modellist.json b/test/end2end/cases/categorized/fast/multi_obj/modellist.json index b77ef0ab8..0ff8e2043 100644 --- a/test/end2end/cases/categorized/fast/multi_obj/modellist.json +++ b/test/end2end/cases/categorized/fast/multi_obj/modellist.json @@ -260,6 +260,20 @@ "_sobj[2]": -17 } }, + { + "name" : "obj_abs_01 obj:multi=2 writeprobindex", + "tags" : ["linear", "integer", "multiobj"], + "options": { + "ANYSOLVER_options": "multiobj=2 writeprob=obj_abs_01.lp writeprobindex=2", + "scip_options": "multiobj=2 writeprob=obj_abs_01.cip writeprobindex=2", + "gcg_options": "multiobj=2 writeprob=obj_abs_01.lp writeprobindex=2", + "mosek_options": "multiobj=2 writeprob=obj_abs_01.jtask writeprobindex=2" + }, + "values": { + "_sobj[1]": 13, + "_sobj[2]": -17 + } + }, { "name" : "obj_abs_02", "tags" : ["linear", "integer", "multiobj"],