用编程实现了工程数学共轭梯度法求解函数的极小点

import java.util.Arrays;

public class ConjugateGradientMethod {
public static void main(String[] args) {
double[] x = {0.0, 0.0, 0.0}; // 初始点
double epsilon = 1e-6;
int maxIterations = 1000;

    double[] prevX = null; // 初始化 prevX
    double[] d = null; // 搜索方向

    for (int k = 0; k < maxIterations; k++) {
        double[] gk = gradient(x); // 当前梯度
        double gNorm = norm(gk); // 梯度范数

        if (gNorm < epsilon) { // 判断是否收敛
            System.out.println("迭代次数:" + k);
            System.out.println("极小点:" + Arrays.toString(x));
            return;
        }

        if (k == 0) {
            d = Arrays.stream(gk).map(v -> -v).toArray(); // 初始搜索方向
        } else {
            double[] gkPrev = gradient(prevX); // 上一次梯度
            double beta = norm(gk) * norm(gk) / (norm(gkPrev) * norm(gkPrev)); // 计算 Beta
            d = new double[3];
            for (int i = 0; i < 3; i++) {
                d[i] = -gk[i] + beta * d[i]; // 更新搜索方向
            }
        }

        double alpha = calculateAlpha(x, d); // 计算步长
        prevX = x.clone(); // 保存当前点
        for (int i = 0; i < 3; i++) {
            x[i] += alpha * d[i]; // 更新点
        }
    }
    System.out.println("达到最大迭代次数,未找到极小点");
}

private static double[] gradient(double[] x) {
    double x1 = x[0], x2 = x[1], x3 = x[2];
    return new double[]{
        2 * x1 - 2 * x2 + 1,
        -2 * x1 + 4 * x2 - x3 + 3,
        2 * x3 - x2 - 1
    };
}

private static double norm(double[] arr) {
    double sum = 0;
    for (double v : arr) sum += v * v;
    return Math.sqrt(sum);
}

private static double calculateAlpha(double[] x, double[] d) {
    double x1 = x[0], x2 = x[1], x3 = x[2];
    double d1 = d[0], d2 = d[1], d3 = d[2];

    double a = 2 * d1 * d1 + 4 * d2 * d2 + 2 * d3 * d3 - 4 * d1 * d2 - 2 * d2 * d3;
    double b = 2 * d1 * (2 * x1 - 2 * x2 + 1) + 2 * d2 * (-2 * x1 + 4 * x2 - x3 + 3) + 2 * d3 * (2 * x3 - x2 - 1);
    return -b / (2 * a);
}

}以上实现了共轭梯度法求解函数极小点

posted @ 2025-04-01 21:04  Lomook  阅读(18)  评论(0)    收藏  举报