public static bool IsGoodColumn(BigTableau bt, int i) { int j = bt.ind[i]; if (bt.t[bt.m][j] > double.Epsilon) { return false; } if (Math.Abs(bt.t[i][j] - 1.0) > double.Epsilon) { return false; } for (int k = 0; k < bt.m; k++) { if (k != i && bt.t[k][j] > double.Epsilon) { return false; } } return true; }
public static double[][] F21c(BigTableau bt, double[] c, double[] cBar) { int m = bt.m; int n = bt.n; int nVar = n - m; double[][] t = bt.t; int[] nonBase = GetNonBaseIndices(bt.ind, m, n, nVar); double[][] limits = new double[m][]; for (int i = 0; i < m; i++) { limits[i] = new double[3]; limits[i][0] = double.NegativeInfinity; limits[i][1] = c[i]; limits[i][2] = double.PositiveInfinity; } for (int lineIndex = 0; lineIndex < m; lineIndex++) { int i = bt.ind[lineIndex]; // Skip the ones which aren't original variables. if (i >= m) { continue; } double zi = t[m][i] - c[i] + cBar[i]; ComputeCInterval(i, nVar, lineIndex, m, c, zi, t, limits, nonBase); } return limits; }
public static void FixBigRestartedTableau(BigTableau bt, Action<string, object> notify) { for (var i = 0; i < bt.m; i++) { if (!IsGoodColumn(bt, i)) { Pivot(bt, i, bt.ind[i]); if (notify != null) { notify("After pivoting " + (i + 1) + "," + (bt.ind[i] + 1) + ":", bt); } } else { if (notify != null) { notify("Not pivoting:", i + 1); } } } if (notify != null) { notify("After pivoting:", bt); } for (var i = 0; i < bt.m; i++) { if (bt.t[i][bt.n] <= 0) { throw new InfeasibleProblemException(); } } bool done = true; for (var j = 0; j < bt.n; j++) { if (bt.t[bt.m][j] < 0) { done = false; break; } } if (done) { return; } SolveBig(bt, notify); if (notify != null) { notify("After solving:", bt); } }
public static BigTableau EliminateArtificials(BigTableau bt, ArtEqSimplexProblem p, EqSimplexProblem pOrig) { int nVars = bt.n - bt.m; int n2 = bt.n - p.art.Length; double[][] t = new double[bt.m + 1][]; for (int i = 0; i <= bt.m; i++) { t[i] = new double[n2 + 1]; } int k = 0; for (int j = 0; j < bt.n; j++) { if (j >= nVars && p.baseVar[j - nVars] == -1) { continue; } for (int i = 0; i < bt.m; i++) { t[i][k] = bt.t[i][j]; } k++; } // Copy RHS. for (int i = 0; i < bt.m; i++) { t[i][n2] = bt.t[i][bt.n]; } // Restoring the indices. int[] ind = (int[])bt.ind.Clone(); for (int i = 0; i < ind.Length; i++) { if (ind[i] >= nVars) { ind[i] = p.baseVar[ind[i] - nVars]; } } bool[] nonBase = NonBase2(ind, n2); // Solving the new objective function. for (int j = 0; j <= n2; j++) { if (!nonBase[j]) { continue; } for (int i = 0; i < bt.m; i++) { Console.WriteLine(j + " " + i + " ::: " + ind[i] + " " + t[i][j] + " " + pOrig.c[ind[i]]); t[bt.m][j] += t[i][j] * pOrig.c[ind[i]]; } } return new BigTableau(bt.m, n2, t, ind); }
public static double[][] F21b(BigTableau bt, double[] b, double[] bBar) { int m = bt.m; int n = bt.n; int nVar = n - m; double[][] t = bt.t; double[][] limits = new double[m][]; double rhsj; for (int j = 0; j < m; j++) { // For this b_j compute the RHS[j]. rhsj = 0.0; for (int k = 0; k < m; k++) { // Skip the fixed j. if (j != k) { rhsj += t[j][nVar + k] * b[k]; } } // Add in the modified value. rhsj += t[j][nVar + j] * bBar[j]; limits[j] = new double[3]; ComputeBInterval(t, j, m, n, nVar, rhsj, b, limits); } return limits; }
public double[][] f21b(BigTableau bt, double[] b, double[] bBar) { return Simplex.F21b(bt, b, bBar); }
public static BigTableau CreateBigTableau(ArtEqSimplexProblem p, Action<string, object> notify) { if (notify != null) { notify("Problem:", p); } int m = p.A.Length; int n = p.c.Length; int nVars = n - m; double[][] t = new double[m + 1][]; for (int i = 0; i < m; i++) { t[i] = new double[n + 1]; Array.Copy(p.A[i], t[i], n); t[i][n] = p.b[i]; } t[m] = new double[n + 1]; for (int i = 0; i < n; i++) { t[m][i] = -p.c[i]; } int[] ind = new int[m]; for (int i = 0; i < ind.Length; i++) { ind[i] = nVars + i; } BigTableau bt = new BigTableau(m, n, t, ind); if (notify != null) { notify("Artificial tableau before new objectives:", bt); } // Solving the new objective function. for (int j = 0; j <= n; j++) { t[m][j] = 0; } for (int i = 0; i < p.art.Length; i++) { for (int j = 0; j < m; j++) { t[m][j] -= t[p.art[i] - nVars][j]; } t[m][n] -= t[p.art[i] - nVars][n]; } if (notify != null) { notify("Artificial tableau after new objectives:", bt); } return bt; }
private static void Pivot(BigTableau bt, int k, int l) { double[][] t = bt.t; for (int i = 0; i <= bt.m; i++) { if (i == k) { continue; } for (int j = 0; j <= bt.n; j++) { if (j == l) { continue; } t[i][j] = (t[i][j] * t[k][l] - t[i][l] * t[k][j]) / t[k][l]; } } for (int i = 0; i <= bt.m; i++) { if (i != k) { t[i][l] = 0; } } for (int j = 0; j <= bt.n; j++) { if (j != l) { t[k][j] /= t[k][l]; } } t[k][l] = 1; // Change indices. bt.ind[k] = l; }
public static BigTableau CreateBigRestartedTableau(BigTableau bt, SimplexProblem p) { int m = bt.m; int n = bt.n; int nVar = n - m; double[][] t1 = bt.t; double[][] t2 = new double[m + 1][]; // Allocating new matrix and setting the middle S* and y*T. for (int i = 0; i <= m; i++) { t2[i] = new double[n + 1]; Array.Copy(t1[i], nVar, t2[i], nVar, m); } // Setting S*b. double sum; for (int i = 0; i < m; i++) { sum = 0.0; for (int j = 0; j < m; j++) { sum += t1[i][nVar + j] * p.b[j]; } t2[i][n] = sum; } // Setting y*Tb. sum = 0.0; for (int j = 0; j < m; j++) { sum += t1[m][nVar + j] * p.b[j]; } t2[m][n] = sum; // Setting S*A. for (int i = 0; i < m; i++) { for (int j = 0; j < nVar; j++) { sum = 0.0; for (int k = 0; k < nVar; k++) { sum += t1[i][nVar + k] * p.A[k][j]; } t2[i][j] = sum; } } // Setting y*TA-cT. for (int j = 0; j < nVar; j++) { sum = 0.0; for (int i = 0; i < m; i++) { sum += t1[m][nVar + i] * p.A[i][j]; } t2[m][j] = sum - p.c[j]; } // Copying the labels. int[] ind = new int[m]; Array.Copy(bt.ind, ind, m); return new BigTableau(m, n, t2, ind); }
private static int ChooseColumnBland(BigTableau bt) { for (int j = 0; j < bt.n; j++) { if (bt.t[bt.m][j] < 0) { return j; } } return -1; }
private static int ChooseRow(BigTableau bt, int l) { int k = -1; double tkmin = double.MaxValue; double[][] t = bt.t; for (int i = 0; i < bt.m; i++) { if (t[i][l] > 0) { double tk = t[i][bt.n] / t[i][l]; if (tk < tkmin) { tkmin = tk; k = i; } } } return k; }
private string Print(BigTableau bt) { StringBuilder sb = new StringBuilder(); sb.Append("<table class='big-tableau'>"); sb.Append("<tr><td class='header first'> </td>"); for (int j = 0; j < bt.n; j++) { sb.AppendFormat("<td class='header'>x<sub>{0}</sub></td>", j + 1); } sb.Append("<td class='header last'>RHS</td></tr>"); for (int i = 0; i < bt.m; i++) { sb.AppendFormat("<tr><td class='first'>x<sub>{0}</sub></td>", bt.ind[i] + 1); for (int j = 0; j < bt.n; j++) { sb.AppendFormat("<td>{0:0.###}</td>", bt.t[i][j]); } sb.AppendFormat("<td class='last'>{0:0.###}</td></tr>", bt.t[i][bt.n]); } sb.Append("<tr><td class='footer first'>z</td>"); for (int j = 0; j < bt.n; j++) { sb.AppendFormat("<td class='footer'>{0:0.###}</td>", bt.t[bt.m][j]); } sb.AppendFormat("<td class='footer last'>{0:0.###}</td></tr>", bt.t[bt.m][bt.n]); return sb.ToString(); }
public double[] simplex2(BigTableau bt) { Simplex.SolveBig(bt, notify); return bt.MakeSolution(); }
public double[][] f21c(BigTableau bt, double[] c, double[] cBar) { return Simplex.F21c(bt, c, cBar); }
public static void SolveBig(BigTableau ct) { SolveBig(ct, null); }
public static BigTableau CreateBigTableau(SimplexProblem p, Action<string, object> notify) { if (notify != null) { notify("Problem:", p); } int m = p.A.Length; int nVars = p.A[0].Length; int n = m + nVars; double[][] t = new double[m + 1][]; for (int i = 0; i < m; i++) { t[i] = new double[n + 1]; Array.Copy(p.A[i], t[i], nVars); t[i][nVars + i] = 1; t[i][n] = p.b[i]; } t[m] = new double[n + 1]; for (int i = 0; i < nVars; i++) { t[m][i] = -p.c[i]; } int[] ind = new int[m]; for (int i = 0; i < ind.Length; i++) { ind[i] = nVars + i; } BigTableau bt = new BigTableau(m, n, t, ind); if (notify != null) { notify("Created tableau:", bt); } return bt; }
public static void SolveBig(BigTableau ct, Action<string, object> notify) { int iter = 1; while (true) { int l = ChooseColumnBland(ct); if (l == -1) { break; // The optimal solution was found. } int k = ChooseRow(ct, l); if (k == -1) { throw new UnboundedProblemException(); } Pivot(ct, k, l); if (notify != null) { notify("After iteration " + iter, ct); } iter++; } }
public double[] simplex2Restart(BigTableau old, SimplexProblem p) { BigTableau bt2 = Simplex.CreateBigRestartedTableau(old, p); if (notify != null) { notify("Before pivoting:", bt2); } Simplex.FixBigRestartedTableau(bt2, notify); return bt2.MakeSolution(); }