Beispiel #1
0
        private static void Pivot(CompactTableau ct, int k, int l)
        {
            double[][] t = ct.t;

            for (int i = 0; i <= ct.m; i++) {
                if (i == k) {
                    continue;
                }

                for (int j = 0; j <= ct.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 <= ct.m; i++) {
                if (i != k) {
                    t[i][l] = -t[i][l] / t[k][l];
                }
            }

            for (int j = 0; j <= ct.n; j++) {
                if (j != l) {
                    t[k][j] /= t[k][l];
                }
            }

            t[k][l] = 1 / t[k][l];

            // Change indices.
            int tmp = ct.ind[ct.n + k];
            ct.ind[ct.n + k] = ct.ind[l];
            ct.ind[l] = tmp;
        }
Beispiel #2
0
        private static int ChooseRow(CompactTableau ct, int l)
        {
            int k = -1;
            double tkmin = double.MaxValue;
            double[][] t = ct.t;

            for (int i = 0; i < ct.m; i++) {
                if (t[i][l] > 0) {
                    double tk = t[i][ct.n] / t[i][l];
                    if (tk < tkmin) {
                        tkmin = tk;
                        k = i;
                    }
                }
            }

            return k;
        }
Beispiel #3
0
        private static int ChooseRowBlandDual(CompactTableau ct)
        {
            for (int i = 0; i < ct.m; i++) {
                if (ct.t[i][ct.n] < 0) {
                    return i;
                }
            }

            return -1;
        }
Beispiel #4
0
        private static int ChooseColumnDual(CompactTableau ct, int k)
        {
            int l = -1;
            double tlmin = double.MaxValue;
            double[][] t = ct.t;

            for (int j = 0; j < ct.n; j++) {
                if (t[k][j] < 0) {
                    double tl = t[ct.m][j] / t[k][j];
                    if (tl < tlmin) {
                        tlmin = tl;
                        l = j;
                    }
                }
            }

            return l;
        }
Beispiel #5
0
        // Use this if you like infinite loops.
        private static int ChooseColumnMax(CompactTableau ct)
        {
            int l = 0;
            double max = Double.MinValue;
            double tmj;

            for (int j = 0; j < ct.n; j++) {
                tmj = ct.t[ct.m][j];
                if (tmj > 0 && tmj > max) {
                    max = tmj;
                    l = j;
                }
            }

            return l;
        }
Beispiel #6
0
 public static void SolveDual(CompactTableau ct)
 {
     SolveDual(ct, null);
 }
 public double[] simplex(CompactTableau ct)
 {
     Simplex.SolveFeasible(ct, notify);
     return ct.MakeSolution();
 }
        private string XNumber(CompactTableau ct, int j)
        {
            if (ct.hasU && ct.ind[j] == ct.ind.Length - 1) {
                return "u";
            }

            return "x<sub>" + (ct.ind[j] + 1) + "</sub>";
        }
Beispiel #9
0
 public static void SolveFeasible(CompactTableau ct)
 {
     SolveFeasible(ct, null);
 }
        private void PrintSimplexHeader(StringBuilder sb, CompactTableau ct)
        {
            sb.Append("<tr class='header'>");

            for (int j = 0; j < ct.n; j++) {
                sb.AppendFormat("<td>" + XNumber(ct, j) + "</td>");
            }

            sb.Append("<td class='rhs'>-1</td>");
            sb.Append("<td>&nbsp;</td>");

            sb.Append("</tr>");
        }
        private string PrintSimplexTableau(CompactTableau ct)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("<table class='simplex-tableau'>");

            PrintSimplexHeader(sb, ct);

            for (int i = 0; i < ct.m; i++) {
                sb.Append("<tr>");

                for (int j = 0; j < ct.n; j++) {
                    sb.AppendFormat("<td>{0:0.###}</td>", ct.t[i][j]);
                }

                sb.AppendFormat("<td class='rhs'>{0:0.###}</td>",
                        ct.t[i][ct.n]);
                sb.AppendFormat("<td class='last'>= -{0}</td>",
                        XNumber(ct, ct.n + i));

                sb.Append("</tr>");
            }

            PrintSimplexFooter(sb, ct);

            sb.Append("</table>");

            return sb.ToString();
        }
        private void PrintSimplexFooter(StringBuilder sb, CompactTableau ct)
        {
            sb.Append("<tr class='footer'>");

            for (int j = 0; j < ct.n; j++) {
                sb.AppendFormat("<td>{0:0.###}</td>", ct.t[ct.m][j]);
            }

            sb.AppendFormat("<td class='rhs'>{0:0.###}</td>",
                    ct.t[ct.m][ct.n]);
            sb.Append("<td class='last'>= z</td>");

            sb.Append("</tr>");
        }
        private string PrintDualTableau(CompactTableau ct)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("<table class='simplex-dual-tableau'>");

            for (int i = 0; i < ct.m; i++) {
                sb.Append("<tr>");

                sb.AppendFormat("<td class='first'>y<sub>{0}</sub></td>",
                        ct.ind[ct.n + i] + 1);

                for (int j = 0; j < ct.n; j++) {
                    sb.AppendFormat("<td>{0:0.###}</td>", ct.t[i][j]);
                }

                sb.AppendFormat("<td class='last'>{0:0.###}</td>",
                        ct.t[i][ct.n]);

                sb.Append("</tr>");
            }

            sb.Append("<tr>");
            sb.Append("<td class='vals first'>-1</td>");
            for (int j = 0; j < ct.n; j++) {
                sb.AppendFormat("<td class='vals'>{0:0.###}</td>",
                    ct.t[ct.m][j]);
            }
            sb.AppendFormat("<td class='vals last'>{0:0.###}</td>",
                    ct.t[ct.m][ct.n]);
            sb.Append("</tr>");

            sb.Append("<tr>");
            sb.Append("<td class='first'>&nbsp;</td>");
            for (int j = 0; j < ct.n; j++) {
                sb.AppendFormat("<td>= y<sub>{0}</sub></td>", ct.ind[j] + 1);
            }
            sb.AppendFormat("<td class='last'>= w</td>");
            sb.Append("</tr>");

            sb.Append("</table>");

            return sb.ToString();
        }
 private string Print(CompactTableau ct)
 {
     return ct.dual ? PrintDualTableau(ct) : PrintSimplexTableau(ct);
 }
Beispiel #15
0
        public static CompactTableau CreateDualTableau(SimplexProblem p,
            Action<string, object> notify)
        {
            if (notify != null) {
                notify("Problem:", p);
            }

            int m = p.A[0].Length;
            int n = p.A.Length;

            double[][] t = new double[m + 1][];

            for (int i = 0; i < m; i++) {
                t[i] = new double[n + 1];
                for (int j = 0; j < n; j++) {
                    t[i][j] = p.A[j][i];
                }
                t[i][n] = p.c[i];
            }
            t[m] = new double[n + 1];
            Array.Copy(p.b, t[m], n);

            int[] ind = new int[n + m];
            for (int j = 0; j < n; j++) {
                ind[j] = m + j;
            }
            for (int i = 0; i < m; i++) {
                ind[n + i] = i;
            }

            CompactTableau ct = new CompactTableau(m, n, t, ind, false);
            ct.dual = true;
            if (notify != null) {
                notify("Created dual tableau:", ct);
            }

            return ct;
        }
Beispiel #16
0
        public static void TransformToFeasible(CompactTableau ct, double[] c)
        {
            ct.n--;

            double[][] t = ct.t;
            int[] ind = ct.ind;
            int m = ct.m;
            int n = ct.n;

            int uIndex = ind.Length - 1;

            // Checking the position of the u in the columns.
            int uPos = -1;
            for (int i = 0; i <= n; i++) {
                if (ind[i] == uIndex) {
                    uPos = i;
                    break;
                }
            }

            if (uPos == -1) {
                throw new InfeasibleProblemException();
            }

            // Removing the column.
            for (int i = 0; i < m; i++) {
                for (int j = uPos; j <= n; j++) {
                    t[i][j] = t[i][j + 1];
                }
            }

            // Removing the extra index.
            for (int j = uPos; j < uIndex; j++) {
                ind[j] = ind[j + 1];
            }

            // Solving the new objective function.
            for (int j = 0; j < n; j++) {
                t[m][j] = (ind[j] < n) ? c[ind[j]] : 0;
            }
            t[m][n] = 0;

            for (int i = 0; i < m; i++) {
                if (ind[n + i] < n) {
                    for (int j = 0; j <= n; j++) {
                        t[m][j] -= c[ind[n + i]] * t[i][j];
                    }
                }
            }

            ct.hasU = false;
        }
Beispiel #17
0
        public static void PivotInfeasibleTableau(CompactTableau ct)
        {
            int iMin = 0;
            double iValMin = ct.t[iMin][ct.n];

            for (int i = 1; i < ct.m; i++) {
                if (ct.t[i][ct.n] < iValMin) {
                    iValMin = ct.t[i][ct.n];
                    iMin = i;
                }
            }

            Pivot(ct, iMin, ct.n - 1);
        }
Beispiel #18
0
        private static int ChooseColumnBland(CompactTableau ct)
        {
            for (int j = 0; j < ct.n; j++) {
                if (ct.t[ct.m][j] > 0) {
                    return j;
                }
            }

            return -1;
        }
Beispiel #19
0
        public static void SolveDual(CompactTableau ct,
            Action<string, object> notify)
        {
            int iter = 1;

            while (true) {
                int k = ChooseRowBlandDual(ct);
                if (k == -1) {
                    break; // The optimal solution was found.
                }

                int l = ChooseColumnDual(ct, k);

                if (l == -1) {
                    throw new UnboundedProblemException();
                }

                Pivot(ct, k, l);

                if (notify != null) {
                    notify("After iteration " + iter + ":", ct);
                }
                iter++;
            }
        }
 public double[] simplexDual(CompactTableau ct)
 {
     Simplex.SolveDual(ct, notify);
     return ct.MakeDualSolution();
 }