0

我正在尝试在 java 中编写一个单纯形算法来进行分配。我的代码适用于某些输入,但算法经常陷入循环,从状态 A 重新计算到状态 B,然后返回到状态 A。进入无限循环。

起初我认为这是一个退化问题。但我实际上是在使用 Bland 的规则,进一步的头脑风暴和尝试调试让我意识到这是导致循环的约束不等式中的负系数。

所以我想我明白为什么会发生错误。但我不确定我应该如何改变我的算法来解决这个问题。

这是我的整个代码...

public class Main {

    // initialize tableau
    static double tableau[][] = new double[101][201];
    static int variable[] = new int[100];
    static int nCount, mCount, totalColumnCount;

    public static void main(String[] args) {
        try {
            // read from file
            Scanner s = new Scanner(new File("c:\\hw6\\input.txt"));

            // for formatting double values to two decimal places
            DecimalFormat oneDigit = new DecimalFormat("#,###0.00");

            // ----------------------------------------initialize tableau---------------------------------------------------
            // read number of n(variables) and m(constraints)
            nCount = s.nextInt();
            mCount = s.nextInt();
            totalColumnCount = nCount + mCount + 1;

            // fill variable[] with arbitrarily large values
            for (int j = 0; j < mCount; j++) {
                variable[j] = 200;
            }

            // get coefficients for objective function and store into tableau
            for (int j = 0; j < nCount; j++) {
                tableau[mCount][j] = -s.nextInt();
            }
            for (int j = nCount; j < nCount + mCount; j++) {
                tableau[mCount][j] = 0;
            }
            tableau[mCount][nCount + mCount] = 1; // value of MAX (P)
            tableau[mCount][nCount + mCount + 1] = 0; // RHS (which should be 0)

            // get coefficients of constraint inequalities
            for (int j = 0; j < mCount; j++) {
                for (int k = 0; k < nCount; k++) {
                    tableau[j][k] = s.nextInt();
                }
                for (int k = nCount; k < nCount + mCount; k++) {
                    if (k - nCount == j)
                        tableau[j][k] = 1;
                    else
                        tableau[j][k] = 0;
                }
                // get the RHS
                tableau[j][nCount + mCount + 1] = s.nextInt();
            }

            // store variables that each constraint refers to
            for (int j = 0; j < mCount; j++) {
                variable[j] = j + 1;
            }
            // ----------------------------------------initialize tableau---------------------------------------------------

            // look for any negative values in the objective function
            for (int j = 0; j <= totalColumnCount; j++) {
                if (tableau[mCount][j] < 0) {
                    Coordinate pivot = findPivot();
                    pivotTo1(pivot);
                    pivotColumnTo0(pivot);

                    // for checking that this iteration of converting constraints has been calculated correctly
                    for (int k = 0; k <= mCount; k++) {
                        System.out.print("[ ");
                        for (int l = 0; l <= totalColumnCount; l++) {
                            System.out.print(oneDigit.format(tableau[k][l]) + " ");
                        }
                        System.out.println(" ]");
                    }
                    System.out.println();

                    // repeat looking for any negative values in the objective function
                    j = 0;
                    continue;
                }
            }
            // get solutions
            getSolution();

        } catch (IOException e) {
            System.out.println(e);
        }
    }

    public static Coordinate findPivot() {
        double currentMinColumn = Integer.MAX_VALUE;
        double currentCalculation = Integer.MAX_VALUE;
        int pivotColumn = 0;
        int pivotRow = 0;

        // find pivot column
        for (int i = 0; i < totalColumnCount; i++) {
            if (currentMinColumn > tableau[mCount][i]) {
                currentMinColumn = tableau[mCount][i];
                pivotColumn = i;
            }
        }

        // find pivot
        for (int i = 0; i < mCount; i++) {
            if (currentCalculation > tableau[i][totalColumnCount] / tableau[i][pivotColumn]) {
                currentCalculation = tableau[i][totalColumnCount] / tableau[i][pivotColumn];
                pivotRow = i;
            }
        }

        // return coordinate of pivot value
        return new Coordinate(pivotRow, pivotColumn);
    }

    public static void pivotTo1(Coordinate pivot) {
        double pivotValue = tableau[pivot.row()][pivot.column()];

        // find factor to multiply to pivot's row to convert pivot to 1
        double multFactor = 1.0 / pivotValue;

        // convert the pivot's row
        for (int i = 0; i <= totalColumnCount; i++) {
            tableau[pivot.row()][i] *= multFactor;
        }

        // update variable for the constraint
        variable[pivot.row()] = pivot.column();
    }

    public static void pivotColumnTo0(Coordinate pivot) {
        double multFactor = 0;

        // for all constraints
        for (int i = 0; i < mCount + 1; i++) {
            // skip constraint containing pivot
            if (i == pivot.row())
                continue;

            // get multFactor of constraint
            multFactor = -tableau[i][pivot.column()];

            // update each constraint by making pivot column values become zero
            for (int j = 0; j <= totalColumnCount; j++) {
                tableau[i][j] = tableau[i][j] + (multFactor * tableau[pivot.row()][j]);
            }
        }
    }

    public static void getSolution() {
        int solutionExists;

        // for all variables
        for (int i = 0; i < nCount; i++) {
            solutionExists = 0;

            // for all variables in the variable[] array
            for (int j = 0; j < mCount; j++) {
                // if the variable exists in the variable[] array print the value
                if (i == variable[j]) {
                    System.out.println(tableau[j][totalColumnCount]);
                    solutionExists = 1;
                    break;
                }
            }
            // if it does not exist print 0
            if (solutionExists == 0) {
                System.out.println(0);
            }
        }
    }
}

(我本来希望只发布相关的代码片段,这样你们就不会那么费力地试图破译这个,我认为你们无论如何都需要整个代码来找到我的错误在哪里。我试图尽可能具体地发表评论。)

我将此视频用作理解单纯形法的参考:https ://www.youtube.com/watch?v=gRgsT9BB5-8

input.txt 如下所示:

这个有效

3 3         // number of variables (n), number of constraints (m)
6 5 4       // objective function:      6x1 + 5x2 + 4x3
2 1 1 180   // constraint 1:            2x1 + 1x2 + 1x3 <= 180
1 3 2 300
2 1 2 240

给出解决方案

48.0
84.0
0

这个不行

2 2
2 5
2 -1 4
-1 2 9

任何帮助或建议将不胜感激。非常感谢!

4

0 回答 0