最大化二次目标函数受R中线性相等和不等式约束的影响

时间:2016-09-02 12:32:16

标签: r mathematical-optimization

我试图找到如何在R中使用相等和不等式约束来最大化二次函数:

最大化x' * H * x
受制于:Aeq * x = beq
A * x >= bx >= 0

问题的简化版本可能是

最大化x^2 + y^2
x + y = 1为准 和x, y >= 0

由于这是最大化问题,我无法在solve.QP包中使用quadprog功能。

我也尝试使用constrOptim。但请注意,存在一个等式约束,constrOptim需要在可行区域内部进行初始猜测。因此constrOptim不能用于等式约束。

我也尝试在auglag包中使用alabama。但我似乎没有得到最大化问题的正确答案。

如果问题是最小化问题,那么简单问题的答案是x = 0.5和y = 0.5。 auglagsolve.QP都给了我这个答案。

但我正在寻找最大化问题的解决方案。几何的答案位于(x = 1和y = 0)OR(x = 0和y = 1)。

2 个答案:

答案 0 :(得分:3)

这不是一个完整的答案,但可能会向您展示一些替代的算法方法。

问题

这个问题似乎是非凸的,这使得它难以解决(并限制了可用软件的数量)。

一般非线性优化

正如Christoph在评论中提到的,一般非线性优化是一种可能的方法。当然,我们失去了有关全球最佳解决方案的保证。在内部使用优秀的开源软件ipopt的东西将是一个很好的第一次尝试。

替代方案:凸 - 凹 - 凸 - 编程的区别

您可能会考虑凸凹编程(它解决了全局中的一些简单问题),它具有非常好的工作启发式,称为凸凹程序Yuille, Alan L., and Anand Rangarajan. "The concave-convex procedure." Neural computation 15.4 (2003): 915-936.),它应该更好地工作而不是更一般的非线性方法。

我不确定在R中是否有一种很好的方法(不用手工完成),但在Python中有一个非常现代的开源研究库dccp(基于{{ 3}})。

代码

from cvxpy import *
import dccp
from dccp.problem import is_dccp

x = Variable(1)
y = Variable(1)
constraints = [x >= 0, y >= 0, x+y == 1]
objective = Maximize(square(x) + square(y))
problem = Problem(objective, constraints)

print("problem is DCP:", problem.is_dcp())
print("problem is DCCP:", is_dccp(problem))

problem.solve(method='dccp')

print('solution (x,y): ', x.value, y.value)

输出

('problem is DCP:', False)
('problem is DCCP:', True)
iteration= 1 cost value =  -2.22820497851 tau =  0.005
iteration= 2 cost value =  0.999999997451 tau =  0.006
iteration= 3 cost value =  0.999999997451 tau =  0.0072
('solution (x,y): ', 0.99999999872569856, 1.2743612156911721e-09)

编辑/更新

根据问题的大小(小),您还可以尝试全局非线性求解器,例如cvxpy

代码

from pyomo.environ import *

model = ConcreteModel()

model.x = Var()
model.y = Var()

model.xpos = Constraint(expr = model.x >= 0)
model.ypos = Constraint(expr = model.y >= 0)
model.eq = Constraint(expr = model.x + model.y == 1)
model.obj = Objective(expr = model.x**2 + model.y**2, sense=maximize)

model.preprocess()

solver = 'couenne'
solver_io = 'nl'
stream_solver = True     # True prints solver output to screen
keepfiles =     True    # True prints intermediate file names (.nl,.sol,...)
opt = SolverFactory(solver,solver_io=solver_io)
results = opt.solve(model, keepfiles=keepfiles, tee=stream_solver)

print("Print values for all variables")
for v in model.component_data_objects(Var):
  print str(v), v.value

输出

Couenne 0.5.6 -- an Open-Source solver for Mixed Integer Nonlinear Optimization
Mailing list: couenne@list.coin-or.org
Instructions: http://www.coin-or.org/Couenne

Couenne: new cutoff value -1.0000000000e+00 (0.004 seconds)
NLP0012I 
              Num      Status      Obj             It       time                 Location
NLP0014I             1         OPT -0.5        6 0.004
Loaded instance "/tmp/tmpLwTNz1.pyomo.nl"
Constraints:            3
Variables:              2 (0 integer)
Auxiliaries:            3 (0 integer)

Coin0506I Presolve 11 (-1) rows, 4 (-1) columns and 23 (-2) elements
Clp0006I 0  Obj -0.9998 Primal inf 4.124795 (5) Dual inf 0.999999 (1)
Clp0006I 4  Obj -1
Clp0000I Optimal - objective value -1
Clp0032I Optimal objective -1 - 4 iterations time 0.002, Presolve 0.00
Clp0000I Optimal - objective value -1
NLP Heuristic: NLP0014I             2         OPT -1        5 0
no solution.
Clp0000I Optimal - objective value -1
Optimality Based BT: 0 improved bounds
Probing: 0 improved bounds
NLP Heuristic: no solution.
Cbc0013I At root node, 0 cuts changed objective from -1 to -1 in 1 passes
Cbc0014I Cut generator 0 (Couenne convexifier cuts) - 0 row cuts average 0.0 elements, 2 column cuts (2 active)
Cbc0004I Integer solution of -1 found after 0 iterations and 0 nodes (0.00 seconds)
Cbc0001I Search completed - best objective -1, took 0 iterations and 0 nodes (0.01 seconds)
Cbc0035I Maximum depth 0, 0 variables fixed on reduced cost

couenne: Optimal

    "Finished"

Linearization cuts added at root node:         12
Linearization cuts added in total:             12  (separation time: 0s)
Total solve time:                           0.008s (0.008s in branch-and-bound)
Lower bound:                                   -1
Upper bound:                                   -1  (gap: 0.00%)
Branch-and-bound nodes:                         0
Print values for all variables
x 0.0
y 1.0

答案 1 :(得分:-1)

您可以使用提供的来解决这个问题它可以处理非凸目标。两点:

  1. 要解决非线性等式约束的问题,您可以执行x + y >= 1x + y <= 1,这与x + y = 1相同。这同样适用于一般Aeq*x = bAeq*x <= bAeq*x >= b
  2. @jogo在评论中是对的:你只需要改变目标函数的符号。实际上,你是最大化非有界凸函数(即具有[半]正定Hessian矩阵),这只有因为约束才有意义。因此,对于最小化非有界凹函数(即具有[半]负定Hessian矩阵)也是如此。只要这样思考:&#34;尽可能多地上升就像颠倒世界一样,尽可能多地下降&#34;