// see https://www.youtube.com/watch?v=Axg9OhJ4cjg (german) bottom row is negative unlike in the video // see http://de.slideshare.net/itsmedv91/special-cases-in-simplex special cases // TODO< handle other special cases > public Result iterate() { setupVariables(); // for now we use a iteration counter to protect us from infinite loops // TODO< implement loop detection scheme, basic idea // * we manage a fixed sized array as a sliding window or the hashes of the operations // * if we detect a loop we apply bland's rule to resolve it (is the rule detection realy neccesary?) // // // * every operation (pivot column, pivot row, number of pivot element itself) gets an hash // * at each iteration we subtract the previous hash and add the current hash // * if the hash doesn't change in n iteration(where n == 2 for the simple loop) we are looping // > // TODO< implement https://en.wikipedia.org/wiki/Bland's_rule > uint iterationCounter = 0; const uint MaximalIterationCounter = 128; for (;;) { iterationCounter++; if (iterationCounter > MaximalIterationCounter) { return(new Result(Result.EnumSolverState.TOOMANYITERATIONS)); } bool foundMaximumColumn; int pivotColumnIndex = searchMinimumColumn(out foundMaximumColumn); // all values in the target value row are < 0.0, done if (!foundMaximumColumn) { return(new Result(Result.EnumSolverState.FOUNDSOLUTION)); } //std.cout << "min column " << pivotColumnIndex << std.endl; if (areAllEntriesOfPivotColumnNegativeOrZero(pivotColumnIndex)) { // solution is unbounded return(new Result(Result.EnumSolverState.UNBOUNDEDSOLUTION)); } // divide numbers of pivot column with right side and store in temporary vector Matrix minRatioVector = divideRightSideWithPivotColumnWhereAboveZero(pivotColumnIndex); //std.cout << "temporary vector" << std.endl; //std.cout << minRatioVector << std.endl; int minIndexOfTargetFunctionCoefficient = getMinIndexOfMinRatioVector(minRatioVector); bool positiveMinRatioExists = doesPositiveMinRatioExist(minRatioVector); if (!positiveMinRatioExists) { // solution is unbounded return(new Result(Result.EnumSolverState.UNBOUNDEDSOLUTION)); } int pivotRowIndex = minIndexOfTargetFunctionCoefficient; //std.cout << "pivotRowIndex " << pivotRowIndex << std.endl; // C++ code was matrix(pivotRowIndex, pivotColumnIndex) double pivotElement = matrix[pivotRowIndex, pivotColumnIndex]; // divide the pivot row with the pivot element MatrixUtilities.block(matrix, (uint)pivotRowIndex, 0, 1, matrix.columns).div(pivotElement); // TODO< assert that pivot elemnt is roughtly 1.0 > // do pivot operation for (int pivotRowIteration = 0; pivotRowIteration < matrix.rows; pivotRowIteration++) { if (pivotRowIteration == pivotRowIndex) { continue; } double iterationElementAtPivotColumn = matrix[pivotRowIteration, pivotColumnIndex]; //matrix.block(pivotRowIteration, 0, 1, matrix.columns) -= (matrix.block(pivotRowIndex, 0, 1, matrix.columns) * iterationElementAtPivotColumn); MatrixUtilities.block(matrix, (uint)pivotRowIteration, 0, 1, matrix.columns).subEqual( MatrixUtilities.block(matrix, (uint)pivotRowIndex, 0, 1, matrix.columns).scaleAndDeref(iterationElementAtPivotColumn) ); } // set the variable identifier that we know which row of the matrix is for which variable variables[pivotRowIndex] = new Variable(Variable.EnumType.NAMEME, pivotColumnIndex); //std.cout << matrix << std.endl; } }