internal Vector SolveInternal(Matrix A, Vector b, Vector c, StartingBasis B, Matrix AB, Vector bB) { //Init simplex var m = A.RowCount; var ABi = AB.Inverse(); //X is a starting vector var x = AB.LU().Solve(bB); while (true) { iteration++; //Compute lambda (cT*AB.inv())T var lambda = (c.ToRowMatrix()*ABi).Transpose().ToRowWiseArray(); //check for optimality if (lambda.All(l => l >= 0)) return (Vector) x; //Find leaving index r (first index where component < 0) var r = lambda.Select((i, index) => new {i, index}) .Where((i, index) => i.i < 0) .First().index; //compute direction to move int - take r-th column var d = ABi.Column(r)*(-1); //Determine the set K (all indexes of positive values of lambda) //all k that a(k).T*d>0, 1 <= i <=m var K = new List<int>(); for (int k = 0; k < m; k++) { var val = A.Row(k)*d; if (val > 0 && !val.FloatEquals(0)) K.Add(k); } if (K.Count == 0) throw new SimplexException("Problem is unbounded") {Iteration = iteration}; //Find entering index e int e = 0; var v = double.MaxValue; foreach (var k in K) { var w = (b[k] - A.Row(k)*x)/(A.Row(k)*d); if (!(w < v)) continue; v = w; e = k; } //Update basis B.InequalityIndexes[r] = e; AB.SetRow(r, A.Row(e)); bB[r] = b[e]; //Trick - lets update inverse AB in a smart way - sinse there is only one new inequality we only need to //compute new inversed row (should drop complexity of whole algo to n*n) var f = AB.Row(r)*ABi; var g = -f; g[r] = 1; g /= f[r]; g[r] -= 1; ABi = ABi.Add(ABi.Column(r).ToColumnMatrix()*g.ToRowMatrix()); //Compute new x x = x + v*d; } }