使用 Prolog 库 Simplex 求解线性方程组

问题描述

我正在尝试使用 SWI-Prolog simplex library 来求解以实数集为域的线性方程组。有没有人知道为什么以下查询不成功?

maximize(
[],state(
 0,[],[ 
   c(0,[- 0.95*x(3),0.05*x(0),0.05*x(1),0.05*x(2)],=,1479754163278877r9007199254740992),c(0,[0.95*x(2),- 0.05*x(0),- 0.05*x(1),- 0.05*x(3)],185786871969449310676024028079063r3975352282315727403093661252059136
   ),[0.95*x(1),- 0.05*x(2),756128230024134313216574233897861r15901409129262909612374645008236544
   ),[0.95*x(0),294112628726237r72057594037927936
   )
 ],[]
),S).

我打算解决的系统如下:

0.05*x(0)+0.05*x(1)+0.05*x(2)-0.95*x(3)
= 
1479754163278877/9007199254740992

- 0.05*x(0)- 0.05*x(1)+0.95*x(2)- 0.05*x(3) 
=
185786871969449310676024028079063/3975352282315727403093661252059136

- 0.05*x(0)+0.95*x(1)- 0.05*x(2)- 0.05*x(3)
=
756128230024134313216574233897861/15901409129262909612374645008236544

0.95*x(0)- 0.05*x(1)- 0.05*x(2)- 0.05*x(3)
=
294112628726237/72057594037927936

或者,你能知道在 Prolog 中解决这个问题的更好方法吗?

解决方法

看起来求解器假设所有变量都是非负的。所以问题就变成了:我们能否将 Ax=b(其中 x 是自由变量)重新表述为使用非负变量的东西?答案是:是的。使用称为变量拆分的技术,我们可以将每个 x(j) 替换为 xplus(j)-xmin(j) where xplus(j),xmin(j)>=0。于是方程组变为:

  sum(j,a(i,j)*(xplus(j)-xmin(j))) = b(i)   for all i
  xplus(j),xmin(j)>=0
       

我们可能需要确保只有一对 (xplus(j),xmin(j)) 可以变为非零。这可能会自动成立,因为如果两者都在基中,基矩阵 B 将变得奇异。但是我们也可以设置一个目标来处理这个问题:

  min sum(j,xplus(j)+xmin(j))

只要方程组有可行解,目标将确保只有一个 (xplus(j),xmin(j)) 非零。