/** @file instanceGenerator.cpp * * @author Robert Fourer, Jun Ma, Kipp Martin, * @version 1.0, 10/05/2005 * @since OS1.0 * * \remarks * Copyright (C) 2005, Robert Fourer, Jun Ma, Kipp Martin, * Northwestern University, and the University of Chicago. * All Rights Reserved. * This software is licensed under the Common Public License. * Please see the accompanying LICENSE file in root directory for terms. * * In this example we show how to use the OSInstance API * to generate an OSiL problem instance. * * The objective of this example is to illustrate how to build a problem instance * using the OSIntance class API. In particular we illutrate a number of the set() * methods in the OSInstance class. As written, we need the LINDO nonlinear solver. * * Model: A nonlinear model with multiple local minimizers. * Taken from the Samples directory of the LINDO API * * maximize abs( x0 + 1) + .4 * x1;
* s.t. x0 + x1 <= 4;
* x0 * x1 + x1 <= 6;
* x0 * x1 <= 0;
* max(x0 , x1 + 1) >= 0;
* if(x1, 1, x1) <= 0;
* (x1 * 2 * x1 - x1) * x0 <= 0;
* -100 <= x0 <= 100
* x1 is binary
*/ #include #include #include "CoinHelperFunctions.hpp" #include "OSConfig.h" #include "OSInstance.h" #include "OSiLWriter.h" #include "OSParameters.h" #include "OSnLNode.h" #include "OSErrorClass.h" using std::cout; using std::endl; int main(){ WindowsErrorPopupBlocker(); cout << "Start Building the Model" << endl; try{ OSInstance *osinstance; osinstance = new OSInstance(); // // put in some of the OSInstance information osinstance->setInstanceSource("An example from the LINDO API samples directory"); osinstance->setInstanceDescription("A good example of a hard nonlinear program"); // // now put in the OSInstance information // // first the variables osinstance->setVariableNumber( 2); //addVariable(int index, string name, double lowerBound, double upperBound, char type, double init, string initString); // we could use setVariables() and add all the variable with one method call -- below is easier osinstance->addVariable(0, "x0", -100, 100, 'C', OSNAN, ""); osinstance->addVariable(1, "x1", 0, 1, 'B', OSNAN, ""); // // now add the objective function osinstance->setObjectiveNumber( 1); // now the coefficient SparseVector *objcoeff; objcoeff = new SparseVector(1); objcoeff->indexes[ 0] = 1; objcoeff->values[ 0] = .4; //bool addObjective(int index, string name, string maxOrMin, double constant, double weight, SparseVector* objectiveCoefficients); osinstance->addObjective(-1, "objfunction", "max", 0.0, 1.0, objcoeff); objcoeff->bDeleteArrays = true; delete objcoeff; // // now the constraints osinstance->setConstraintNumber( 6); //bool addConstraint(int index, string name, double lowerBound, double upperBound, double constant); // note: we could use setConstraints() and add all the constraints with one method call -- below is easier osinstance->addConstraint(0, "row0", -OSDBL_MAX, 4, 0); osinstance->addConstraint(1, "row1", -OSDBL_MAX, 6, 0); osinstance->addConstraint(2, "row2", -OSDBL_MAX, 0, 0); osinstance->addConstraint(3, "row3", 0 , OSDBL_MAX, 0); osinstance->addConstraint(4, "row4", -OSDBL_MAX, 0, 0); osinstance->addConstraint(5, "row5", -OSDBL_MAX, 0, 0); // // // now add the //bool setLinearConstraintCoefficients(int numberOfValues, bool isColumnMajor, //double* values, int valuesBegin, int valuesEnd, //int* indexes, int indexesBegin, int indexesEnd, //int* starts, int startsBegin, int startsEnd); double *values = new double[ 3]; int *indexes = new int[ 3]; int *starts = new int[ 3]; values[ 0] = 1.0; values[ 1] = 1.0; values[ 2] = 1.0; indexes[ 0] = 0; indexes[ 1] = 0; indexes[ 2] = 1; starts[ 0] = 0; starts[ 1] = 2; starts[ 2] = 3; osinstance->setLinearConstraintCoefficients(3, true, values, 0, 2, indexes, 0, 2, starts, 0, 2); // // finally the nonlinear part, not as nice since we don't have any set() methods // yet, we must work directly with the data structures // // we have 6 nonlinear expressions osinstance->instanceData->nonlinearExpressions->numberOfNonlinearExpressions = 6; osinstance->instanceData->nonlinearExpressions->nl = new Nl*[ 6 ]; // define the vectors OSnLNode *nlNodePoint; OSnLNodeVariable *nlNodeVariablePoint; OSnLNodeNumber *nlNodeNumberPoint; OSnLNodeMax *nlNodeMaxPoint; std::vector nlNodeVec; // // // the objective function nonlinear term abs( x0 + 1) osinstance->instanceData->nonlinearExpressions->nl[ 0] = new Nl(); osinstance->instanceData->nonlinearExpressions->nl[ 0]->idx = -1; osinstance->instanceData->nonlinearExpressions->nl[ 0]->osExpressionTree = new OSExpressionTree(); // create a variable nl node for x0 nlNodeVariablePoint = new OSnLNodeVariable(); nlNodeVariablePoint->idx=0; nlNodeVec.push_back( nlNodeVariablePoint); // create the nl node for number 1 nlNodeNumberPoint = new OSnLNodeNumber(); nlNodeNumberPoint->value = 1.0; nlNodeVec.push_back( nlNodeNumberPoint); // create the nl node for + nlNodePoint = new OSnLNodePlus(); nlNodeVec.push_back( nlNodePoint); // create the nl node for max nlNodePoint = new OSnLNodeAbs(); nlNodeVec.push_back( nlNodePoint); // the vectors are in postfix format // now the expression tree osinstance->instanceData->nonlinearExpressions->nl[ 0]->osExpressionTree->m_treeRoot = nlNodeVec[ 0]->createExpressionTreeFromPostfix( nlNodeVec); nlNodeVec.clear(); // // // constraint 0 has no nonlinear terms // generate the x0*x1 term in constraint 1 // osinstance->instanceData->nonlinearExpressions->nl[ 1] = new Nl(); osinstance->instanceData->nonlinearExpressions->nl[ 1]->idx = 1; osinstance->instanceData->nonlinearExpressions->nl[ 1]->osExpressionTree = new OSExpressionTree(); // create a variable nl node for x0 nlNodeVariablePoint = new OSnLNodeVariable(); nlNodeVariablePoint->idx=0; nlNodeVec.push_back( nlNodeVariablePoint); // create the nl node for x1 nlNodeVariablePoint = new OSnLNodeVariable(); nlNodeVariablePoint->idx=1; nlNodeVec.push_back( nlNodeVariablePoint); // create the nl node for * nlNodePoint = new OSnLNodeTimes(); nlNodeVec.push_back( nlNodePoint); // the vectors are in postfix format // now the expression tree osinstance->instanceData->nonlinearExpressions->nl[ 1]->osExpressionTree->m_treeRoot = nlNodeVec[ 0]->createExpressionTreeFromPostfix( nlNodeVec); nlNodeVec.clear(); // // // generate the x0*x1 term in constraint 2 osinstance->instanceData->nonlinearExpressions->nl[ 2] = new Nl(); osinstance->instanceData->nonlinearExpressions->nl[ 2]->idx = 2; osinstance->instanceData->nonlinearExpressions->nl[ 2]->osExpressionTree = new OSExpressionTree(); // create a variable nl node for x0 nlNodeVariablePoint = new OSnLNodeVariable(); nlNodeVariablePoint->idx=0; nlNodeVec.push_back( nlNodeVariablePoint); // create the nl node for x0 nlNodeVariablePoint = new OSnLNodeVariable(); nlNodeVariablePoint->idx=1; nlNodeVec.push_back( nlNodeVariablePoint); // create the nl node for * nlNodePoint = new OSnLNodeTimes(); nlNodeVec.push_back( nlNodePoint); // the vectors are in postfix format // now the expression tree osinstance->instanceData->nonlinearExpressions->nl[ 2]->osExpressionTree->m_treeRoot = nlNodeVec[ 0]->createExpressionTreeFromPostfix( nlNodeVec); nlNodeVec.clear(); // // // // generate the max(x0 , x1 + 1) term in constraint 3 osinstance->instanceData->nonlinearExpressions->nl[ 3] = new Nl(); osinstance->instanceData->nonlinearExpressions->nl[ 3]->idx = 3; osinstance->instanceData->nonlinearExpressions->nl[ 3]->osExpressionTree = new OSExpressionTree(); // create a variable nl node for x1 nlNodeVariablePoint = new OSnLNodeVariable(); nlNodeVariablePoint->idx=1; nlNodeVec.push_back( nlNodeVariablePoint); // create the nl node for number 1 nlNodeNumberPoint = new OSnLNodeNumber(); nlNodeNumberPoint->value = 1.0; nlNodeVec.push_back( nlNodeNumberPoint); // create the nl node for + nlNodePoint = new OSnLNodePlus(); nlNodeVec.push_back( nlNodePoint); // now push x0 to the stack nlNodeVariablePoint = new OSnLNodeVariable(); nlNodeVariablePoint->idx=0; nlNodeVec.push_back( nlNodeVariablePoint); // create the nl node for max nlNodeMaxPoint = new OSnLNodeMax(); nlNodeMaxPoint->inumberOfChildren = 2; nlNodeMaxPoint->m_mChildren = new OSnLNode*[ nlNodeMaxPoint->inumberOfChildren]; nlNodeVec.push_back( nlNodeMaxPoint); // the vectors are in postfix format // now the expression tree osinstance->instanceData->nonlinearExpressions->nl[ 3]->osExpressionTree->m_treeRoot = nlNodeVec[ 0]->createExpressionTreeFromPostfix( nlNodeVec); nlNodeVec.clear(); // // // // generate the if(x1, 1, x1) term in constraint 4 osinstance->instanceData->nonlinearExpressions->nl[ 4] = new Nl(); osinstance->instanceData->nonlinearExpressions->nl[ 4]->idx = 4; osinstance->instanceData->nonlinearExpressions->nl[ 4]->osExpressionTree = new OSExpressionTree(); // create a variable nl node for x1 nlNodeVariablePoint = new OSnLNodeVariable(); nlNodeVariablePoint->idx=1; nlNodeVec.push_back( nlNodeVariablePoint); // create the nl node for number 1 nlNodeNumberPoint = new OSnLNodeNumber(); nlNodeNumberPoint->value = 1.0; nlNodeVec.push_back( nlNodeNumberPoint); // now push x1 to the stack nlNodeVariablePoint = new OSnLNodeVariable(); nlNodeVariablePoint->idx=1; nlNodeVec.push_back( nlNodeVariablePoint); // create the nl node for If nlNodePoint = new OSnLNodeIf(); nlNodeVec.push_back( nlNodePoint); // the vectors are in postfix format // now the expression tree osinstance->instanceData->nonlinearExpressions->nl[ 4]->osExpressionTree->m_treeRoot = nlNodeVec[ 0]->createExpressionTreeFromPostfix( nlNodeVec); nlNodeVec.clear(); // // // // generate the (x1 * 2 * x1 - x1) * x0 term in constraint 5 osinstance->instanceData->nonlinearExpressions->nl[ 5] = new Nl(); osinstance->instanceData->nonlinearExpressions->nl[ 5]->idx = 5; osinstance->instanceData->nonlinearExpressions->nl[ 5]->osExpressionTree = new OSExpressionTree(); // create a variable nl node for x1 nlNodeVariablePoint = new OSnLNodeVariable(); nlNodeVariablePoint->idx=1; nlNodeVec.push_back( nlNodeVariablePoint); // create the nl node for number 1 nlNodeNumberPoint = new OSnLNodeNumber(); nlNodeNumberPoint->value = 2.0; nlNodeVec.push_back( nlNodeNumberPoint); // create an nl node for * nlNodePoint = new OSnLNodeTimes(); nlNodeVec.push_back( nlNodePoint); // now push x1 to the stack nlNodeVariablePoint = new OSnLNodeVariable(); nlNodeVariablePoint->idx=1; nlNodeVec.push_back( nlNodeVariablePoint); // create an nl node for * nlNodePoint = new OSnLNodeTimes(); nlNodeVec.push_back( nlNodePoint); // create a variable nl node for x1 nlNodeVariablePoint = new OSnLNodeVariable(); nlNodeVariablePoint->idx=1; nlNodeVec.push_back( nlNodeVariablePoint); // create an nl node for - nlNodePoint = new OSnLNodeMinus(); nlNodeVec.push_back( nlNodePoint); // create a variable nl node for x0 nlNodeVariablePoint = new OSnLNodeVariable(); nlNodeVariablePoint->idx=0; nlNodeVec.push_back( nlNodeVariablePoint); // create an nl node for * nlNodePoint = new OSnLNodeTimes(); nlNodeVec.push_back( nlNodePoint); // the vectors are in postfix format // now the expression tree osinstance->instanceData->nonlinearExpressions->nl[ 5]->osExpressionTree->m_treeRoot = nlNodeVec[ 0]->createExpressionTreeFromPostfix( nlNodeVec); nlNodeVec.clear(); // // // cout << "End Building the Model" << endl; // Write out the model OSiLWriter *osilwriter; osilwriter = new OSiLWriter(); cout << osilwriter->writeOSiL( osinstance); // done writing the model cout << "Done writing the Model" << endl; delete osinstance; osinstance = NULL; delete osilwriter; osilwriter = NULL; cout << "Done with garbage collection" << endl; return 0; } catch(const ErrorClass& eclass){ cout << eclass.errormsg << endl; } }