Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "benders.h"
- #include "cut.h"
- #include "instance.h"
- #include "solution.h"
- #include <math.h>
- Benders::Benders(std::shared_ptr<Instance> instance) :
- _master(new Master(instance)),
- _subproblem(new Subproblem(instance)){
- }
- void timeConverter(int index, char* buffer) {
- char str[10];
- if (index == 0 || index == 1) {
- sprintf(str, "12:");
- }
- else if (index > 1 && index < 20) {
- int time = floor(index/2);
- sprintf(str, "0%d:", time);
- }
- else if (index > 19 && index < 26) {
- int time = floor(index/2);
- sprintf(str, "%d:", time);
- }
- else if (index > 25 && index < 44) {
- int time = floor(index/2) - 12;
- sprintf(str, "0%d:", time);
- }
- else {
- int time = floor(index/2) - 12;
- sprintf(str, "%d:", time);
- }
- strcat(str, (index % 2 == 0 ? "00" : "30"));
- strcat(str, (index < 24 ? " AM" : " PM"));
- for(int i = 0; i < 10; i++) {
- buffer[i] = str[i];
- }
- }
- Benders::~Benders(){}
- void Benders::run(std::shared_ptr<Instance> instance){
- // framework assumes only 1 subproblem - needs to be extended if there are more
- std::shared_ptr<Solution> optSolution;
- std::vector< std::shared_ptr<Cut> > cuts;
- bool solved = false;
- double lb = 0.0;
- double ub = std::numeric_limits<double>::max();
- int name_counter = 0;
- const double *sol1;
- const double *sol2;
- const double *y;
- while(!solved){
- char str[20];
- sprintf(str,"master_model%d",name_counter);
- _master->writeModel(str);
- name_counter++;
- // solve master
- //const double *y = _master->solve();
- y = _master->solve();
- // get lower bound
- lb = _master->getObjectiveValue();
- _subproblem->fixMasterSolution(instance, y);
- std::cout << "\nNew Lower Bound: " << lb << std::endl;
- // identify cuts
- cuts.clear();
- double sobj = 0;
- for(size_t i = 0; i < instance->getNumberOfDemandCurves(); i++) {
- _subproblem->solve(instance, y, cuts, (int)i);
- if (i == 0) {
- sol1 = _subproblem->getSolution();
- }
- else {
- sol2 = _subproblem->getSolution();
- }
- sobj += _subproblem->getObjectiveValue();
- }
- if(sobj < ub){
- //const double *x = _subproblem->getSolution();
- optSolution.reset(new Solution(sobj));
- ub = sobj;
- cout << "New upper bound: " << ub << endl;
- }
- // check for violated cuts
- if(!cuts.empty()){
- for(size_t c=0;c<cuts.size();c++){
- _master->addCut(cuts.at(c));
- }
- }
- else {
- // done!
- solved = true;
- }
- }
- //std::cout << "Printing solution..." << std::endl;
- if(optSolution != NULL) {
- std::shared_ptr<std::vector<std::vector<unsigned int>>> shifts = instance->getShifts();
- std::vector<unsigned int> shiftL = shifts->at(0);
- int shiftLength = shiftL.size();
- cout << "Found optimal solution!" << endl;
- cout << "Objective value: " << _master->getObjectiveValue() << endl;
- cout << "\n------------------------------------------------------------------------------------" << endl;
- cout << "SCHEDULE" << endl;
- cout << "------------------------------------------------------------------------------------" << endl;
- cout << " Shift number\t| Start time\t| End time\t| Staff (Day 1) | Staff (Day 2) |" << endl;
- cout << "------------------------------------------------------------------------------------" << endl;
- for(size_t s = 0; s < instance->getTotalNumberOfShifts(); s++) {
- if(y[s] > 1-10e-16) {
- char buffer_start[10];
- char buffer_end[10];
- timeConverter(shifts->at(s).at(0), buffer_start);
- timeConverter(shifts->at(s).at(shiftLength - 1) + 1, buffer_end);
- cout << " " << s << "\t\t| " << buffer_start << "\t| " << buffer_end << "\t| " << sol1[s] << "\t\t | " << sol2[s] << "\t\t |" << endl;
- }
- }
- cout << "------------------------------------------------------------------------------------" << endl;
- }
- else {
- std::cout << "No optimal solution exists!" << std::endl;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement