说我想找到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.

最佳答案

这里有几个问题。首先,只是为了解决这个问题: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.
    
  • 注意,必须将my_constraint/1的最终目标更改为constraint([-1*x, -1*y,z] = 0, S5, S),以符合此库所需的语法。

  • 话虽如此,让我们现在进入问题的核心:有一系列迭代解决二次优化问题的著名方法,使用一系列线性程序并通过梯度推理来更接近解决方案。因此,library(simplex)仍可以间接用于解决您的问题。

    特别是,请查看miscellaneous programs提供的最陡峭上升方法。它包括一个用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];
    错误的。

    我希望您可以使用浮点运算令人难以忍受的麻烦。

    10-08 18:33