Prolog中的优化

6

假设我想找到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中如何实现?我看到有用于线性求解的simplex库,但这是一个二次问题,而偏导数不是。(我有点困惑!)

这是我拥有的:

:- 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.
1个回答

5
这里有几个问题。首先,让我们把这个问题解决掉: library(simplex) 只能处理线性约束条件。所以它不能直接用来解决你的实际问题。
但是,library(simplex) 通常仍然很有用,因此我想快速指出以下内容:
  1. variable_value/3 only works on the solved tableau. This means that you must have invoked maximize/3 first.

    For example:

    ?- my_constraints(S), maximize([x,y], S, Max), variable_value(Max, x, X).
    S = ...,
    Max = ...,
    X = 0.
    
  2. Note that you must change the final goal of my_constraint/1 to constraint([-1*x, -1*y,z] = 0, S5, S) to conform to the syntax required by this library.

话虽如此,现在让我们来到问题的核心:有着众所周知的方法以迭代的方式解决二次优化问题,使用一系列的线性程序和关于梯度的推理来接近一个解。因此,可以间接地使用library(simplex)来解决你的问题。
特别是,请查看杂项程序中提供的最陡上升法方法。它包括一个用Prolog编写的小型符号导数计算器。是的,这是“符号”;-)
将您的任务插入,我得到:
?- maximize(- 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],Max)。
Max = [4.298588509886033e-17, 0.125, 0.12500000000000006] ;
false。
这是,除了浮点运算不可忍受的污点之外,我希望你能够使用的东西。

谢谢,我对输入矩阵有些困惑。 这是限制条件吗? 第一行[-1,0,0]是否对应于下一个参数的第一个元素,即x(1)>= 0?如果是这样,那么为什么我们有[-1,-1,1]和[1,1,-1]? - user27815
使用不等式表达相等约束;-) - mat
抱歉,我仍然感到困惑。如果我有6个未知数需要加起来等于零,那我应该放什么?我是否仍然只需要在矩阵中对称地放置两行? - user27815
每一行是大于等于还是小于等于的不等式? - user27815

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接