Я бы попытался решить эту проблему эмпирически (решить, используя возврат ) вместо аналитического, то есть найти все возможности * (я объясню *).По сути, мы хотим поместить каждый прямоугольник, начиная с минимального размера этого прямоугольника, до его максимального размера (максимальный размер может быть определен по наибольшему прямоугольнику до столкновения с начальной точкой его соседей или роста до главного прямоугольника контейнера).Это означает, что если мы попытаемся поместить каждый прямоугольник во все его возможные размеры, одно из этих решений будет лучшим решением.Также обратите внимание, что это действительно одномерная проблема, так как высота и ширина канавок связаны соотношением;установка одного неявно устанавливает другого.
* - Когда я сказал все возможности, я действительно имел в виду наиболее разумные возможности.Поскольку мы находимся в пространстве с плавающей запятой, мы не можем проверить ВСЕ возможности.Мы можем проверять более высокую точность, но не сможем проверить все размеры.В связи с этим мы определяем размер шага для итерации по размеру ритов, которые мы попробуем.
const float STEP_SIZE = 0.0001;
float fLastTotalSize = 0;
int main()
{
PlaceRect(myRects.begin(), myRects.end());
}
void PlaceRect(Iterator currentRect, Iterator end)
{
if (currentRect == end)
{
return;
}
float fRectMaxSize = CalculateMaxPossibleRectSize(*currentRect);
// find the number of steps it will take to iterate from the smallest
// rect size to the largest
int nSteps = fRectMaxSize / STEP_SIZE;
for(int i = 0; i < nSteps; ++i)
{
// based on the step index scale the rect size
float fCurrentRectTestSize = i*STEP_SIZE;
currentRect->SetSize(fCurrentRectTestSize);
float fTotalSize = CalculateTotalSizesOfAllRects();
if (fTotalSize > fLastTotalSize)
{
fLastTotalSize = fTotalSize;
SaveRectConfiguration();
}
// Continue placing the rest of the rects assuming the size
// we just set for the current rect
PlaceRect(currentRect + 1, end);
// Once we return we can now reset the current rect size to
// something else and continue testing possibilities
}
}
Исходя из размера шага и количества прямоугольников, этот процесс может выполняться очень долго, но он найдет вам эмпирическое решение.