找到满足不等式约束的{x,y}离散对

时间:2010-09-25 10:56:29

标签: c# matlab mathematical-optimization linear-programming nonlinear-optimization

我有一些关于{x,y}的不等式,它满足以下等式:

x>=0
y>=0
f(x,y)=x^2+y^2>=100
g(x,y)=x^2+y^2<=200

请注意,xy必须为整数。

图形上可以表示如下,蓝色区域是满足上述不等式的区域:

alt text

现在的问题是,Matlab中是否有任何函数可以找到{x,y}的每个可接受对?如果有算法来做这种事情,我也很高兴听到它。

当然,我们可以使用的一种方法是强力方法,我们测试{x,y}的每个可能组合,以查看是否满足不等式。但这是最后的手段,因为它耗费时间。我正在寻找一个聪明的算法来做到这一点,或者在最好的情况下,我可以直接使用现有的库。

x^2+y^2>=100 and x^2+y^2<=200只是示例;实际上fg可以是任何程度的任何多项式函数。

编辑:欢迎使用C#代码。

1 个答案:

答案 0 :(得分:4)

对于一般的多项式不等式集合,通过枚举搜索以外的任何方法,即使存在有限数量的解,也无法做到这一点。 (也许我应该说这不是微不足道的,因为它是可能的。枚举搜索将起作用,受浮点问题的影响。)请注意,感兴趣的域不需要简单地连接到更高阶的不等式。

编辑:OP询问了如何进行搜索。

考虑问题

x^3 + y^3 >= 1e12
x^4 + y^4 <= 1e16

x >= 0, y >= 0

解决此系统的所有整数解决方案。请注意,这里的任何形式的整数编程都不够,因为请求所有整数解。

在这里使用meshgrid将迫使我们查看域中的点(0:10000)X(0:10000)。所以它会迫使我们采样一组1e8点,测试每个点以查看它们是否满足约束条件。

一个简单的循环可能比这更有效,尽管它仍然需要一些努力。

% Note that I will store these in a cell array,
% since I cannot preallocate the results.
tic
xmax = 10000;
xy = cell(1,xmax);
for x = 0:xmax
  % solve for y, given x. This requires us to
  % solve for those values of y such that
  %   y^3 >= 1e12 - x.^3
  %   y^4 <= 1e16 - x.^4
  % These are simple expressions to solve for.
  y = ceil((1e12 - x.^3).^(1/3)):floor((1e16 - x.^4).^0.25);
  n = numel(y);
  if n > 0
    xy{x+1} = [repmat(x,1,n);y];
  end
end
% flatten the cell array
xy = cell2mat(xy);
toc

所需时间是......

Elapsed time is 0.600419 seconds.

在我们可能测试的100020001组合中,我们找到了多少解决方案?

size(xy)
ans =
           2     4371264

不可否认,详尽的搜索更容易编写。

tic
[x,y] = meshgrid(0:10000);
k = (x.^3 + y.^3 >= 1e12) & (x.^4 + y.^4 <= 1e16);
xy = [x(k),y(k)];
toc

我在一台64位机器上运行它,有8 GB的内存。但即便如此,测试本身也是一头CPU。

Elapsed time is 50.182385 seconds.

请注意,浮点注意事项有时会导致找到不同数量的点,具体取决于计算的完成方式。

最后,如果您的约束方程更复杂,您可能需要在表达式中使用y作为边界的根,以帮助确定约束的满足位置。这里的好处是它仍适用于更复杂的多项式边界。