Пример #1
0
        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;
        }
Пример #2
0
        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;
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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);
        }
Пример #5
0
        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;
        }
Пример #6
0
 public double[][] f21b(BigTableau bt, double[] b, double[] bBar)
 {
     return Simplex.F21b(bt, b, bBar);
 }
Пример #7
0
        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;
        }
Пример #8
0
        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;
        }
Пример #9
0
        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);
        }
Пример #10
0
        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;
        }
Пример #11
0
        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;
        }
Пример #12
0
        private string Print(BigTableau bt)
        {
            StringBuilder sb = new StringBuilder();

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

            sb.Append("<tr><td class='header first'>&nbsp;</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();
        }
Пример #13
0
 public double[] simplex2(BigTableau bt)
 {
     Simplex.SolveBig(bt, notify);
     return bt.MakeSolution();
 }
Пример #14
0
 public double[][] f21c(BigTableau bt, double[] c, double[] cBar)
 {
     return Simplex.F21c(bt, c, cBar);
 }
Пример #15
0
 public static void SolveBig(BigTableau ct)
 {
     SolveBig(ct, null);
 }
Пример #16
0
        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;
        }
Пример #17
0
        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++;
            }
        }
Пример #18
0
        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();
        }