//===========================================================================// void OSDipApp::createModels() { UtilPrintFuncBegin(m_osLog, m_classTag, "createModels()", m_appParam.LogLevel, 2); int i; int j; const int nCols = m_osInterface.getVariableNumber(); const int nRows = m_osInterface.getConstraintNumber(); try{ //First the define the objective function over the entire variable space //Create the memory for the objective function m_objective = new double[nCols]; for (i = 0; i < nCols; i++) { m_objective[i] = m_osInterface.getObjectiveFunctionCoeff()[i]; //std::cout << "obj coeff = " << m_objective[i] << std::endl; } setModelObjective( m_objective); //--- //--- Construct the core matrix. //--- int nRowsRelax, nRowsCore; nRowsRelax = 0; nRowsCore = 0; std::vector<OtherConstraintOption*> otherConstraintOptions; std::vector<OtherConstraintOption*>::iterator vit; // // Now construct the block matrices // int *rowsRelax; int whichBlock; DecompConstraintSet *modelRelax = NULL; std::set<int> blockVars; //variables indexes in the specific block std::set<int> blockVarsAll; //all variable indexes that appear in a block std::set<int> blockConAll; //all constraint indexes that appear in a block std::set<int>::iterator sit; CoinPackedVector *row; int *rowVars; int rowSize; if (m_osInterface.m_osoption != NULL && m_osInterface.m_osoption->getNumberOfOtherConstraintOptions() > 0) { otherConstraintOptions = m_osInterface.m_osoption->getOtherConstraintOptions("Dip"); //iterate over the vector of contraint options for (vit = otherConstraintOptions.begin(); vit != otherConstraintOptions.end(); vit++) { // see if we have a Core Constraint Set if( ( (*vit)->name.compare("constraintSet") == 0) && ( (*vit)->type.compare("Block") == 0)) { //get the block number //ch = new char[(*vit)->value.size() + 1]; //ch[(*vit)->value.size()] = 0; //memcpy(ch, (*vit)->value.c_str(), (*vit)->value.size()); //whichBlock = atoi(ch); //delete ch; whichBlock = atoi( (*vit)->value.c_str() ); // first get the number of constraints in this block nRowsRelax = (*vit)->numberOfCon; rowsRelax = new int[nRowsRelax]; //now get the variable indexes for just this block //first clear indexes from a previous block blockVars.clear(); for (i = 0; i < nRowsRelax; i++) { rowsRelax[i] = (*vit)->con[i]->idx; if( (*vit)->con[i]->idx >= nRows) throw ErrorClass( "found an invalid row index in OSoL file"); m_blocks[ whichBlock].push_back( rowsRelax[i] ); //also add to the set of all rows if (blockConAll.find( (*vit)->con[i]->idx ) == blockConAll.end()) { blockConAll.insert( (*vit)->con[i]->idx ); } //add the variables for this row to the set blockVars row = m_osInterface.getRow(rowsRelax[i]); rowSize = row->getNumElements(); rowVars = row->getIndices(); for (j = 0; j < rowSize; j++) { if (blockVars.find(rowVars[j]) == blockVars.end()) { blockVars.insert(rowVars[j]); } } delete row; }//end for or rows in this block modelRelax = new DecompConstraintSet(); CoinAssertHint(modelRelax, "Error: Out of Memory"); //create the active columns in this block for (sit = blockVars.begin(); sit != blockVars.end(); sit++) { modelRelax->activeColumns.push_back( *sit); //insert into the all variables set also, but throw an execption //if already there -- same variable cannot be in more than one block if (blockVarsAll.find( *sit) == blockVarsAll.end()) { blockVarsAll.insert (*sit); }else{ throw ErrorClass("Variable " + UtilIntToStr(*sit) + " appears in more than one block"); } } // // if (m_appParam.LogLevel >= 3) { (*m_osLog) << "Active Columns : " << whichBlock << endl; UtilPrintVector(modelRelax->activeColumns, m_osLog); } createModelPartSparse(modelRelax, nRowsRelax, rowsRelax); //does not work for cutting planes //createModelPart(modelRelax, nRowsRelax, rowsRelax); //modelRelax->fixNonActiveColumns(); m_modelR.insert(make_pair(whichBlock + 1, modelRelax)); setModelRelax(modelRelax, "relax" + UtilIntToStr(whichBlock), whichBlock); if (m_appParam.LogLevel >= 3) { (*m_osLog) << std::endl << std::endl; (*m_osLog) << "HERE COMES THE DUPLICATION (WHEN createModelPartSparse USED)" << std::endl; } UtilPrintVector( modelRelax->activeColumns, m_osLog); //free local memory UTIL_DELARR( rowsRelax); } }//end for over constraint options }// if on ospton null //get the core constraints -- constraints NOT in a block int *rowsCore = NULL; int kount = 0; nRowsCore = nRows - blockConAll.size(); if(nRowsCore <= 0) throw ErrorClass("We need at least one coupling constraint"); rowsCore = new int[nRowsCore]; for(i = 0; i < nRows; i++){ if (blockConAll.find( i ) == blockConAll.end() ){ rowsCore[ kount++] = i; } } if( kount != nRowsCore) throw ErrorClass("There was an error counting coupling constraints"); DecompConstraintSet * modelCore = new DecompConstraintSet(); createModelPart(modelCore, nRowsCore, rowsCore); setModelCore(modelCore, "core"); //--- //--- save a pointer so we can delete it later //--- m_modelC = modelCore; //get the master only variables //modelCore->masterOnlyCols.push_back(i); for (i = 0; i < nCols; i++) { if (blockVarsAll.find(i) == blockVarsAll.end()) { modelCore->masterOnlyCols.push_back(i); std::cout << "MASTER ONLY VARIABLE " << i << std::endl; } } //--- //--- create an extra "empty" block for the master-only vars //--- since I don't know what OSI will do with empty problem //--- we will make column bounds explicity rows //--- int nMasterOnlyCols = static_cast<int> (modelCore->masterOnlyCols.size()); if (nMasterOnlyCols) { if (m_appParam.LogLevel >= 1) (*m_osLog) << "Create model part Master-Only." << endl; createModelMasterOnlys2(modelCore->masterOnlyCols); } UtilPrintFuncBegin(m_osLog, m_classTag, "printCurrentProblem()", m_appParam.LogLevel, 2); //free local memory UTIL_DELARR( rowsCore); }//end try catch(const ErrorClass& eclass){ throw ErrorClass( eclass.errormsg); } }// end createModels()
//===========================================================================// void SDPUC_DecompApp::createModelCore(DecompConstraintSet * model){ //--- //--- MASTER (A''): //--- z[i,j,t] <= y1[i,j] for all (i,j) in A, t in T //arc-investment //--- z[i,j,t] - z[i,j,t-1] <= y2[i,j,t] for all (i,j) in A, t in T //arc(unit) commitment //--- y[i,j] binary for all (i,j) in A //--- int i, t, a, colIndex; int numTimeperiods = m_instance.m_numTimeperiods; int numArcs = m_instance.m_numArcs; int numNodes = m_instance.m_numNodes; int numCols = numArcs //y1-vars + 3 * numTimeperiods * numArcs //y2-, z-, and x-vars + numTimeperiods * numNodes; //theta-vars int numRows = numArcs * numTimeperiods; int col_yStartIndex = 0; int col_zStartIndex = numArcs*(1+numTimeperiods); int col_xStartIndex = numArcs * (1 + 2*numTimeperiods); int col_thetaStartIndex = numArcs*(1 + 3*numTimeperiods) ; SDPUC_Instance::arc * arcs = m_instance.m_arcs; UtilPrintFuncBegin(m_osLog, m_classTag, "createModelCore()", m_appParam.LogLevel, 2); //--- //--- create space for the model matrix (row-majored) //--- model->M = new CoinPackedMatrix(false, 0.0, 0.0); if(!model->M) throw UtilExceptionMemory("createModelCore", "SDPUC_DecompApp"); model->M->setDimensions(0, numCols); model->reserve(numRows, numCols); //--- //--- create the rows and set the col/row bounds //--- UtilFillN(model->colLB, numCols, -m_infinity); UtilFillN(model->colUB, numCols, m_infinity); for(a = 0; a < numArcs; a++){ colIndex = a; //add y1-vars model->colLB[colIndex] = 0; model->colUB[colIndex] = 1; for(t = 0; t < numTimeperiods; t++){ int t_prev = 0; if(t == 0) { t_prev = numTimeperiods - 1; } else { t_prev = t - 1; } colIndex = a + t * numArcs + numArcs; //add y2-vars model->colLB[colIndex] = 0; model->colUB[colIndex] = 1; CoinPackedVector row1; // 0 <= y1[i,j] - z[i,j,t] for all (i,j) in A, t in T CoinPackedVector row2; // 0 <= y2[i,j,t] - z[i,j,t] + z[i,j,t-1] for all (i,j) in A, t in T CoinPackedVector rowFix_y1; //fix y1=1 CoinPackedVector y2upper1; // y2(t) <= z(t) : if off in t then we dont start-up CoinPackedVector y2upper2; // y2(t) <= 1-z(t-1) : if on in t-1 then dont start up in t //insert y1-var coefficient row1.insert(a, 1.0); rowFix_y1.insert(a, 1.0); //insert y2-var coefficient colIndex = t * numArcs + a + numArcs; row2.insert(colIndex, 1.0); y2upper1.insert(colIndex, -1.0); y2upper2.insert(colIndex, -1.0); //add z-vars colIndex = t * numArcs + a + col_zStartIndex; model->colLB[colIndex] = 0; model->colUB[colIndex] = 1; //insert z-var coefficient row1.insert(colIndex, -1.0); row2.insert(colIndex, -1.0); y2upper1.insert(colIndex, 1.0); colIndex = t_prev * numArcs + a + col_zStartIndex; row2.insert(colIndex, 1.0); y2upper2.insert(colIndex, -1.0); std::string rowName1_1 = "MP1_1_" + UtilIntToStr(a) + "_" + UtilIntToStr(t); std::string rowName1_2 = "MP1_2_" + UtilIntToStr(a) + "_" + UtilIntToStr(t); std::string rowName2_1 = "MP2_1_" + UtilIntToStr(a) + "_" + UtilIntToStr(t); std::string rowName2_2 = "MP2_2_" + UtilIntToStr(a) + "_" + UtilIntToStr(t); std::string rowNameFix = "fix_y1_" + UtilIntToStr(a) + "_" + UtilIntToStr(t); //TODO: any issue with range constraint model->appendRow(row1, 0.0, m_infinity, rowName1_1); //add MP1_constraints (arc investments) model->appendRow(row1, -m_infinity, 1.0, rowName1_2); //add MP1_constraints (arc investments) if(arcs[a].tail == 0) { //ONLY for supply arcs (!!) model->appendRow(row2, 0.0, m_infinity, rowName2_1); //add MP2_constraints (arc commitment) model->appendRow(row2, -m_infinity, 1.0, rowName2_2); //add MP2_constraints (arc commitment) } model->appendRow(rowFix_y1, 1.0, m_infinity, rowNameFix); //add fix y1 vars //model->appendRow(y2upper1, 0.0, m_infinity, std::string("y2-upperbound-1")); //add upperbounds on y2 //model->appendRow(y2upper2, -1.0, m_infinity, std::string("y2-upperbound-2")); //..to strengthen formulation } } //--- //--- create column names (helps with debugging) //--- //y-vars for(a = 0; a < numArcs; a++){ std::string colName = "y1(a" + UtilIntToStr(a) + "(" + UtilIntToStr(arcs[a].tail) + "," + UtilIntToStr(arcs[a].head) + "))"; model->colNames.push_back(colName); } for(t = 0; t < numTimeperiods; t++){ for(a = 0; a < numArcs; a++){ std::string colName = "y2(t" + UtilIntToStr(t) + ",a" + UtilIntToStr(a) + "(" + UtilIntToStr(arcs[a].tail) + "," + UtilIntToStr(arcs[a].head) + "))"; model->colNames.push_back(colName); } } //z-vars for(t = 0; t < numTimeperiods; t++){ for(a = 0; a < numArcs; a++){ std::string colName = "z(t" + UtilIntToStr(t) + ",a" + UtilIntToStr(a) + "(" + UtilIntToStr(arcs[a].tail) + "," + UtilIntToStr(arcs[a].head) + "))"; model->colNames.push_back(colName); } } //x-vars for(t = 0; t < numTimeperiods; t++){ for(a = 0; a < numArcs; a++){ std::string colName = "x(t" + UtilIntToStr(t) + ",a" + UtilIntToStr(a) + "(" + UtilIntToStr(arcs[a].tail) + "," + UtilIntToStr(arcs[a].head) + "))"; model->colNames.push_back(colName); } } //theta-vars for(t = 0; t < numTimeperiods; t++){ for(i = 0; i < numNodes; i++){ std::string colName = "theta(t" + UtilIntToStr(t) + ",n" + UtilIntToStr(i) + ")"; model->colNames.push_back(colName); } } //--- //--- create a list of the "active" columns (those related //--- to this commmodity) all other columns are fixed to 0 //--- UtilFillN(model->colLB, numCols, 0.0); UtilFillN(model->colUB, numCols, 0.0); colIndex = 0; for(a = 0; a < numArcs; a++){ //set y-columns active //model->colLB[colIndex] = 0; //model->colUB[colIndex] = 1; //model->activeColumns.push_back(colIndex); //set y-columns as master-only columns colIndex = col_yStartIndex + a; model->masterOnlyCols.push_back(colIndex); //y1-vars for(t = 0; t < numTimeperiods; t++){ colIndex = col_yStartIndex + t * numArcs + a + numArcs; model->masterOnlyCols.push_back(colIndex); //y2-vars } } if(m_appParam.LogLevel >= 3){ (*m_osLog) << "Master only columns:" << endl; UtilPrintVector(model->masterOnlyCols, m_osLog); if(model->getColNames().size() > 0) UtilPrintVector(model->masterOnlyCols, model->getColNames(), m_osLog); } //--- //--- set the indices of the integer variables of model //--- UtilIotaN(model->integerVars, col_xStartIndex, col_yStartIndex); UtilPrintFuncEnd(m_osLog, m_classTag, "createModelCore()", m_appParam.LogLevel, 2); //--- //--- display problem //--- //int j = 0; //cout << "find: \nActive cols: "; //std::vector<int>::const_iterator it; //for(it = model->getActiveColumns().begin(); it != model->getActiveColumns().end(); it++){ //cout << *it << " "; //} // //cout << "\ns.t.\n"; //for(j = 0; j < model->getNumRows(); j++){ //cout << model->rowNames[j] << " : \t\t"; //cout << model->rowLB[j] << " \t <= \t" ; //for (i = 0; i < model->getNumCols(); i++){ ////cout << "numCols=" << model->getNumCols() << endl; //if(model->getMatrix()->getCoefficient(j,i) != 0) { ////cout << "i" << i << " "; //cout << " " << model->M->getCoefficient(j,i) << " " ; //cout << model->getColNames()[i] ; //} //else {cout << "" ;} //} //cout << " \t <= \t " << model->rowUB[j] << endl ; // //} }