Skip to content

Commit

Permalink
[ANT-1224] Preparing loop around benders solver (#739)
Browse files Browse the repository at this point in the history
steps:
- [x] create a storage struct for cuts data
- [x] interface and its implementation(s) to save cuts data
- [x] re-use cuts 
- [x] external loop criterion check
- [x] add external loop constraint
- [x] add "mathematical" logs for external loop (think about data to
print)
- [x] improve operational logs with external loop 
- [x] Computation of initial lambda_max by solving investment free
problem + check criterion -> raise warning / exception if not satisfied
at this point
- [ ] Handle infeasibility / errors / ...
- [x] Write test
#706
  • Loading branch information
a-zakir authored Mar 18, 2024
1 parent 63a47c9 commit 12bf8f6
Show file tree
Hide file tree
Showing 66 changed files with 1,991 additions and 323 deletions.
4 changes: 4 additions & 0 deletions data_test/external_loop_test/expansion/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore
17 changes: 17 additions & 0 deletions data_test/external_loop_test/lp/master.mps
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
* Generated by MPModelProtoExporter
* Name :
* Format : Free
* Constraints : 0
* Variables : 1
* Binary : 0
* Integer : 0
* Continuous : 1
NAME
ROWS
N COST
COLUMNS
G_p_max_0_0 COST 20
RHS
BOUNDS
UP BOUND G_p_max_0_0 10
ENDATA
5 changes: 5 additions & 0 deletions data_test/external_loop_test/lp/master_last_basis.bss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
NAME
LL G_p_max_0_0 0
XU alpha R1 19 0
XL alpha_0 R2 19 -19
ENDATA
29 changes: 29 additions & 0 deletions data_test/external_loop_test/lp/options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"MAX_ITERATIONS": -1,
"ABSOLUTE_GAP": 1e-04,
"RELATIVE_GAP": 1e-06,
"RELAXED_GAP": 1e-05,
"AGGREGATION": false,
"OUTPUTROOT": "data_test/external_loop_test/lp/",
"TRACE": true,
"SLAVE_WEIGHT": "CONSTANT",
"SLAVE_WEIGHT_VALUE": 3,
"MASTER_NAME": "master",
"STRUCTURE_FILE": "data_test/external_loop_test/lp/structure.txt",
"INPUTROOT": "data_test/external_loop_test/lp/",
"CSV_NAME": "benders_output_trace",
"BOUND_ALPHA": true,
"SEPARATION_PARAM": 0.5,
"BATCH_SIZE": 0,
"JSON_FILE":"data_test/external_loop_test/expansion/out.json",
"LAST_ITERATION_JSON_FILE":"data_test/external_loop_test/expansion/last_iteration.json",
"MASTER_FORMULATION": "integer",
"SOLVER_NAME": "XPRESS",
"TIME_LIMIT": 1000000000000.0,
"LOG_LEVEL": 1,
"LAST_MASTER_MPS": "master_last_iteration",
"LAST_MASTER_BASIS": "master_last_basis.bss",
"EXT_LOOP_CRITERION_VALUE": 3.0,
"EXT_LOOP_CRITERION_TOLERANCE": 1e-1,
"EXT_LOOP_CRITERION_COUNT_THRESHOLD": 1e-1
}
2 changes: 2 additions & 0 deletions data_test/external_loop_test/lp/structure.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
master G_p_max_0_0 0
subproblem.mps G_p_max_0_0 24
88 changes: 88 additions & 0 deletions data_test/external_loop_test/lp/subproblem.mps
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
* Generated by MPModelProtoExporter
* Name :
* Format : Free
* Constraints : 10
* Variables : 25
* Binary : 0
* Integer : 0
* Continuous : 25
NAME
ROWS
N COST
E N0_Balance
E N0_Balance_1
E N1_Balance
E N1_Balance_2
E N2_Balance
E N2_Balance_3
E N3_Balance
E N3_Balance_4
L G_Max_generation
L G_Max_generation_5
COLUMNS
N0_NegativeUnsuppliedEnergy_0_0 COST 0.5 N0_Balance -1
N0_NegativeUnsuppliedEnergy_0_1 COST 0.5 N0_Balance_1 -1
PositiveUnsuppliedEnergy::N0::0::0 COST 5 N0_Balance 1
PositiveUnsuppliedEnergy::N0::0::1 COST 5 N0_Balance_1 1
N1_NegativeUnsuppliedEnergy_0_0 COST 0.5 N1_Balance -1
N1_NegativeUnsuppliedEnergy_0_1 COST 0.5 N1_Balance_2 -1
PositiveUnsuppliedEnergy::N1::0::0 COST 5 N1_Balance 1
PositiveUnsuppliedEnergy::N1::0::1 COST 5 N1_Balance_2 1
N2_NegativeUnsuppliedEnergy_0_0 COST 0.5 N2_Balance -1
N2_NegativeUnsuppliedEnergy_0_1 COST 0.5 N2_Balance_3 -1
PositiveUnsuppliedEnergy::N2::0::0 COST 5 N2_Balance 1
PositiveUnsuppliedEnergy::N2::0::1 COST 5 N2_Balance_3 1
N3_NegativeUnsuppliedEnergy_0_0 COST 0.5 N3_Balance -1
N3_NegativeUnsuppliedEnergy_0_1 COST 0.5 N3_Balance_4 -1
PositiveUnsuppliedEnergy::N3::0::0 COST 5 N3_Balance 1
PositiveUnsuppliedEnergy::N3::0::1 COST 5 N3_Balance_4 1
L01_flow_0_0 COST 1 N0_Balance -1
L01_flow_0_0 N1_Balance 1
L01_flow_0_1 COST 1 N0_Balance_1 -1
L01_flow_0_1 N1_Balance_2 1
L02_flow_0_0 COST 0.5 N0_Balance -1
L02_flow_0_0 N2_Balance 1
L02_flow_0_1 COST 0.5 N0_Balance_1 -1
L02_flow_0_1 N2_Balance_3 1
L03_flow_0_0 COST 1.5 N0_Balance -1
L03_flow_0_0 N3_Balance 1
L03_flow_0_1 COST 1.5 N0_Balance_1 -1
L03_flow_0_1 N3_Balance_4 1
G_generation_0_0 COST 0.5 N0_Balance 1
G_generation_0_0 G_Max_generation 1
G_generation_0_1 COST 0.5 N0_Balance_1 1
G_generation_0_1 G_Max_generation_5 1
G_p_max_0_0 G_Max_generation -1 G_Max_generation_5 -1
RHS
RHS N0_Balance 0 N0_Balance_1 0
RHS N1_Balance 1 N1_Balance_2 3
RHS N2_Balance 3 N2_Balance_3 3
RHS N3_Balance 0 N3_Balance_4 3
RHS G_Max_generation 1 G_Max_generation_5 1
BOUNDS
PL BOUND N0_NegativeUnsuppliedEnergy_0_0
PL BOUND N0_NegativeUnsuppliedEnergy_0_1
PL BOUND PositiveUnsuppliedEnergy::N0::0::0
PL BOUND PositiveUnsuppliedEnergy::N0::0::1
PL BOUND N1_NegativeUnsuppliedEnergy_0_0
PL BOUND N1_NegativeUnsuppliedEnergy_0_1
PL BOUND PositiveUnsuppliedEnergy::N1::0::0
PL BOUND PositiveUnsuppliedEnergy::N1::0::1
PL BOUND N2_NegativeUnsuppliedEnergy_0_0
PL BOUND N2_NegativeUnsuppliedEnergy_0_1
PL BOUND PositiveUnsuppliedEnergy::N2::0::0
PL BOUND PositiveUnsuppliedEnergy::N2::0::1
PL BOUND N3_NegativeUnsuppliedEnergy_0_0
PL BOUND N3_NegativeUnsuppliedEnergy_0_1
PL BOUND PositiveUnsuppliedEnergy::N3::0::0
PL BOUND PositiveUnsuppliedEnergy::N3::0::1
UP BOUND L01_flow_0_0 100
UP BOUND L01_flow_0_1 100
UP BOUND L02_flow_0_0 100
UP BOUND L02_flow_0_1 100
UP BOUND L03_flow_0_0 100
UP BOUND L03_flow_0_1 100
PL BOUND G_generation_0_0
PL BOUND G_generation_0_1
UP BOUND G_p_max_0_0 10
ENDATA
1 change: 1 addition & 0 deletions src/cpp/benders/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/benders_core")
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/logger")
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/benders_sequential")
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/benders_by_batch")
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/external_loop")


add_subdirectory ("${CMAKE_CURRENT_SOURCE_DIR}/benders_mpi")
Expand Down
24 changes: 13 additions & 11 deletions src/cpp/benders/benders_by_batch/BendersByBatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ void BendersByBatch::InitializeProblems() {
problem_count++;
}
}
init_problems_ = false;
}
void BendersByBatch::BroadcastSingleSubpbCostsUnderApprox() {
DblVector single_subpb_costs_under_approx(_data.nsubproblem);
Expand All @@ -57,7 +58,13 @@ void BendersByBatch::BroadcastSingleSubpbCostsUnderApprox() {
SetAlpha_i(single_subpb_costs_under_approx);
}
void BendersByBatch::Run() {
PreRunInitialization();
if (init_data_) {
PreRunInitialization();
} else {
// only ?
_data.stop = false;
}

MasterLoop();
if (Rank() == rank_0) {
compute_ub();
Expand Down Expand Up @@ -94,11 +101,7 @@ void BendersByBatch::MasterLoop() {
remaining_epsilon_ = Gap();

if (Rank() == rank_0) {
_logger->display_message(
" _______________________________________________________________"
"_"
"________");
_logger->display_message("/");
_logger->PrintIterationSeparatorBegin();

_logger->display_message("\tSolving master...");
get_master_value();
Expand Down Expand Up @@ -127,9 +130,7 @@ void BendersByBatch::MasterLoop() {
_logger->LogSubproblemsSolvingCumulativeCpuTime(
GetSubproblemsCumulativeCpuTime());
_logger->LogSubproblemsSolvingWalltime(GetSubproblemsWalltime());
_logger->display_message(
"\\________________________________________________________________"
"________");
_logger->PrintIterationSeparatorEnd();
mathLoggerDriver_->Print(_data);
}
}
Expand Down Expand Up @@ -234,8 +235,9 @@ void BendersByBatch::BuildCut(
misprice_ = global_misprice;
Gather(subproblem_data_map, gathered_subproblem_map, rank_0);
SetSubproblemsWalltime(subproblems_timer_per_proc.elapsed());

for (const auto &subproblem_map : gathered_subproblem_map) {
for (auto &&[_, subproblem_data] : subproblem_map) {
for (auto &&[sub_problem_name, subproblem_data] : subproblem_map) {
SetSubproblemCost(GetSubproblemCost() + subproblem_data.subproblem_cost);
BoundSimplexIterations(subproblem_data.simplex_iter);
}
Expand Down Expand Up @@ -264,7 +266,7 @@ void BendersByBatch::GetSubproblemCut(
if (std::find(batch_sub_problems.cbegin(), batch_sub_problems.cend(),
name) != batch_sub_problems.cend()) {
Timer subproblem_timer;
SubProblemData subproblem_data;
PlainData::SubProblemData subproblem_data;
worker->fix_to(_data.x_cut);
worker->solve(subproblem_data.lpstatus, Options().OUTPUTROOT,
Options().LAST_MASTER_MPS + MPS_SUFFIX, _writer);
Expand Down
Loading

0 comments on commit 12bf8f6

Please sign in to comment.