为了账号安全,请及时绑定邮箱和手机立即绑定

基于线性方程计算值的算法

基于线性方程计算值的算法

ibeautiful 2022-11-02 15:09:21
我正在使用java基于线性方程计算PayStructure中各种Paycodes的值。我的不同方程如下:CTC = Fixed ValueBasic = CTC * 0.4HRA = Basic/2ConveyanceAllowance = Fixed ValueProvidentFund = Basic * 0.12Gratuity = Basic * .0481OtherAllowance = (CTC - (Basic + HRA + ConveyanceAllowance + ProvidentFund + Gratuity))我试过使用这里给出的解决方案。但是这个解决方案只有在所有计算值都是整数的情况下才有效,在我的情况下,这些值也可以包含十进制数字。我根据上述条件修改的代码如下:public class PayStructure {    public static void main(String[] args) {        findAndprintSolutions(1, 1000000);    }    private static void findAndprintSolutions(int from, int to) {        for (int a = from; a < to; a++) {            for (int b = from; b < to; b++) {                for (int c = from; c < to; c++) {                    for (int d = from; d < to; d++) {                        for (int e = from; e < to; e++) {                            for (int f = from; f < to; f++) {                                for (int g = from; g < to; g++) {                                    if (isSolution(a, b, c, d, e, f, g))                                        printSolution(new int[] { a, b, c, d, e, f, g });                                }                            }                        }                    }                }            }        }    }    private static boolean isSolution(int a, int b, int c, int d, int e, int f, int g) {        if (a != 100000)            return false;        if (b != a * (.4))            return false;        if (c != b / 2)            return false;        if (d != 10000)            return false;        if (e != b * (.12))            return false;        if (f != b * (.0481))            return false;        if (g != (a - (b + c + d + e + f)))            return false;        return true;    }此外,上述代码将被终止,因为 CTC 的最大值可能是数百万,并且根据变量的数量,时间复杂度最终会达到millions^NumberOfVariables. 是否有任何其他可能性来计算基于给定方程的值?方程和变量的数量可能会有所不同,但会有一个解决方案来计算每个变量的值,因此通用解决方案的任何输入都会更好。
查看完整描述

3 回答

?
慕的地8271018

TA贡献1796条经验 获得超4个赞

也许您最好的选择是弄清楚如何将其转化为形式的线性方程组的形式c[1]x[1] + c[2]x[2] … + c[n]x[n] = 0。从那里,您可以使用广泛建立的线性系统技术来求解系统。有关大量信息,请参阅Wikipedia页面。您可以让用户以这种形式为您的方法提供输入,或者您可以对每个方程进行少量处理以对其进行转换(例如,如果所有方程在 LHS 上都有一个变量,如您的示例所示,则翻转签名并将其放在 RHS 的末尾)。

解释求解线性方程组的理论超出了这个答案的范围,但基本上,如果有一个有效的分配,你的系统要么是唯一确定的,如果不存在有效的分配是过度确定的,或者如果有无限多的分配是可能的. 如果有一个独特的任务,你会得到数字;如果系统未确定,您至少会得到一组约束,这些约束必须包含无限多个解决方案中的任何一个;如果不确定,您将一无所获并且知道原因。


查看完整回答
反对 回复 2022-11-02
?
隔江千里

TA贡献1906条经验 获得超10个赞

使用 Java 的一些线性代数库例如,使用此处记录的矩阵运算求解线性方程组。您的深层嵌套循环太慢了,有更好的算法可用。



查看完整回答
反对 回复 2022-11-02
?
慕码人8056858

TA贡献1803条经验 获得超6个赞

这就是我解决这个问题的方法。首先,我通过将所有变量放在左侧并将值 & 0 放在右侧来创建方程:


CTC = 1000000

(0.4)CTC - Basic = 0

(0.5)Basic-HRA = 0

ConvAll = 10000

(0.12)Basic-PF = 0

(0.0481)Basic - Gratuity = 0

CTC - (Basic + HRA + ConvAll + PF+ Gratuity + OtherAll) = 0

然后我创建了一个这样的矩阵:


|1          0     0    0   0   0   0| |CTC     | = |1000000|

|0.4       -1     0    0   0   0   0| |Basic   | = |0      |

|0         0.5   -1    0   0   0   0| |HRA     | = |0

|0          0     0    1   0   0   0| |ConvAll | = |10000  |

|0         0.12   0    0  -1   0   0| |PF      | = |0      |

|0        0.0481  0    0   0  -1   0| |Gratuity| = |10000  |

|1         -1    -1   -1  -1  -1  -1| |OtherAll| = |0      |

在此之后,我计算了(上面第一个矩阵的逆)和(最右边的矩阵)的乘积,并使用下面的代码得到了每个分量的相应值:


public class Matrix


{

    static int n = 0;


    public static void main(String argv[]) {

        Scanner input = new Scanner(System.in);

        System.out.println("Enter the dimension of square matrix: ");


        n = input.nextInt();

        double a[][] = new double[n][n];

        System.out.println("Enter the elements of matrix: ");

        for (int i = 0; i < n; i++)

            for (int j = 0; j < n; j++)

                a[i][j] = input.nextDouble();

        double d[][] = invert(a);

        System.out.println();

        System.out.println("Enter the equation values: ");

        System.out.println();

        double b[][] = new double[n][1];

        for (int i = 0; i < n; i++) {

            b[i][0] = input.nextDouble();

        }


        double e[][] = multiplyMatrix(d, b);

        System.out.println();

        System.out.println("The final solution is: ");

        System.out.println();

        for (int i = 0; i < n; i++) {

            for (int j = 0; j < 1; j++) {

                System.out.printf(e[i][j] + " ");

            }

            System.out.println();

        }

        input.close();

    }


    public static double[][] invert(double a[][]) {

        int n = a.length;

        double x[][] = new double[n][n];

        double b[][] = new double[n][n];

        int index[] = new int[n];

        for (int i = 0; i < n; ++i)

            b[i][i] = 1;


        // Transform the matrix into an upper triangle

        gaussian(a, index);


        // Update the matrix b[i][j] with the ratios stored

        for (int i = 0; i < n - 1; ++i)

            for (int j = i + 1; j < n; ++j)

                for (int k = 0; k < n; ++k)

                    b[index[j]][k] -= a[index[j]][i] * b[index[i]][k];


        // Perform backward substitutions

        for (int i = 0; i < n; ++i) {

            x[n - 1][i] = b[index[n - 1]][i] / a[index[n - 1]][n - 1];

            for (int j = n - 2; j >= 0; --j) {

                x[j][i] = b[index[j]][i];

                for (int k = j + 1; k < n; ++k) {

                    x[j][i] -= a[index[j]][k] * x[k][i];

                }

                x[j][i] /= a[index[j]][j];

            }

        }

        return x;

    }


    // Method to carry out the partial-pivoting Gaussian


    // elimination. Here index[] stores pivoting order.


    public static void gaussian(double a[][], int index[]) {

        int n = index.length;

        double c[] = new double[n];


        // Initialize the index

        for (int i = 0; i < n; ++i)

            index[i] = i;


        // Find the rescaling factors, one from each row

        for (int i = 0; i < n; ++i) {

            double c1 = 0;

            for (int j = 0; j < n; ++j) {

                double c0 = Math.abs(a[i][j]);

                if (c0 > c1)

                    c1 = c0;

            }

            c[i] = c1;

        }


        // Search the pivoting element from each column

        int k = 0;


        for (int j = 0; j < n - 1; ++j) {

            double pi1 = 0;

            for (int i = j; i < n; ++i) {

                double pi0 = Math.abs(a[index[i]][j]);

                pi0 /= c[index[i]];

                if (pi0 > pi1) {

                    pi1 = pi0;

                    k = i;

                }

            }


            // Interchange rows according to the pivoting order

            int itmp = index[j];

            index[j] = index[k];

            index[k] = itmp;

            for (int i = j + 1; i < n; ++i) {

                double pj = a[index[i]][j] / a[index[j]][j];

                // Record pivoting ratios below the diagonal

                a[index[i]][j] = pj;

                // Modify other elements accordingly

                for (int l = j + 1; l < n; ++l)

                    a[index[i]][l] -= pj * a[index[j]][l];

            }

        }

    }


    public static double[][] multiplyMatrix(double a[][], double b[][]) {

        double c[][] = new double[n][1];

        for (int i = 0; i < n; i++) {

            for (int j = 0; j < 1; j++) {

                for (int k = 0; k < n; k++) {

                    c[i][j] = c[i][j] + a[i][k] * b[k][j];

                }

            }

        }

        return c;

    }

}

谢谢大家的线索。


查看完整回答
反对 回复 2022-11-02
  • 3 回答
  • 0 关注
  • 120 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信