use*_*815 5 prolog swi-prolog quadratic-programming
我想找到argmax(x,y,z)-1/2(20x ^ 2 + 32xy + 16y ^ 2)+ 2x + 2y.
受制于:x> = 0,y> = 0,z> = 0且-x-y + z = 0.
我知道偏导数设置为0是:
-20x-16y + 2 = 0和-16x-16y + 2 = 0
所以我们可以得x = 0和y = 1/8,z = 1/8.
我如何在Swi-prolog中做到这一点?我看到有用于线性求解的库单形,但这是一个二次问题,但偏导数不是.(我有一点困惑!)
这就是我所拥有的:
:- use_module(library(simplex)).
my_constraints(S):-
gen_state(S0),
constraint([-20*x, -16*y] = 0, S0, S1),
constraint([-16*x,-16*y] = 0, S1,S2),
constraint([x] >= 0,S2,S3),
constraint([y] >= 0,S3,S4),
constraint([z] >= 0,S4,S5),
constraint([-x-y+z] = 0,S5,S).
?- my_constraints(S), variable_value(S,x,Val1),variable_value(S,y,Val2).
false.
Run Code Online (Sandbox Code Playgroud)
这里有几个问题。首先,为了解决这个问题:library(simplex)只能处理线性约束。所以是的,它不能——至少不能直接——用来解决你的实际问题。
但library(simplex)无论如何通常都是有用的,所以我想快速指出以下几点:
variable_value/3仅适用于已解决的画面。这意味着您必须先调用maximize/3。
例如:
?- my_constraints(S), maximize([x,y], S, Max), variable_value(Max, x, X).
S = ...,
Max = ...,
X = 0.
Run Code Online (Sandbox Code Playgroud)my_constraint/1请注意,您必须更改to的最终目标constraint([-1*x, -1*y,z] = 0, S5, S)以符合此库所需的语法。
话虽如此,现在让我们进入问题的核心:有一些众所周知的方法可以迭代解决二次优化问题,使用一系列线性 程序和梯度推理来更接近解决方案。因此,library(simplex)仍然可以间接地用来解决你的问题。
特别是,请查看各种程序中可用的最陡上升方法。它包括一个用 Prolog 编写的小型符号导数计算器。是的,这是“象征性的”;-)
插入你的任务,我得到:
?- 最大化(- 0.5*(20*x(1)^2 + 32*x(1)*x(2) + 16*x(2)^2) + 2*x(1) + 2*x( 2),
[[-1,0,0],
[0,-1,0],
[0,0,-1],
[-1,-1,1],
[1,1,-1]],
[0,0,0,0,0],
[0,0,0],最大值)。
最大值 = [4.298588509886033e-17, 0.125, 0.12500000000000006] ;
错误的。
这就是浮点运算令人难以忍受的肮脏之处,我希望你能使用它。