Qt 4.8
Public Functions | Private Types | Private Functions | Properties | List of all members
QSimplex Class Reference

The QSimplex class is a Linear Programming problem solver based on the two-phase simplex method. More...

#include <qsimplex_p.h>

Public Functions

void dumpMatrix ()
 
 QSimplex ()
 
bool setConstraints (const QList< QSimplexConstraint *> constraints)
 Sets the new constraints in the simplex solver and returns whether the problem is feasible. More...
 
void setObjective (QSimplexConstraint *objective)
 
qreal solveMax ()
 Maximize the original objective. More...
 
qreal solveMin ()
 Minimize the original objective. More...
 
virtual ~QSimplex ()
 

Private Types

enum  solverFactor { Minimum = -1, Maximum = 1 }
 

Private Functions

void clearColumns (int first, int last)
 
void clearDataStructures ()
 
void clearRow (int rowIndex)
 
void collectResults ()
 Reads results from the simplified matrix and saves them in the "result" member of each QSimplexVariable. More...
 
void combineRows (int toIndex, int fromIndex, qreal factor)
 
int findPivotColumn ()
 
bool iterate ()
 Does one iteration towards a better solution for the problem. More...
 
int pivotRowForColumn (int column)
 For a given pivot column, find the pivot row. More...
 
void reducedRowEchelon ()
 
void setValueAt (int row, int column, qreal value)
 
bool simplifyConstraints (QList< QSimplexConstraint *> *constraints)
 Looks for single-valued variables and remove them from the constraints list. More...
 
void solveMaxHelper ()
 Run simplex on the current matrix with the current objective. More...
 
qreal solver (solverFactor factor)
 Both solveMin and solveMax are interfaces to this method. More...
 
qreal valueAt (int row, int column)
 

Properties

int columns
 
QList< QSimplexConstraint * > constraints
 
int firstArtificial
 
qrealmatrix
 
QSimplexConstraintobjective
 
int rows
 
QList< QSimplexVariable * > variables
 

Detailed Description

The QSimplex class is a Linear Programming problem solver based on the two-phase simplex method.

Warning
This function is not part of the public interface.

It takes a set of QSimplexConstraints as its restrictive constraints and an additional QSimplexConstraint as its objective function. Then methods to maximize and minimize the problem solution are provided.

The two-phase simplex method is based on the following steps: First phase: 1.a) Modify the original, complex, and possibly not feasible problem, into a new, easy to solve problem. 1.b) Set as the objective of the new problem, a feasible solution for the original complex problem. 1.c) Run simplex to optimize the modified problem and check whether a solution for the original problem exists.

Second phase: 2.a) Go back to the original problem with the feasibl (but not optimal) solution found in the first phase. 2.b) Set the original objective. 3.c) Run simplex to optimize the original problem towards its optimal solution.

Definition at line 149 of file qsimplex_p.h.

Enumerations

◆ solverFactor

enum QSimplex::solverFactor
private
Enumerator
Minimum 
Maximum 

Definition at line 181 of file qsimplex_p.h.

Constructors and Destructors

◆ QSimplex()

QSimplex::QSimplex ( )
Warning
This function is not part of the public interface.

Definition at line 84 of file qsimplex_p.cpp.

84  : objective(0), rows(0), columns(0), firstArtificial(0), matrix(0)
85 {
86 }
int firstArtificial
Definition: qsimplex_p.h:191
QSimplexConstraint * objective
Definition: qsimplex_p.h:187
int columns
Definition: qsimplex_p.h:190
int rows
Definition: qsimplex_p.h:189
qreal * matrix
Definition: qsimplex_p.h:193

◆ ~QSimplex()

QSimplex::~QSimplex ( )
virtual
Warning
This function is not part of the public interface.

Definition at line 91 of file qsimplex_p.cpp.

92 {
94 }
void clearDataStructures()
Definition: qsimplex_p.cpp:99

Functions

◆ clearColumns()

void QSimplex::clearColumns ( int  first,
int  last 
)
private
Warning
This function is not part of the public interface.

Definition at line 350 of file qsimplex_p.cpp.

Referenced by setConstraints().

351 {
352  for (int i = 0; i < rows; ++i) {
353  qreal *row = matrix + i * columns;
354  for (int j = first; j <= last; ++j)
355  row[j] = 0.0;
356  }
357 }
double qreal
Definition: qglobal.h:1193
int columns
Definition: qsimplex_p.h:190
int rows
Definition: qsimplex_p.h:189
qreal * matrix
Definition: qsimplex_p.h:193

◆ clearDataStructures()

void QSimplex::clearDataStructures ( )
private
Warning
This function is not part of the public interface.

Definition at line 99 of file qsimplex_p.cpp.

Referenced by setConstraints(), and ~QSimplex().

100 {
101  if (matrix == 0)
102  return;
103 
104  // Matrix
105  rows = 0;
106  columns = 0;
107  firstArtificial = 0;
108  free(matrix);
109  matrix = 0;
110 
111  // Constraints
112  for (int i = 0; i < constraints.size(); ++i) {
113  delete constraints[i]->helper.first;
114  delete constraints[i]->artificial;
115  delete constraints[i];
116  }
117  constraints.clear();
118 
119  // Other
120  variables.clear();
121  objective = 0;
122 }
int firstArtificial
Definition: qsimplex_p.h:191
QList< QSimplexConstraint * > constraints
Definition: qsimplex_p.h:185
QSimplexConstraint * objective
Definition: qsimplex_p.h:187
int columns
Definition: qsimplex_p.h:190
void clear()
Removes all items from the list.
Definition: qlist.h:764
T & first()
Returns a reference to the first item in the list.
Definition: qlist.h:282
int rows
Definition: qsimplex_p.h:189
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
QList< QSimplexVariable * > variables
Definition: qsimplex_p.h:186
qreal * matrix
Definition: qsimplex_p.h:193

◆ clearRow()

void QSimplex::clearRow ( int  rowIndex)
private
Warning
This function is not part of the public interface.

Definition at line 340 of file qsimplex_p.cpp.

Referenced by solver().

341 {
342  qreal *item = matrix + rowIndex * columns;
343  for (int i = 0; i < columns; ++i)
344  item[i] = 0.0;
345 }
double qreal
Definition: qglobal.h:1193
int columns
Definition: qsimplex_p.h:190
qreal * matrix
Definition: qsimplex_p.h:193

◆ collectResults()

void QSimplex::collectResults ( )
private

Reads results from the simplified matrix and saves them in the "result" member of each QSimplexVariable.

Warning
This function is not part of the public interface.

Definition at line 608 of file qsimplex_p.cpp.

Referenced by solver().

609 {
610  // All variables are zero unless overridden below.
611 
612  // ### Is this really needed? Is there any chance that an
613  // important variable remains as non-basic at the end of simplex?
614  for (int i = 0; i < variables.size(); ++i)
615  variables[i]->result = 0;
616 
617  // Basic variables
618  // Update the variable indicated in the first column with the value
619  // in the last column.
620  for (int i = 1; i < rows; ++i) {
621  int index = valueAt(i, 0) - 1;
622  if (index < variables.size())
623  variables[index]->result = valueAt(i, columns - 1);
624  }
625 }
int columns
Definition: qsimplex_p.h:190
qreal valueAt(int row, int column)
Definition: qsimplex_p.h:196
int rows
Definition: qsimplex_p.h:189
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
QList< QSimplexVariable * > variables
Definition: qsimplex_p.h:186
quint16 index

◆ combineRows()

void QSimplex::combineRows ( int  toIndex,
int  fromIndex,
qreal  factor 
)
private
Warning
This function is not part of the public interface.

Definition at line 384 of file qsimplex_p.cpp.

Referenced by iterate(), and reducedRowEchelon().

385 {
386  if (!factor)
387  return;
388 
389  qreal *from = matrix + fromIndex * columns;
390  qreal *to = matrix + toIndex * columns;
391 
392  for (int j = 1; j < columns; ++j) {
393  qreal value = from[j];
394 
395  // skip to[j] = to[j] + factor*0.0
396  if (value == 0.0)
397  continue;
398 
399  to[j] += factor * value;
400 
401  // ### Avoid Numerical errors
402  if (qAbs(to[j]) < 0.0000000001)
403  to[j] = 0.0;
404  }
405 }
double qreal
Definition: qglobal.h:1193
Q_DECL_CONSTEXPR T qAbs(const T &t)
Definition: qglobal.h:1201
int columns
Definition: qsimplex_p.h:190
qreal * matrix
Definition: qsimplex_p.h:193

◆ dumpMatrix()

void QSimplex::dumpMatrix ( )
Warning
This function is not part of the public interface.

Definition at line 362 of file qsimplex_p.cpp.

363 {
364  qDebug("---- Simplex Matrix ----\n");
365 
366  QString str(QLatin1String(" "));
367  for (int j = 0; j < columns; ++j)
368  str += QString::fromAscii(" <%1 >").arg(j, 2);
369  qDebug("%s", qPrintable(str));
370  for (int i = 0; i < rows; ++i) {
371  str = QString::fromAscii("Row %1:").arg(i, 2);
372 
373  qreal *row = matrix + i * columns;
374  for (int j = 0; j < columns; ++j)
375  str += QString::fromAscii("%1").arg(row[j], 7, 'f', 2);
376  qDebug("%s", qPrintable(str));
377  }
378  qDebug("------------------------\n");
379 }
double qreal
Definition: qglobal.h:1193
static QString fromAscii(const char *, int size=-1)
Returns a QString initialized with the first size characters from the string str. ...
Definition: qstring.cpp:4276
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
The QString class provides a Unicode character string.
Definition: qstring.h:83
Q_CORE_EXPORT void qDebug(const char *,...)
int columns
Definition: qsimplex_p.h:190
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
Definition: qstring.cpp:7186
int rows
Definition: qsimplex_p.h:189
qreal * matrix
Definition: qsimplex_p.h:193
#define qPrintable(string)
Definition: qglobal.h:1750

◆ findPivotColumn()

int QSimplex::findPivotColumn ( )
private
Warning
This function is not part of the public interface.

Definition at line 410 of file qsimplex_p.cpp.

Referenced by iterate().

411 {
412  qreal min = 0;
413  int minIndex = -1;
414 
415  for (int j = 0; j < columns-1; ++j) {
416  if (valueAt(0, j) < min) {
417  min = valueAt(0, j);
418  minIndex = j;
419  }
420  }
421 
422  return minIndex;
423 }
double qreal
Definition: qglobal.h:1193
int columns
Definition: qsimplex_p.h:190
qreal valueAt(int row, int column)
Definition: qsimplex_p.h:196

◆ iterate()

bool QSimplex::iterate ( )
private

Does one iteration towards a better solution for the problem.

Warning
This function is not part of the public interface.

See 'solveMaxHelper'.

Definition at line 487 of file qsimplex_p.cpp.

Referenced by solveMaxHelper().

488 {
489  // Find Pivot column
490  int pivotColumn = findPivotColumn();
491  if (pivotColumn == -1)
492  return false;
493 
494  // Find Pivot row for column
495  int pivotRow = pivotRowForColumn(pivotColumn);
496  if (pivotRow == -1) {
497  qWarning() << "QSimplex: Unbounded problem!";
498  return false;
499  }
500 
501  // Normalize Pivot Row
502  qreal pivot = valueAt(pivotRow, pivotColumn);
503  if (pivot != 1.0)
504  combineRows(pivotRow, pivotRow, (qreal(1.0) - pivot) / pivot);
505 
506  // Update other rows
507  for (int row=0; row < rows; ++row) {
508  if (row == pivotRow)
509  continue;
510 
511  combineRows(row, pivotRow, -1 * valueAt(row, pivotColumn));
512  }
513 
514  // Update first column
515  setValueAt(pivotRow, 0, pivotColumn);
516 
517  // dumpMatrix();
518  // qDebug("------------ end of iteration --------------\n");
519  return true;
520 }
int findPivotColumn()
Definition: qsimplex_p.cpp:410
double qreal
Definition: qglobal.h:1193
qreal valueAt(int row, int column)
Definition: qsimplex_p.h:196
Q_CORE_EXPORT void qWarning(const char *,...)
int pivotRowForColumn(int column)
For a given pivot column, find the pivot row.
Definition: qsimplex_p.cpp:445
int rows
Definition: qsimplex_p.h:189
void setValueAt(int row, int column, qreal value)
Definition: qsimplex_p.h:201
void combineRows(int toIndex, int fromIndex, qreal factor)
Definition: qsimplex_p.cpp:384

◆ pivotRowForColumn()

int QSimplex::pivotRowForColumn ( int  column)
private

For a given pivot column, find the pivot row.

Warning
This function is not part of the public interface.

That is, the row with the minimum associated "quotient" where:

  • quotient is the division of the value in the last column by the value in the pivot column.
  • rows with value less or equal to zero are ignored
  • if two rows have the same quotient, lines are chosen based on the highest variable index (value in the first column)

The last condition avoids a bug where artificial variables would be left behind for the second-phase simplex, and with 'good' constraints would be removed before it, what would lead to incorrect results.

Definition at line 445 of file qsimplex_p.cpp.

Referenced by iterate().

446 {
447  qreal min = qreal(999999999999.0); // ###
448  int minIndex = -1;
449 
450  for (int i = 1; i < rows; ++i) {
451  qreal divisor = valueAt(i, column);
452  if (divisor <= 0)
453  continue;
454 
455  qreal quotient = valueAt(i, columns - 1) / divisor;
456  if (quotient < min) {
457  min = quotient;
458  minIndex = i;
459  } else if ((quotient == min) && (valueAt(i, 0) > valueAt(minIndex, 0))) {
460  minIndex = i;
461  }
462  }
463 
464  return minIndex;
465 }
double qreal
Definition: qglobal.h:1193
int columns
Definition: qsimplex_p.h:190
qreal valueAt(int row, int column)
Definition: qsimplex_p.h:196
int rows
Definition: qsimplex_p.h:189

◆ reducedRowEchelon()

void QSimplex::reducedRowEchelon ( )
private
Warning
This function is not part of the public interface.

Definition at line 470 of file qsimplex_p.cpp.

Referenced by solveMaxHelper().

471 {
472  for (int i = 1; i < rows; ++i) {
473  int factorInObjectiveRow = valueAt(i, 0);
474  combineRows(0, i, -1 * valueAt(0, factorInObjectiveRow));
475  }
476 }
qreal valueAt(int row, int column)
Definition: qsimplex_p.h:196
int rows
Definition: qsimplex_p.h:189
void combineRows(int toIndex, int fromIndex, qreal factor)
Definition: qsimplex_p.cpp:384

◆ setConstraints()

bool QSimplex::setConstraints ( const QList< QSimplexConstraint *>  newConstraints)

Sets the new constraints in the simplex solver and returns whether the problem is feasible.

Warning
This function is not part of the public interface.

This method sets the new constraints, normalizes them, creates the simplex matrix and runs the first simplex phase.

Definition at line 135 of file qsimplex_p.cpp.

Referenced by QGraphicsAnchorLayoutPrivate::solveMinMax(), and QGraphicsAnchorLayoutPrivate::solvePreferred().

136 {
138  // Reset to initial state //
141 
142  if (newConstraints.isEmpty())
143  return true; // we are ok with no constraints
144 
145  // Make deep copy of constraints. We need this copy because we may change
146  // them in the simplification method.
147  for (int i = 0; i < newConstraints.size(); ++i) {
149  c->constant = newConstraints[i]->constant;
150  c->ratio = newConstraints[i]->ratio;
151  c->variables = newConstraints[i]->variables;
152  constraints << c;
153  }
154 
155  // Remove constraints of type Var == K and replace them for their value.
157  qWarning() << "QSimplex: No feasible solution!";
159  return false;
160  }
161 
163  // Prepare variables and constraints //
165 
166  // Set Variables direct mapping.
167  // "variables" is a list that provides a stable, indexed list of all variables
168  // used in this problem.
169  QSet<QSimplexVariable *> variablesSet;
170  for (int i = 0; i < constraints.size(); ++i)
171  variablesSet += \
173  variables = variablesSet.toList();
174 
175  // Set Variables reverse mapping
176  // We also need to be able to find the index for a given variable, to do that
177  // we store in each variable its index.
178  for (int i = 0; i < variables.size(); ++i) {
179  // The variable "0" goes at the column "1", etc...
180  variables[i]->index = i + 1;
181  }
182 
183  // Normalize Constraints
184  // In this step, we prepare the constraints in two ways:
185  // Firstly, we modify all constraints of type "LessOrEqual" or "MoreOrEqual"
186  // by the adding slack or surplus variables and making them "Equal" constraints.
187  // Secondly, we need every single constraint to have a direct, easy feasible
188  // solution. Constraints that have slack variables are already easy to solve,
189  // to all the others we add artificial variables.
190  //
191  // At the end we modify the constraints as follows:
192  // - LessOrEqual: SLACK variable is added.
193  // - Equal: ARTIFICIAL variable is added.
194  // - More or Equal: ARTIFICIAL and SURPLUS variables are added.
195  int variableIndex = variables.size();
196  QList <QSimplexVariable *> artificialList;
197 
198  for (int i = 0; i < constraints.size(); ++i) {
199  QSimplexVariable *slack;
200  QSimplexVariable *surplus;
201  QSimplexVariable *artificial;
202 
203  Q_ASSERT(constraints[i]->helper.first == 0);
204  Q_ASSERT(constraints[i]->artificial == 0);
205 
206  switch(constraints[i]->ratio) {
208  slack = new QSimplexVariable;
209  slack->index = ++variableIndex;
210  constraints[i]->helper.first = slack;
211  constraints[i]->helper.second = 1.0;
212  break;
214  surplus = new QSimplexVariable;
215  surplus->index = ++variableIndex;
216  constraints[i]->helper.first = surplus;
217  constraints[i]->helper.second = -1.0;
218  // fall through
220  artificial = new QSimplexVariable;
221  constraints[i]->artificial = artificial;
222  artificialList += constraints[i]->artificial;
223  break;
224  }
225  }
226 
227  // All original, slack and surplus have already had its index set
228  // at this point. We now set the index of the artificial variables
229  // as to ensure they are at the end of the variable list and therefore
230  // can be easily removed at the end of this method.
231  firstArtificial = variableIndex + 1;
232  for (int i = 0; i < artificialList.size(); ++i)
233  artificialList[i]->index = ++variableIndex;
234  artificialList.clear();
235 
237  // Fill the Simplex matrix //
239 
240  // One for each variable plus the Basic and BFS columns (first and last)
241  columns = variableIndex + 2;
242  // One for each constraint plus the objective function
243  rows = constraints.size() + 1;
244 
245  matrix = (qreal *)malloc(sizeof(qreal) * columns * rows);
246  if (!matrix) {
247  qWarning() << "QSimplex: Unable to allocate memory!";
248  return false;
249  }
250  for (int i = columns * rows - 1; i >= 0; --i)
251  matrix[i] = 0.0;
252 
253  // Fill Matrix
254  for (int i = 1; i <= constraints.size(); ++i) {
255  QSimplexConstraint *c = constraints[i - 1];
256 
257  if (c->artificial) {
258  // Will use artificial basic variable
259  setValueAt(i, 0, c->artificial->index);
260  setValueAt(i, c->artificial->index, 1.0);
261 
262  if (c->helper.second != 0.0) {
263  // Surplus variable
265  }
266  } else {
267  // Slack is used as the basic variable
268  Q_ASSERT(c->helper.second == 1.0);
269  setValueAt(i, 0, c->helper.first->index);
270  setValueAt(i, c->helper.first->index, 1.0);
271  }
272 
274  for (iter = c->variables.constBegin();
275  iter != c->variables.constEnd();
276  ++iter) {
277  setValueAt(i, iter.key()->index, iter.value());
278  }
279 
280  setValueAt(i, columns - 1, c->constant);
281  }
282 
283  // Set objective for the first-phase Simplex.
284  // Z = -1 * sum_of_artificial_vars
285  for (int j = firstArtificial; j < columns - 1; ++j)
286  setValueAt(0, j, 1.0);
287 
288  // Maximize our objective (artificial vars go to zero)
289  solveMaxHelper();
290 
291  // If there is a solution where the sum of all artificial
292  // variables is zero, then all of them can be removed and yet
293  // we will have a feasible (but not optimal) solution for the
294  // original problem.
295  // Otherwise, we clean up our structures and report there is
296  // no feasible solution.
297  if ((valueAt(0, columns - 1) != 0.0) && (qAbs(valueAt(0, columns - 1)) > 0.00001)) {
298  qWarning() << "QSimplex: No feasible solution!";
300  return false;
301  }
302 
303  // Remove artificial variables. We already have a feasible
304  // solution for the first problem, thus we don't need them
305  // anymore.
306  clearColumns(firstArtificial, columns - 2);
307 
308  return true;
309 }
void solveMaxHelper()
Run simplex on the current matrix with the current objective.
Definition: qsimplex_p.cpp:323
double qreal
Definition: qglobal.h:1193
unsigned char c[8]
Definition: qnumeric_p.h:62
void clearDataStructures()
Definition: qsimplex_p.cpp:99
QPair< QSimplexVariable *, qreal > helper
Definition: qsimplex_p.h:95
int firstArtificial
Definition: qsimplex_p.h:191
T1 first
Definition: qpair.h:65
T2 second
Definition: qpair.h:66
QSimplexVariable * artificial
Definition: qsimplex_p.h:96
QList< QSimplexConstraint * > constraints
Definition: qsimplex_p.h:185
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
Q_DECL_CONSTEXPR T qAbs(const T &t)
Definition: qglobal.h:1201
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QHash< QSimplexVariable *, qreal > variables
Definition: qsimplex_p.h:91
static double ratio(Bigint *a, Bigint *b)
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
int columns
Definition: qsimplex_p.h:190
QList< T > toList() const
Definition: qset.h:296
qreal valueAt(int row, int column)
Definition: qsimplex_p.h:196
Q_CORE_EXPORT void qWarning(const char *,...)
void clear()
Removes all items from the list.
Definition: qlist.h:764
T & first()
Returns a reference to the first item in the list.
Definition: qlist.h:282
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the hash.
Definition: qhash.h:466
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:469
bool simplifyConstraints(QList< QSimplexConstraint *> *constraints)
Looks for single-valued variables and remove them from the constraints list.
Definition: qsimplex_p.cpp:635
int rows
Definition: qsimplex_p.h:189
const Key key(const T &value) const
Returns the first key mapped to value.
Definition: qhash.h:674
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
QList< QSimplexVariable * > variables
Definition: qsimplex_p.h:186
void setValueAt(int row, int column, qreal value)
Definition: qsimplex_p.h:201
quint16 index
void clearColumns(int first, int last)
Definition: qsimplex_p.cpp:350
qreal * matrix
Definition: qsimplex_p.h:193
The QList class is a template class that provides lists.
Definition: qdatastream.h:62

◆ setObjective()

void QSimplex::setObjective ( QSimplexConstraint newObjective)
Warning
This function is not part of the public interface.

Definition at line 332 of file qsimplex_p.cpp.

Referenced by QGraphicsAnchorLayoutPrivate::solveMinMax(), and QGraphicsAnchorLayoutPrivate::solvePreferred().

333 {
334  objective = newObjective;
335 }
QSimplexConstraint * objective
Definition: qsimplex_p.h:187

◆ setValueAt()

void QSimplex::setValueAt ( int  row,
int  column,
qreal  value 
)
inlineprivate

Definition at line 201 of file qsimplex_p.h.

Referenced by iterate(), setConstraints(), and solver().

202 {
203  matrix[rowIndex * columns + columnIndex] = value;
204 }
int columns
Definition: qsimplex_p.h:190
qreal * matrix
Definition: qsimplex_p.h:193

◆ simplifyConstraints()

bool QSimplex::simplifyConstraints ( QList< QSimplexConstraint *> *  constraints)
private

Looks for single-valued variables and remove them from the constraints list.

Warning
This function is not part of the public interface.

Definition at line 635 of file qsimplex_p.cpp.

Referenced by setConstraints().

636 {
637  QHash<QSimplexVariable *, qreal> results; // List of single-valued variables
638  bool modified = true; // Any chance more optimization exists?
639 
640  while (modified) {
641  modified = false;
642 
643  // For all constraints
644  QList<QSimplexConstraint *>::iterator iter = constraints->begin();
645  while (iter != constraints->end()) {
646  QSimplexConstraint *c = *iter;
647  if ((c->ratio == QSimplexConstraint::Equal) && (c->variables.count() == 1)) {
648  // Check whether this is a constraint of type Var == K
649  // If so, save its value to "results".
650  QSimplexVariable *variable = c->variables.constBegin().key();
651  qreal result = c->constant / c->variables.value(variable);
652 
653  results.insert(variable, result);
654  variable->result = result;
655  variable->index = -1;
656  modified = true;
657 
658  }
659 
660  // Replace known values among their variables
662  for (r = results.constBegin(); r != results.constEnd(); ++r) {
663  if (c->variables.contains(r.key())) {
664  c->constant -= r.value() * c->variables.take(r.key());
665  modified = true;
666  }
667  }
668 
669  // Keep it normalized
670  if (c->constant < 0)
671  c->invert();
672 
673  if (c->variables.isEmpty()) {
674  // If constraint became empty due to substitution, delete it.
675  if (c->isSatisfied() == false)
676  // We must ensure that the constraint soon to be deleted would not
677  // make the problem unfeasible if left behind. If that's the case,
678  // we return false so the simplex solver can properly report that.
679  return false;
680 
681  delete c;
682  iter = constraints->erase(iter);
683  } else {
684  ++iter;
685  }
686  }
687  }
688 
689  return true;
690 }
double qreal
Definition: qglobal.h:1193
unsigned char c[8]
Definition: qnumeric_p.h:62
iterator begin()
Returns an STL-style iterator pointing to the first item in the list.
Definition: qlist.h:267
T take(const Key &key)
Removes the item with the key from the hash and returns the value associated with it...
Definition: qhash.h:807
QHash< QSimplexVariable *, qreal > variables
Definition: qsimplex_p.h:91
bool contains(const Key &key) const
Returns true if the hash contains an item with the key; otherwise returns false.
Definition: qhash.h:872
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:270
bool isEmpty() const
Returns true if the hash contains no items; otherwise returns false.
Definition: qhash.h:297
The QList::iterator class provides an STL-style non-const iterator for QList and QQueue.
Definition: qlist.h:181
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the hash.
Definition: qhash.h:466
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:469
iterator erase(iterator pos)
Removes the item associated with the iterator pos from the list, and returns an iterator to the next ...
Definition: qlist.h:464
const Key key(const T &value) const
Returns the first key mapped to value.
Definition: qhash.h:674
int count(const Key &key) const
Returns the number of items associated with the key.
Definition: qhash.h:719

◆ solveMax()

qreal QSimplex::solveMax ( )

Maximize the original objective.

Warning
This function is not part of the public interface.

Definition at line 594 of file qsimplex_p.cpp.

Referenced by QGraphicsAnchorLayoutPrivate::solveMinMax().

595 {
596  return solver(Maximum);
597 }
qreal solver(solverFactor factor)
Both solveMin and solveMax are interfaces to this method.
Definition: qsimplex_p.cpp:538

◆ solveMaxHelper()

void QSimplex::solveMaxHelper ( )
private

Run simplex on the current matrix with the current objective.

Warning
This function is not part of the public interface.

This is the iterative method. The matrix lines are combined as to modify the variable values towards the best solution possible. The method returns when the matrix is in the optimal state.

Definition at line 323 of file qsimplex_p.cpp.

Referenced by setConstraints(), and solver().

324 {
326  while (iterate()) ;
327 }
void reducedRowEchelon()
Definition: qsimplex_p.cpp:470
bool iterate()
Does one iteration towards a better solution for the problem.
Definition: qsimplex_p.cpp:487

◆ solveMin()

qreal QSimplex::solveMin ( )

Minimize the original objective.

Warning
This function is not part of the public interface.

Definition at line 582 of file qsimplex_p.cpp.

Referenced by QGraphicsAnchorLayoutPrivate::solveMinMax(), and QGraphicsAnchorLayoutPrivate::solvePreferred().

583 {
584  return solver(Minimum);
585 }
qreal solver(solverFactor factor)
Both solveMin and solveMax are interfaces to this method.
Definition: qsimplex_p.cpp:538

◆ solver()

qreal QSimplex::solver ( solverFactor  factor)
private

Both solveMin and solveMax are interfaces to this method.

Warning
This function is not part of the public interface.

The enum solverFactor admits 2 values: Minimum (-1) and Maximum (+1).

This method sets the original objective and runs the second phase Simplex to obtain the optimal solution for the problem. As the internal simplex solver is only able to maximize objectives, we handle the minimization case by inverting the original objective and then maximizing it.

Definition at line 538 of file qsimplex_p.cpp.

Referenced by solveMax(), and solveMin().

539 {
540  // Remove old objective
541  clearRow(0);
542 
543  // Set new objective in the first row of the simplex matrix
544  qreal resultOffset = 0;
546  for (iter = objective->variables.constBegin();
547  iter != objective->variables.constEnd();
548  ++iter) {
549 
550  // Check if the variable was removed in the simplification process.
551  // If so, we save its offset to the objective function and skip adding
552  // it to the matrix.
553  if (iter.key()->index == -1) {
554  resultOffset += iter.value() * iter.key()->result;
555  continue;
556  }
557 
558  setValueAt(0, iter.key()->index, -1 * factor * iter.value());
559  }
560 
561  solveMaxHelper();
562  collectResults();
563 
564 #ifdef QT_DEBUG
565  for (int i = 0; i < constraints.size(); ++i) {
566  Q_ASSERT(constraints[i]->isSatisfied());
567  }
568 #endif
569 
570  // Return the value calculated by the simplex plus the value of the
571  // fixed variables.
572  return (factor * valueAt(0, columns - 1)) + resultOffset;
573 }
void solveMaxHelper()
Run simplex on the current matrix with the current objective.
Definition: qsimplex_p.cpp:323
double qreal
Definition: qglobal.h:1193
QList< QSimplexConstraint * > constraints
Definition: qsimplex_p.h:185
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QSimplexConstraint * objective
Definition: qsimplex_p.h:187
QHash< QSimplexVariable *, qreal > variables
Definition: qsimplex_p.h:91
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
int columns
Definition: qsimplex_p.h:190
void collectResults()
Reads results from the simplified matrix and saves them in the "result" member of each QSimplexVariab...
Definition: qsimplex_p.cpp:608
qreal valueAt(int row, int column)
Definition: qsimplex_p.h:196
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the hash.
Definition: qhash.h:466
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:469
void clearRow(int rowIndex)
Definition: qsimplex_p.cpp:340
const Key key(const T &value) const
Returns the first key mapped to value.
Definition: qhash.h:674
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
void setValueAt(int row, int column, qreal value)
Definition: qsimplex_p.h:201

◆ valueAt()

qreal QSimplex::valueAt ( int  row,
int  column 
)
inlineprivate

Definition at line 196 of file qsimplex_p.h.

Referenced by collectResults(), findPivotColumn(), iterate(), pivotRowForColumn(), reducedRowEchelon(), setConstraints(), and solver().

197 {
198  return matrix[rowIndex * columns + columnIndex];
199 }
int columns
Definition: qsimplex_p.h:190
qreal * matrix
Definition: qsimplex_p.h:193

Properties

◆ columns

int QSimplex::columns
private

◆ constraints

QList<QSimplexConstraint *> QSimplex::constraints
private

Definition at line 185 of file qsimplex_p.h.

Referenced by clearDataStructures(), setConstraints(), and solver().

◆ firstArtificial

int QSimplex::firstArtificial
private

Definition at line 191 of file qsimplex_p.h.

Referenced by clearDataStructures(), and setConstraints().

◆ matrix

qreal* QSimplex::matrix
private

◆ objective

QSimplexConstraint* QSimplex::objective
private

Definition at line 187 of file qsimplex_p.h.

Referenced by clearDataStructures(), setObjective(), and solver().

◆ rows

int QSimplex::rows
private

◆ variables

QList<QSimplexVariable *> QSimplex::variables
private

The documentation for this class was generated from the following files: