/// <summary> /// constructor /// </summary> /// <param name="basis">basis[i] is the var chosen for the constraint i</param> /// <param name="X">the tableau, the tableau will be changed in place</param> /// <param name="c">cost</param> internal Solver(int[] basis, double[] X, double[] x, double[] c, double epsForReducedCosts) { Contract.Requires(x.Length > 0); this.reducedCostEps = epsForReducedCosts; #if DEBUGSIMPLEX if (x.Length == 0) { throw new InvalidOperationException();//"wrong lengths"); } #endif tableau.UpdateMatrix(X, x.Length, X.Length / x.Length); tableau.SetSolution(x); // if(X.Length/x.Length!=c.Length) // throw new System.Exception("wrong lengths"); #if DEBUGSIMPLEX for (int i = 0; i < basis.Length; i++) { if (basis[i] >= c.Length || basis[i] < 0) { throw new InvalidOperationException(); //"wrong basis"); } } #endif for (int i = 0; i < basis.Length; i++) { Contract.Assume(basis[i] >= 0);// F: we need quantified invariants here tableau.PutVarToBasis(i, basis[i]); } this.c = c; }
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; } } } }