Gra*_*ton 5 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
Run Code Online (Sandbox Code Playgroud)
需要注意的是x和y必须是整数.
在图形上它可以表示如下,蓝色区域是满足上述不等式的区域:

现在的问题是,Matlab中是否有任何函数可以找到每个可接受的对{x,y}?如果有算法来做这种事情,我也很高兴听到它.
当然,我们总能使用的一种方法是强力方法,我们测试每种可能的组合,{x,y}以查看是否满足不等式.但这是最后的手段,因为它耗费时间.我正在寻找一个聪明的算法来做到这一点,或者在最好的情况下,我可以直接使用现有的库.
这x^2+y^2>=100 and x^2+y^2<=200只是例子; 在现实中f,g可以是任何程度的任何多项式函数.
编辑:C#代码也受到欢迎.
小智 4
对于一般的多项式不等式集,通过枚举搜索以外的任何方法,这当然是不可能的,即使存在有限数量的解。(也许我应该说这不是微不足道的,因为这是可能的。枚举搜索将起作用,但会受到浮点问题的影响。)请注意,对于高阶不等式,感兴趣的域不需要简单地连接。
编辑:OP 询问如何进行搜索。
考虑问题
x^3 + y^3 >= 1e12
x^4 + y^4 <= 1e16
x >= 0, y >= 0
Run Code Online (Sandbox Code Playgroud)
求解该系统的所有整数解。请注意,任何形式的整数规划在这里都不够,因为需要所有整数解决方案。
此处使用网格网格将迫使我们查看域 (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
Run Code Online (Sandbox Code Playgroud)
所需时间是...
Elapsed time is 0.600419 seconds.
Run Code Online (Sandbox Code Playgroud)
在我们可能测试过的 100020001 个组合中,我们找到了多少种解决方案?
size(xy)
ans =
2 4371264
Run Code Online (Sandbox Code Playgroud)
不可否认,穷举搜索更容易编写。
tic
[x,y] = meshgrid(0:10000);
k = (x.^3 + y.^3 >= 1e12) & (x.^4 + y.^4 <= 1e16);
xy = [x(k),y(k)];
toc
Run Code Online (Sandbox Code Playgroud)
我在 64 位机器上运行这个程序,有 8 GB 内存。但即便如此,测试本身仍然非常消耗 CPU。
Elapsed time is 50.182385 seconds.
Run Code Online (Sandbox Code Playgroud)
请注意,浮点考虑有时会导致找到不同数量的点,具体取决于计算的完成方式。
最后,如果您的约束方程更复杂,您可能需要在 y 上的边界表达式中使用根,以帮助确定满足约束的位置。这里的好处是它仍然适用于更复杂的多项式界限。