Это, безусловно, невозможно сделать в общем случае для общего набора полиномиальных неравенств любым методом, кроме перечислительного поиска, даже если существует конечное число решений. (Возможно, я должен сказать, что нетривиально, поскольку это возможно. Перечислительный поиск будет работать при наличии проблем с плавающей запятой.) Обратите внимание, что интересующая область не должна быть просто связана для неравенств более высокого порядка.
Редактировать: ОП спросил, как можно продолжить поиск.
Рассмотрим проблему
x^3 + y^3 >= 1e12
x^4 + y^4 <= 1e16
x >= 0, y >= 0
Решите для всех целочисленных решений этой системы. Обратите внимание, что целочисленного программирования в ЛЮБОЙ форме здесь будет недостаточно, поскольку запрашиваются ВСЕ целочисленные решения.
Использование сетки здесь заставит нас посмотреть на точки в домене (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 гигабайтами оперативной памяти. Но даже в этом случае сам тест был загружен процессором.
Elapsed time is 50.182385 seconds.
Обратите внимание, что соображения с плавающей запятой иногда приводят к разному количеству точек в зависимости от того, как выполняются вычисления.
Наконец, если ваши уравнения ограничений более сложные, вам может потребоваться использовать корни в выражении для границ по y, чтобы помочь определить, где выполняются ограничения. Хорошая вещь здесь - это все еще работает для более сложных полиномиальных границ.