00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "bande.hh"
00028
00029 namespace bande {
00030
00031
00032
00033
00034 IntegerProgram::IntegerProgram() {
00035 }
00036
00037
00038
00039
00040 IntegerProgram::~IntegerProgram() {
00041 }
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 int IntegerProgram::mkInt(double d) {
00058 static const int max = std::numeric_limits<int>::max() - 100;
00059 static const int min = std::numeric_limits<int>::min() + 100;
00060 if (d > max) return max;
00061 if (d < min) return min;
00062 return (int)floor(d + 0.5);
00063 }
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 void IntegerProgram::readMps(const char* fileName) {
00079 lp.readMps(fileName);
00080 rowBounds.resize(getNumRows());
00081 colBounds.resize(getNumCols());
00082 iSol.resize(getNumCols());
00083 matrix.clear();
00084 matrix.resize(getNumRows() * getNumCols());
00085 for (int row = 0; row < getNumRows(); ++row) {
00086 rowBounds[row].first = mkInt(lp.getRowLower(row));
00087 rowBounds[row].second = mkInt(lp.getRowUpper(row));
00088 }
00089 for (int col = 0; col < getNumCols(); ++col) {
00090 colBounds[col].first = mkInt(lp.getColLower(col));
00091 colBounds[col].second = mkInt(lp.getColUpper(col));
00092 }
00093 const CoinPackedMatrix* cpm = lp.getSolver()->getMatrixByRow();
00094 const double* elements = cpm->getElements();
00095 const int* indices = cpm->getIndices();
00096 for (int row = 0; row < getNumRows(); ++row) {
00097 for (CoinBigIndex i = cpm->getVectorFirst(row),
00098 e = cpm->getVectorLast(row); i != e; ++i) {
00099 m(row, indices[i]) = mkInt(elements[i]);
00100 }
00101 }
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 void IntegerProgram::setColLower(UndoManager& um, int col, int val) {
00114 int& ref = colBounds[col].first;
00115 if (val <= ref) {
00116 std::cerr << "Invalid change of lower bound from "
00117 << ref << " to " << val << std::endl;
00118 exit(EXIT_FAILURE);
00119 }
00120 um.record(new UndoInt(ref));
00121 ref = val;
00122 lp.setColLower(um, col, val);
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 void IntegerProgram::setColUpper(UndoManager& um, int col, int val) {
00135 int& ref = colBounds[col].second;
00136 if (val >= ref) {
00137 std::cerr << "Invalid change of upper bound from "
00138 << ref << " to " << val << std::endl;
00139 exit(EXIT_FAILURE);
00140 }
00141 um.record(new UndoInt(ref));
00142 ref = val;
00143 lp.setColUpper(um, col, val);
00144 }
00145
00146
00147
00148
00149
00150
00151
00152 void IntegerProgram::mkIntSolution() {
00153 for (int col = 0; col < getNumCols(); ++col) {
00154 iSol[col] = mkInt(getColSolution(col));
00155 }
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 bool IntegerProgram::checkIntSolution() const {
00170 for (int col = 0; col < getNumCols(); ++col) {
00171 if (iSol[col] < colBounds[col].first ||
00172 iSol[col] > colBounds[col].second) {
00173 std::cerr << "col " << col << " (" << getColName(col) << "): "
00174 << colBounds[col].first << "<=" << iSol[col] << "<="
00175 << colBounds[col].second << std::endl;
00176 return false;
00177 }
00178 }
00179 for (int row = 0, mi = 0; row < getNumRows(); ++row) {
00180 int sum = 0;
00181 for (int col = 0; col < getNumCols(); ++col)
00182 sum += matrix[mi++] * iSol[col];
00183 if (sum < rowBounds[row].first || sum > rowBounds[row].second) {
00184 std::cerr << "row " << row << " (" << getRowName(row) << "): "
00185 << rowBounds[row].first << "<=" << iSol[row] << "<="
00186 << rowBounds[row].second << std::endl;
00187 return false;
00188 }
00189 }
00190 return true;
00191 }
00192
00193 }