void DoStageOne() { ScaleToMaxVal(); CreateStageOneSolver(); solver.ForbiddenPairs = forbiddenPairs; solver.Solve(); if (solver.status != Status.Optimal) { this.status = Status.Infeasible; return; } //this.CheckConstraints(this.solver.tableau.Getx()); //drive out artificials from the basis tableau = solver.tableau; var X = tableau.ReturnMatrix(); var x = tableau.GetSolution(); var basis = tableau.ReturnBasis(); Contract.Assume(X != null); Contract.Assume(x != null); Contract.Assume(basis != null); int n = tableau.ReturnLengthOne(); int artificialsStart = nVars + nSlaksAndSurpluses; int ioffset = 0; Contract.Assume(x.Length <= basis.Length); for (int i = 0; i < x.Length; i++, ioffset += n) { Contract.Assert(x.Length <= basis.Length); Contract.Assert(i < basis.Length); if (basis[i] >= artificialsStart) { if (x[i] > EpsilonForArtificials) { this.status = Status.Infeasible; //one of the artificials remains non-zero return; } //find any non-zero number in non-artificials int nonNulColumn = -1; for (int j = 0; j < artificialsStart; j++) { Contract.Assume(ioffset + j >= 0); // ioffset gets decremented sometime Contract.Assume(ioffset + j < X.Length); // ioffset gets decremented sometime if (Math.Abs(X[ioffset + j]) > Epsilon) { nonNulColumn = j; break; } } if (nonNulColumn != -1) { tableau.Pivot(i, nonNulColumn); } else { //we have to cross out the i-th row because it is all zero var newX = new double[(x.Length - 1) * n]; var newx = new double[x.Length - 1]; var ioOffset = 0; var Ioffset = 0; var io = 0; for (var I = 0; I < x.Length; I++, Ioffset += n) { if (I != i) { Contract.Assume(io < newx.Length); newx[io] = x[I]; for (int J = 0; J < n; J++) { Contract.Assume(Ioffset + J < X.Length); var v = X[Ioffset + J]; Contract.Assume(ioffset + J < newX.Length); newX[ioOffset + J] = v; } io++; ioOffset += n; } } var newBasis = new int[x.Length - 1]; io = 0; for (var I = 0; I < x.Length; I++) { Contract.Assert(x.Length <= basis.Length); if (I != i) { Contract.Assume(io < newBasis.Length); newBasis[io] = basis[I]; io++; } } //continue the loop on new X and on changed tableau X = newX; x = newx; tableau.UpdateMatrix(X, x.Length, n); tableau.SetSolution(x); tableau.UpdateBasis(newBasis); basis = newBasis; i--; ioffset -= n; } } } }
void DoStageOne() { ScaleToMaxVal(); CreateStageOneSolver(); solver.ForbiddenPairs = forbiddenPairs; solver.Solve(); if (solver.status != Status.Optimal) { this.status = Status.Infeasible; return; } //this.CheckConstraints(this.solver.tableau.Getx()); //drive out artificials from the basis tableau = solver.tableau; var X = tableau.ReturnMatrix(); var x = tableau.GetSolution(); var basis = tableau.ReturnBasis(); Contract.Assume(X != null); Contract.Assume(x != null); Contract.Assume(basis != null); int n = tableau.ReturnLengthOne(); int artificialsStart = nVars + nSlaksAndSurpluses; int ioffset = 0; Contract.Assume(x.Length <= basis.Length); for (int i = 0; i < x.Length; i++, ioffset += n) { Contract.Assert(x.Length <= basis.Length); Contract.Assert(i < basis.Length); if (basis[i] >= artificialsStart) { if (x[i] > EpsilonForArtificials) { this.status = Status.Infeasible; //one of the artificials remains non-zero return; } //find any non-zero number in non-artificials int nonNulColumn = -1; for (int j = 0; j < artificialsStart; j++) { Contract.Assume(ioffset + j >= 0); // ioffset gets decremented sometime Contract.Assume(ioffset + j < X.Length); // ioffset gets decremented sometime if (Math.Abs(X[ioffset + j]) > Epsilon) { nonNulColumn = j; break; } } if (nonNulColumn != -1) tableau.Pivot(i, nonNulColumn); else { //we have to cross out the i-th row because it is all zero var newX = new double[(x.Length - 1) * n]; var newx = new double[x.Length - 1]; var ioOffset = 0; var Ioffset = 0; var io = 0; for (var I = 0; I < x.Length; I++, Ioffset += n) { if (I != i) { Contract.Assume(io < newx.Length); newx[io] = x[I]; for (int J = 0; J < n; J++) { Contract.Assume(Ioffset + J < X.Length); var v = X[Ioffset + J]; Contract.Assume(ioffset + J < newX.Length); newX[ioOffset + J] = v; } io++; ioOffset += n; } } var newBasis = new int[x.Length - 1]; io = 0; for (var I = 0; I < x.Length; I++) { Contract.Assert(x.Length <= basis.Length); if (I != i) { Contract.Assume(io < newBasis.Length); newBasis[io] = basis[I]; io++; } } //continue the loop on new X and on changed tableau X = newX; x = newx; tableau.UpdateMatrix(X, x.Length, n); tableau.SetSolution(x); tableau.UpdateBasis(newBasis); basis = newBasis; i--; ioffset -= n; } } } }