Rsolnp
非线性规划问题
$$ \begin{align} \min \quad & f(x)\ \text { s.t. } & \begin{cases} \{l_{h} \leq h(x) \leq u_{h}} \ {l_{x} \leq x \leq u_{x}} \end{cases} \end{align}
$$
其中, $f(x),g(x),h(x)$ 都是光滑函数,
solnp(pars, fun, eqfun = NULL, eqB = NULL, ineqfun = NULL, ineqLB = NULL, ineqUB = NULL, LB = NULL, UB = NULL, control = list(), ...)
pars : 初始值(向量),
fun : 最小化的目标函数值,输入为pars参数,输出为一个单一值,等价上述问题的f(x)
eqfun : (可选) 等式约束(左边) ,等价与上述问题的 g(x)
egB : (可选) 等式约束右边值,等价上述问题g(x) = 0 的0
ineqfun : (可选) 不等式约束,等价上述问题的 h(x)
ineqLB :(可选) 不等式约束的下限 ,等价于上述问题的 lh
ineqUB :(可选) 不等式约束的上限 ,等价于上述问题的 uh
LB :(可选) 参变量的下限 ,等价于上述问题的lx
UB: (可选) 参变量的上限 ,等价于上述问题的ux
control :(可选) 优化参数控制表。
例子: \( \begin{align} min \quad & exp({\prod_{i=1}^{5}x_i}) \\ s.t. \quad & x_1^2 +x_2^2 +x_3^2+x_4^2+x_5^2 = 10 \\ \quad & x_2x_3-5x_4x_5 = 0 \\ \quad & x_1^3 +x_2^3 = -1 \end{align} \)
# POWELL Problem
library(Rsolnp)
fn1=function(x){
exp(x[1]*x[2]*x[3]*x[4]*x[5])
}
eqn1=function(x){
z1=x[1]*x[1]+x[2]*x[2]+x[3]*x[3]+x[4]*x[4]+x[5]*x[5]
z2=x[2]*x[3]-5*x[4]*x[5]
z3=x[1]*x[1]*x[1]+x[2]*x[2]*x[2]
return(c(z1,z2,z3))
}
x0 = c(-2, 2, 2, -1, -1)
powell=solnp(x0, fun = fn1, eqfun = eqn1, eqB = c(10, 0, -1))
具体参考:https://cran.r-project.org/web/packages/Rsolnp/index.html
Rdonlp2
这个包有一定的问题,我在运行的时候第一次几乎都正常,能得到正确结果,第二次直接系统崩溃。
if(!require('Rdonlp2')) install.packages("Rdonlp2", repos="http://R-Forge.R-project.org")
模型格式如下: \( \begin{array}{l}{\min z=f(\mathbf{x})} \\ {\qquad \begin{array}{l}{\mathrm{x}_{1} \leqslant \mathrm{x} \leqslant \mathrm{x}_{\mathrm{u}}} \\ {\mathrm{b}_{1} \leqslant \mathrm{Ax} \leqslant \mathrm{b}_{\mathrm{u}}} \\ {\mathrm{c}_{1} \leqslant \mathrm{c}(\mathrm{x}) \leqslant \mathrm{c}_{\mathrm{u}}}\end{array}}\end{array} \) 具体可参考: (R软件在最优化中的应用)[]
Matlab:: fmincon
可参考 官网函数解释https://www.mathworks.com/help/optim/ug/fmincon.html
https://wenku.baidu.com/view/6bcb651d0b4e767f5acfce97.html?sxts=1561344526517
https://blog.csdn.net/qq_38784454/article/details/80329021
《MATLAB数学建模》李昕——清华大学出版
example
\[ \begin{array}{l} \min f(x) \\ \text {s.t.}\left\{\begin{array}{l} A \cdot x \leq b \\ \text {Aeq} \cdot x=beq \\ c(x) \leq 0 \\ \operatorname{ceq}(x)=0 \\ l b \leq x \leq u b \end{array}\right. \end{array}\\ f(x)是目标函数, x, b, beq是向量, \\ A, Aeq是矩阵\\ c(x) 和 ceq(x) 是向量函數 \]
% 2.基本语法
[x,fval]=fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon,options)
% 参数解释
x的返回值是决策向量x的取值,fval的返回值是目标函数f(x)的取值
fun是用M文件定义的函数f(x),代表了(非)线性目标函数
x0是x的初始值
A,b,Aeq,beq定义了线性约束 ,如果没有线性约束,则A=[],b=[],Aeq=[],beq=[]
lb和ub是变量x的下界和上界,如果下界和上界没有约束,则lb=[],ub=[],也可以写成lb的各分量都为 -inf,ub的各分量都为inf
nonlcon是用M文件定义的非线性向量函数约束
options定义了优化参数,不填写表示使用Matlab默认的参数设置
例
\[ \min f(x) = x_{1}^{2}+x_{2}^{2}+x_{3}^{2}+8 \\ \text { s. t. }\left\{\begin{array}{l} x_{1}^{2}-x_{2}+x_{3}^{2} \geq 0 \\ x_{1}+x_{2}^{2}+x_{3}^{2} \leq 20 \\ -x_{1}-x_{2}^{2}+2=0 \\ x_{2}+2 x_{3}^{2}=3 \\ x_{1}, x_{2}, x_{3} \geq 0 \end{array}\right. \]
clc,clear all
x0 = rand(3,1); % 初始值
Aeq = []; % 线性等式约束的系数(左边的系数)
beq = []; % 线性等式约束的值 (右边的值)
%A = []; % 线性不等式约束的系数
%b = []; % 线性等式约束的值
ub = []; % 变量的上限(取等号)
lb = repelem(0,3); % 变量的下限(取等号)
[x,y]=fmincon(@myobjfun,x0,[],[],Aeq,beq,lb,ub,@constrain)
function f = myobjfun(x)
f=x(1).^2+x(2).^2+x(3).^2+8;
end
function [g,h]=constrain(x)
g=[-x(1).^2+x(2)-x(3).^2
x(1)+x(2).^2+x(3).^3-20]; % 不等式
h=[-x(1)-x(2).^2+2
x(2)+2*x(3).^2-3]; % 等式约束
end
也可以这样写
(1)编写M函数myobjfun.m 定义目标函数:
function f=myobjfun(x)
f=x(1).^2+x(2).^2+x(3).^2+8;
end
(2)编写M函数constrain.m定义非线性约束条件:
function [g,h]=constrain(x)
g=[-x(1).^2+x(2)-x(3).^2
x(1)+x(2).^2+x(3).^3-20];
h=[-x(1)-x(2).^2+2
x(2)+2*x(3).^2-3];
end
(3)编写主程序函数
[x,y]=fmincon('fun1',rand(3,1),[],[],[],[],zeros(3,1),[],'fun2')
运行即可得到结果
参考 : https://www.cnblogs.com/goodtwo/p/11146540.html
常用非线性规划模型(我)
\[ \begin{align} Min \quad & \sum_{i=1}^{n} \sum_{j=1}^{n}\left(\omega_{i}-a_{i j} \omega_{j}\right)^{2}\\ s.t \quad & \sum_{i=1}^{n} \omega_{i}=1,\\ & 1\geq \omega_{i} \geq 0, \quad i=1,2, \ldots, n \end{align} \]
于是自己写了几个函数模板:
R
library(Rsolnp)
## 最小化的目标函数
obj=function(x){
A1 = matrix(c(1,4,3,1,3,4,
1/4,1,7,3,1/5,1,
1/3,1/7,1,1/5,1/5,1/6,
1,1/3,5,1,1,1/3,
1/3,5,5,1,1,3,
1/4,1,6,3,1/3,1),ncol = 6,nrow = 6,byrow = T)
s = 0
n = nrow(A1)
for(i in 1:n){
for(j in 1:n){
s= s+ (x[i]- A1[i,j]*x[j])^2;
}
}
return(s)
}
## 编写解上述非线性规划的函数
fmin = function(f,n){# n代表参数的个数
eqn1=function(x){
sum(x)
} # 等式约束的左边 ,eqB 为等式约束的右边,如果有多个则用向量
powell=solnp(pars= rep(1/n,n), fun = f, eqfun = eqn1, eqB = 1,LB= rep(0,n) ,UB = rep(1,n))
fx = powell$values
x = powell$pars
return( list('x' = x, 'fx' = fx[length(fx)]) )
}
fmin(obj,n = 6) #调用即可,n代表参数的个数
########################################
library(Rdonlp2)
objFun = function(x){
A1 = matrix(c(1,4,3,1,3,4,
1/4,1,7,3,1/5,1,
1/3,1/7,1,1/5,1/5,1/6,
1,1/3,5,1,1,1/3,
1/3,5,5,1,1,3,
1/4,1,6,3,1/3,1),ncol = 6,nrow = 6,byrow = T)
s = 0
n = nrow(A1)
for(i in 1:n){
for(j in 1:n){
s= s+ (x[i]- A1[i,j]*x[j])^2;
}
}
return(s)
}
fmin = function(objFun,n){ # 这里n为未知参数的个数.
x0 = rep(1/n,n)
lb = rep(0,n) # 自变量的下限
ub = rep(1,n) # 自变量的上限
Aeq = matrix(rep(1,n),1,n)
lbeq = 1
ubeq = 1
ret = donlp2(x0,objFun,par.lower = lb , par.upper = ub,A = Aeq,lin.lower = lbeq,lin.upper = ubeq)
list('x' = ret$par,'objvalue' = ret$fx)
}
fmin(objFun,n = 6)# 只需要改写objFun 就可以了
Matlab
把上述文件存储为fmin.m
,以后只需要更改目标函数myobjfun(x,AA)
即可,其中x代表未知数, AA 代表目标函数的系数,
function x = fmin(AA) % 调用函数接口
n = size(AA,1) ; % 未知数x的长度
x0 = repelem(1/n,n); % 初始迭代位置
Aeq = repelem(1,n); % 线性等式约束的系数(左边的系数)
beq = 1; % 线性等式约束的值 (右边的值)
%A = []; % 线性不等式约束的系数
%b = []; % 线性等式约束的值
ub = repelem(1,n); % 变量的上限(取等号)
lb = repelem(0,n); % 变量的下限(取等号)
[x,fval] = fmincon(@(x)myobjfun(x,AA),x0,[],[],Aeq,beq,lb,ub);
%[x,fval] = fmincon(@myobjfun,x0,[],[],Aeq,beq,lb,ub,[],[],options,A);
end
% 目标函数
function s = myobjfun(x,AA)
n = size(AA,1);
s =0;
for i = 1:n
for j = 1:n
s= s+ (x(i)- AA(i,j)*x(j))^2;
end
end
end