R语言带回溯梯度下降法求解Hilbert矩阵二次优化报错如何解决
问题修复方案
报错Error in g(x) : could not find function "g"的核心原因是你将梯度g和目标函数f定义为了固定表达式而非可调用函数,R会将其识别为普通变量而非可传入参数执行的函数,因此无法通过g(x)的形式调用。
除该报错外,原代码还存在多处逻辑和语法错误,一并修复如下:
修复后的完整代码
# 加载依赖包,hilbert.matrix来自matrixcalc包 library(matrixcalc) # 定义5阶Hilbert矩阵 A <- hilbert.matrix(5) # 带回溯线搜索的梯度下降函数 dec_gradient <- function(f, g, x_0, s, alpha, beta, epsilon) { x <- x_0 grad <- g(x) fun_val <- f(x) iter <- 0 while(norm(grad, type = "2") > epsilon) { iter <- iter + 1 t <- s # 回溯线搜索:找满足Armijo条件的步长t while (f(x - t*grad) > fun_val - alpha * t * norm(grad, type = "2")^2) { t <- beta * t } # 找到合适步长后再更新x、函数值和梯度 x <- x - t * grad fun_val <- f(x) grad <- g(x) # 打印迭代信息 print(paste0('iter_number = ', iter, ' norm_grad = ', round(norm(grad),6), ' fun_val = ', round(fun_val,6))) } # 返回迭代次数和最优解 return(list(iter_num = iter, optimal_x = x, optimal_val = fun_val)) } # 正确定义目标函数f:输入x返回二次型值 f <- function(x) { return(as.numeric(t(x) %*% A %*% x)) } # 正确定义梯度函数g:输入x返回梯度向量 g <- function(x) { return(2 * A %*% x) } # 参数设置 alpha <- 0.5 beta <- 0.5 s <- 1 epsilon <- 1e-4 # 定义初始点 x_0 <- matrix(c(1,2,3,4,5), ncol = 1) # 调用函数 result <- dec_gradient(f, g, x_0, s, alpha, beta, epsilon) # 输出结果 print("迭代次数:") print(result$iter_num) print("最优解x:") print(result$optimal_x) print("最优目标值:") print(result$optimal_val)
关键修改说明
- 将
f和g改为可传入参数x的函数,解决找不到函数g的报错 - 修正回溯线搜索逻辑:先试算步长直到满足Armijo条件,再更新x变量,避免步长试算阶段错误修改迭代值
- 调整
return位置到外层循环结束后,保证迭代完全执行 - 替换字符串拼接的
+为R中正确的paste0()函数 - 显式指定梯度范数为2范数,避免
norm()函数默认参数的歧义 - 函数返回结构化结果,同时输出迭代次数、最优解和最优目标值
内容的提问来源于stack exchange,提问作者Hilary H
相关产品推荐
相关产品推荐

