Commit 5d350514 authored by jonasseidel's avatar jonasseidel

major new features of custom benders impl conshdlrs incl. new separation...

major new features of custom benders impl conshdlrs incl. new separation routine / restructure computational types
parent 724237f3
#ifndef NMP_BULKSEPA_CONSHDLR_H
#include <vector>
#include <iostream>
#include <map>
#include <scip/scip.h>
#include <scip/scipdefplugins.h>
struct container{
SCIP* basic_scip;
SCIP_SOL* opt;
std::map<SCIP_VAR*, SCIP_VAR*> trans;
SCIP_SOL* transopt;
};
extern "C"{
SCIP_RETCODE SCIPincludeConshdlrNMPBenders(
SCIP_RETCODE SCIPincludeConshdlrNMPBendersLP(
SCIP* scip,
SCIP** benders_separators_lpsol,
SCIP** benders_separators_heursol,
int nepochs,
int nedges,
SCIP_SOL* sol
);
SCIP_RETCODE SCIPincludeConshdlrNMPBendersBranch(
SCIP* scip,
SCIP** benders_separators_lpsol,
SCIP** benders_separators_heursol,
int nepochs,
container* c
int nedges
);
}
......
......@@ -6,29 +6,13 @@ struct SCIP_VarData{
SCIP_VAR** vars_of_repr_edge;
};
SCIP_RETCODE delete_trans_info(SCIP* scip, SCIP_PROBDATA** probdata){
assert(scip != NULL);
SCIPprintTransProblem(scip, NULL, NULL, FALSE);
return SCIP_OKAY;
}
SCIP_RETCODE exit_solve(SCIP* scip, SCIP_PROBDATA* probdata, SCIP_Bool restart){
assert(scip != NULL);
SCIPprintTransProblem(scip, NULL, NULL, FALSE);
return SCIP_OKAY;
}
SCIP* Maintenance_Problem::nmp_generate_benders(){
SCIP* nmp_generate_benders(Maintenance_Problem& mp){
// Master Problem:
SCIP* master;
SCIP_CALL_ABORT( SCIPcreate(&master));
SCIP_CALL_ABORT( SCIPincludeDefaultPlugins(master));
SCIP_CALL_ABORT( SCIPcreateProbBasic(master, "-1"));
SCIP_CALL_ABORT( SCIPsetProbDeltrans(master, delete_trans_info) );
SCIP_CALL_ABORT( SCIPsetProbExitsol (master, exit_solve));
SCIP_CALL_ABORT( SCIPsetObjsense(master, SCIP_OBJSENSE_MAXIMIZE));
SCIP_CALL_ABORT( SCIPsetIntParam(master, "presolving/maxrestarts",0) );
......@@ -37,7 +21,7 @@ SCIP* Maintenance_Problem::nmp_generate_benders(){
std::cout << "generating MP variables" << std::endl;
std::unordered_map<Variable*, SCIP_VAR*> mp_variable_lookup;
for(auto pair : Linear_Program::polyeder().variables()){
for(auto pair : mp.polyeder().variables()){
Variable* curr_var = pair.left;
// only decision variables and lower bound on flow enters the mp:
if(curr_var->description().find("Selected") != std::string::npos){
......@@ -46,20 +30,22 @@ SCIP* Maintenance_Problem::nmp_generate_benders(){
SCIP_CALL_ABORT( SCIPaddVar(master, computational_var));
}else if(curr_var->description().find("target_variable") != std::string::npos){
SCIP_VAR* computational_var = curr_var->computational_var(master, 1);
SCIP_CONS* remove;
SCIPcreateConsBasicLinear(master, &remove, "aritficial_bound", 0, NULL, NULL, 0, 50000);
SCIPaddCoefLinear(master, remove, computational_var, 1);
mp_variable_lookup.insert({curr_var, computational_var});
SCIP_CALL_ABORT( SCIPaddVar(master, computational_var));
SCIP_CONS* remove;
SCIPcreateConsBasicLinear(master, &remove, "aritficial_bound", 0, NULL, NULL, 0, 5000);
SCIPaddCoefLinear(master, remove, computational_var, 1);
SCIPaddCons(master, remove);
}
}
// subproblems:
SCIP** subproblems;
SCIP_CALL_ABORT( SCIPallocBufferArray(master, &subproblems, this->_number_of_epochs));
SCIP_CALL_ABORT( SCIPallocBufferArray(master, &subproblems, mp.number_of_epochs()));
std::vector<std::unordered_map<Variable*, SCIP_VAR*>> subproblem_variable_lookups;
subproblem_variable_lookups.reserve(this->_number_of_epochs);
for(int index = 0; index < this->_number_of_epochs; index++){
subproblem_variable_lookups.reserve(mp.number_of_epochs());
for(int index = 0; index < mp.number_of_epochs(); index++){
subproblem_variable_lookups.push_back(std::unordered_map<Variable*, SCIP_VAR*>());
SCIP_CALL_ABORT( SCIPcreate(&subproblems[index]));
......@@ -73,18 +59,18 @@ SCIP* Maintenance_Problem::nmp_generate_benders(){
std::cout << "generating subproblem_" << index << "'s variables" << std::endl;
std::stringstream curr_epoch;
curr_epoch << "epoch_" << index;
for(auto pair : Linear_Program::polyeder().variables()){
for(auto pair : mp.polyeder().variables()){
Variable* curr_var = pair.left;
// only variables of the corresponding epoch may enter the subproblem:
if(curr_var->description().find(curr_epoch.str()) != std::string::npos || curr_var->description().find("target_variable") != std::string::npos){
SCIP_VAR* computational_var = curr_var->computational_var(subproblems[index], 0);
/*
SCIP_Bool infeasible = FALSE;
SCIP_CALL_ABORT( SCIPchgVarType(subproblems[index], computational_var, SCIP_VARTYPE_CONTINUOUS, &infeasible));
if(infeasible){
SCIPABORT();
}*/
assert(!infeasible);
subproblem_variable_lookups[index].insert({curr_var, computational_var});
SCIP_CALL_ABORT( SCIPaddVar(subproblems[index], computational_var));
}
......@@ -94,16 +80,16 @@ SCIP* Maintenance_Problem::nmp_generate_benders(){
// constraints of both:
std::cout << "generating constraints" << std::endl;
for(Constraint cons : Linear_Program::polyeder().constraints()){
for(Constraint cons : mp.polyeder().constraints()){
if(cons.description().find("processed") != std::string::npos){
SCIP_CONS* computational_cons = cons.computational_con(master, mp_variable_lookup);
SCIP_CALL_ABORT( SCIPaddCons(master, computational_cons));
// make the variables for other epochs discoverable via vardata of mp vars:
SCIP_VAR** edge_vars;
SCIP_CALL_ABORT( SCIPallocBlockMemoryArray(master, &edge_vars, this->number_of_epochs()));
SCIP_CALL_ABORT( SCIPallocBlockMemoryArray(master, &edge_vars, mp.number_of_epochs()));
SCIP_Bool result;
SCIP_CALL_ABORT( SCIPgetConsVars(master, computational_cons, edge_vars, this->number_of_epochs(), &result));
SCIP_CALL_ABORT( SCIPgetConsVars(master, computational_cons, edge_vars, mp.number_of_epochs(), &result));
assert(result);
// sorting array by epoch
class epoch_relation_extractor{
......@@ -118,13 +104,13 @@ SCIP* Maintenance_Problem::nmp_generate_benders(){
}
} epoch_relation_extractor_instance;
std::sort(edge_vars, edge_vars+this->number_of_epochs(), epoch_relation_extractor_instance);
std::sort(edge_vars, edge_vars+mp.number_of_epochs(), epoch_relation_extractor_instance);
for(int epoch = 0; epoch < this->number_of_epochs(); epoch++){
for(int epoch = 0; epoch < mp.number_of_epochs(); epoch++){
SCIP_VarData* curr_var_data;
SCIP_CALL_ABORT( SCIPallocBlockMemory(master, &curr_var_data));
curr_var_data->nepochs = this->_number_of_epochs;
curr_var_data->nepochs = mp.number_of_epochs();
curr_var_data->vars_of_repr_edge = edge_vars;
SCIPvarSetData(edge_vars[epoch], curr_var_data);
}
......@@ -140,20 +126,19 @@ SCIP* Maintenance_Problem::nmp_generate_benders(){
}
}
std::cout << this->_number_of_epochs << std::endl;
SCIP_CALL_ABORT( SCIPcreateBendersDefault(master, subproblems, this->_number_of_epochs));
SCIP_CALL_ABORT( SCIPcreateBendersDefault(master, subproblems, mp.number_of_epochs()));
SCIP_CALL_ABORT( SCIPsetBoolParam(master, "constraints/benders/active", TRUE) );
SCIP_CALL_ABORT( SCIPsetBoolParam(master, "constraints/benderslp/active", TRUE) );
SCIP_CALL_ABORT( SCIPsetIntParam(master, "constraints/benders/maxprerounds", 1) );
SCIP_CALL_ABORT( SCIPsetIntParam(master, "presolving/maxrounds", 1) );
SCIP_CALL_ABORT( SCIPsetIntParam(master, "constraints/benders/maxprerounds", 0) );
SCIP_CALL_ABORT( SCIPsetIntParam(master, "presolving/maxrounds", 0) );
//SCIP_CALL_ABORT( SCIPsetPresolving(*scip_benders_feas, SCIP_PARAMSETTING_OFF, true));
//SCIP_CALL_ABORT( SCIPsolve(master));
//SCIP_CALL_ABORT( SCIPprintOrigProblem(master, NULL, NULL, FALSE));
/*
for(size_t index = 0; index < this->_number_of_epochs; index++){
for(size_t index = 0; index < mp.number_of_epochs(); index++){
SCIP_CALL_ABORT( SCIPprintOrigProblem(subproblems[index], NULL, NULL, FALSE));
}*/
......
#ifndef NMP_BENDER_GENERATION_H
#include "../Maintenance_Problem.h"
SCIP* nmp_generate_benders(Maintenance_Problem& mp);
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment