1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
|
/* $Id: addBits.cpp 1941 2013-04-10 16:52:27Z stefan $ */
// Copyright (C) 2005, International Business Machines
// Corporation and others. All Rights Reserved.
// This code is licensed under the terms of the Eclipse Public License (EPL).
/*
This is a simple example to create a model using CoinModel.
For even simpler methods see addRows.cpp and addColumns.cpp
This reads in one model and then creates another one:
a) Row bounds
b) Column bounds and objective
c) Adds elements one by one by row.
Solve
It then repeats the exercise:
a) Column bounds
b) Objective - half the columns as is and half with multiplier of "1.0+multiplier"
c) It then adds rows one by one but for half the rows sets their values
with multiplier of "1.0+1.5*multiplier" where column affected
It then loops with multiplier going from 0.0 to 2.0 in increments of 0.1
(you can have as many different strings as you want)
*/
#include "ClpSimplex.hpp"
#include "CoinHelperFunctions.hpp"
#include "CoinTime.hpp"
#include "CoinModel.hpp"
#include <iomanip>
#include <cassert>
int main(int argc, const char *argv[])
{
// Empty model
ClpSimplex model;
std::string mpsFileName;
if (argc >= 2) mpsFileName = argv[1];
else {
#if defined(NETLIBDIR)
mpsFileName = NETLIBDIR "/25fv47.mps";
#else
fprintf(stderr, "Do not know where to find netlib MPS files.\n");
exit(1);
#endif
}
int status = model.readMps(mpsFileName.c_str(), true);
if (status) {
fprintf(stderr, "Bad readMps %s\n", mpsFileName.c_str());
fprintf(stdout, "Bad readMps %s\n", mpsFileName.c_str());
exit(1);
}
// Point to data
int numberRows = model.numberRows();
const double * rowLower = model.rowLower();
const double * rowUpper = model.rowUpper();
int numberColumns = model.numberColumns();
const double * columnLower = model.columnLower();
const double * columnUpper = model.columnUpper();
const double * columnObjective = model.objective();
CoinPackedMatrix * matrix = model.matrix();
// get row copy
CoinPackedMatrix rowCopy = *matrix;
rowCopy.reverseOrdering();
const int * column = rowCopy.getIndices();
const int * rowLength = rowCopy.getVectorLengths();
const CoinBigIndex * rowStart = rowCopy.getVectorStarts();
const double * element = rowCopy.getElements();
//const int * row = matrix->getIndices();
//const int * columnLength = matrix->getVectorLengths();
//const CoinBigIndex * columnStart = matrix->getVectorStarts();
//const double * elementByColumn = matrix->getElements();
// solve
model.dual();
// Now build new model
CoinModel build;
double time1 = CoinCpuTime();
// Row bounds
int iRow;
for (iRow = 0; iRow < numberRows; iRow++) {
build.setRowBounds(iRow, rowLower[iRow], rowUpper[iRow]);
// optional name
build.setRowName(iRow, model.rowName(iRow).c_str());
}
// Column bounds and objective
int iColumn;
for (iColumn = 0; iColumn < numberColumns; iColumn++) {
build.setColumnLower(iColumn, columnLower[iColumn]);
build.setColumnUpper(iColumn, columnUpper[iColumn]);
build.setObjective(iColumn, columnObjective[iColumn]);
// optional name
build.setColumnName(iColumn, model.columnName(iColumn).c_str());
}
// Adds elements one by one by row (backwards by row)
for (iRow = numberRows - 1; iRow >= 0; iRow--) {
int start = rowStart[iRow];
for (int j = start; j < start + rowLength[iRow]; j++)
build(iRow, column[j], element[j]);
}
double time2 = CoinCpuTime();
// Now create clpsimplex
ClpSimplex model2;
model2.loadProblem(build);
double time3 = CoinCpuTime();
printf("Time for build using CoinModel is %g (%g for loadproblem)\n", time3 - time1,
time3 - time2);
model2.dual();
// Now do with strings attached
// Save build to show how to go over rows
CoinModel saveBuild = build;
build = CoinModel();
time1 = CoinCpuTime();
// Column bounds
for (iColumn = 0; iColumn < numberColumns; iColumn++) {
build.setColumnLower(iColumn, columnLower[iColumn]);
build.setColumnUpper(iColumn, columnUpper[iColumn]);
}
// Objective - half the columns as is and half with multiplier of "1.0+multiplier"
// Pick up from saveBuild (for no reason at all)
for (iColumn = 0; iColumn < numberColumns; iColumn++) {
double value = saveBuild.objective(iColumn);
if (iColumn * 2 < numberColumns) {
build.setObjective(iColumn, columnObjective[iColumn]);
} else {
// create as string
char temp[100];
sprintf(temp, "%g + abs(%g*multiplier)", value, value);
build.setObjective(iColumn, temp);
}
}
// It then adds rows one by one but for half the rows sets their values
// with multiplier of "1.0+1.5*multiplier"
for (iRow = 0; iRow < numberRows; iRow++) {
if (iRow * 2 < numberRows) {
// add row in simple way
int start = rowStart[iRow];
build.addRow(rowLength[iRow], column + start, element + start,
rowLower[iRow], rowUpper[iRow]);
} else {
// As we have to add one by one let's get from saveBuild
CoinModelLink triple = saveBuild.firstInRow(iRow);
while (triple.column() >= 0) {
int iColumn = triple.column();
if (iColumn * 2 < numberColumns) {
// just value as normal
build(iRow, triple.column(), triple.value());
} else {
// create as string
char temp[100];
sprintf(temp, "%g + (1.5*%g*multiplier)", triple.value(), triple.value());
build(iRow, iColumn, temp);
}
triple = saveBuild.next(triple);
}
// but remember to do rhs
build.setRowLower(iRow, rowLower[iRow]);
build.setRowUpper(iRow, rowUpper[iRow]);
}
}
time2 = CoinCpuTime();
// Now create ClpSimplex
// If small switch on error printing
if (numberColumns < 50)
build.setLogLevel(1);
// should fail as we never set multiplier
int numberErrors = model2.loadProblem(build);
if( numberErrors == 0 )
{
printf("%d errors from model2.loadProblem(build), but we expected some", numberErrors);
return 1;
}
time3 = CoinCpuTime() - time2;
// subtract out unsuccessful times
time1 += time3;
time2 += time3;
build.associateElement("multiplier", 0.0);
numberErrors = model2.loadProblem(build);
assert(!numberErrors);
time3 = CoinCpuTime();
printf("Time for build using CoinModel is %g (%g for successful loadproblem)\n", time3 - time1,
time3 - time2);
build.writeMps("zero.mps");
// It then loops with multiplier going from 0.0 to 2.0 in increments of 0.1
for (double multiplier = 0.0; multiplier < 2.0; multiplier += 0.1) {
build.associateElement("multiplier", multiplier);
numberErrors = model2.loadProblem(build, true);
assert(!numberErrors);
model2.dual();
}
return 0;
}
|