用编程实现了工程数学共轭梯度法求解函数的极小点
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);
}
}以上实现了共轭梯度法求解函数极小点

浙公网安备 33010602011771号