【问题标题】:Maximize the area utilized by rectangles put in a circle最大化放置在圆形中的矩形所使用的面积
【发布时间】:2015-04-14 14:16:22
【问题描述】:

我有一个圆圈,我需要用矩形填充。一个堆放在另一个上。矩形仅提供特定尺寸。我们还给出了必须放置的矩形数量。我需要得到一组覆盖圆的大部分区域的矩形长度。例如,如果圆的直径为 100,则可以放置长度为 [100,95,90,85,...15,10,5] 的矩形。我尝试过通过解析所有可能的组合使用蛮力方法。当数字很小时,它会产生很好的结果。我尝试的另一种算法是限制每个矩形占据的长度范围。就像第一个矩形的长度为 95 或90 得到最好的结果。但是当要放置的矩形数量非常多时,即使这种方法也很麻烦。这是矩形的排列方式

如果第一个矩形的长度为l,圆的直径为d,则其厚度为sqrt(d2-l2)。如果第二个矩形的长度为k,则其厚度为sqrt(d2-k2)-sqrt(d2 -l2)。

有什么算法可以让我去制定结果。

【问题讨论】:

  • 这个问题我一点都不清楚。您的示例似乎表明矩形的一部分允许在圆之外。是这样吗?矩形高度是否以某种方式受到限制?在某些时候,您提到了固定数量的矩形,但我在您的示例中没有看到?
  • 现在允许矩形在我绘制它们时向外延伸,它们只是变大了一点。每个矩形的厚度取决于它的长度,正如我在底部解释的那样。矩形的数量,圆的直径由用户给出,因此您可以认为它是固定的算法,即:n,矩形的长度仅以 5 为步长
  • 有人建议我使用离散分析。但是我对如何解决这个问题几乎没有任何线索
  • 只是为了清楚。 1.“d2”是d^2(d平方)吗? ............. 2. 什么是“第一个”矩形?长度为 100 的矩形的高度(厚度)= sqrt(d^2-100^2) ?第二个长度为 95 的将有 sqrt(d2-95^2)-sqrt(d2-100^2) ?
  • 我已经发布了一个答案(可能对你没有帮助),但我认为这个问题在这里是错误的。最好在math.stackexchange.com 询问

标签: algorithm logic


【解决方案1】:

为什么对这个问题进行蛮力攻击会很困难?您只需要在计算代码中付出一些努力,我相信它会正常工作。它最多只有19个级别。这不应该太复杂,并且会在......好吧,几个小时内给你结果,正如我刚刚发现的那样。 19 个级别将导致 3.3e17 计算。

关于算法:
对于一个矩形,当矩形是正方形时,您将获得最大的覆盖区域。我认为这很容易理解。正方形的角与圆心成 45°(假设水平为 0°,但这实际上并不重要,因为整个结构是点对称的),大小为(0.707*diameter)^2 = 5000
最接近宽度 70.7 的是 70。一般来说,我建议检查低于 (70) 和高于 (75) 的数字,以获得准确的结果 (70.7)。矩形的面积是 70 * 71.41 = 4999。(但很高兴知道,如果高度也必须是 5 格之外的值!

现在变得越来越困难,我希望我是对的:
当我写下这个答案时,事实证明,我错了。 :-( 四舍五入的结果比理论最大值要高。但无论如何我都会发布它,也许它有助于找到真正的答案。

当你有 2 个矩形时,要覆盖的最大区域应该是什么时候

  • rect1 的角为 30°(以及 150°、210°、330°),并且
  • rect2 的角为 60°(以及 120°、240°、300°)。

尺寸为:

  • 矩形 1:0.866*dia * 0.5 *dia = 4330
  • rect 2: 0.5 *dia * 0.866*dia = 4330 - 减去重叠 =>> 0.5*0.36*dia^2 = 1830
  • 总和:6160

四舍五入到 5 的网格:

  • 矩形 1, #1) 85*52.86 = 4478
  • 矩形 2: #1) 50*(86.60-52.86) = 1696.2 #2) 55*(83.52-52.86) = 1696.1 #3) 45*(89.30-52.86) = 1648
  • 总和:6173.87 // 6173.75 // 6126

  • rect 1, #2) 90*43.59 = 3923

  • 矩形 2: #1) 50*(86.60-43.59) = 2151 #2) 55*(83.52-43.59) = 2196 #3) 45*(89.30-43.59) = 2057
  • 总和:6074 // 6119 // 5980

获胜者是组合1.1:rect1 = 85, rect2 = 50。

由于使用四舍五入的值,您必须检查每个矩形的上下(以及是否在网格上)值的每个组合,如果 n 是矩形的数量,则最多检查 3^n 次(n=1 除外)。蛮力不是更好,但可能更容易。 (正如上面发现和写的,它可能会返回更好的结果,因为这种方法是不准确的)。

编辑 1: 1 个矩形(生成正方形)的公式是:

A = x * sqrt(D²-x²)
calculate the maximum using the derivative of A:
A' = D²-2x² / sqrt(D²-x²) = 0

你也可以在这里找到它:http://oregonstate.edu/instruct/mth251/cq/Stage8/Lesson/rectangle.html

2个矩形的公式是:

A = f(x,y) = x * sqrt(D²-x²) + y * [sqrt(D²-y²)-sqrt(D²-x²)]
( x = width of r1, y = width of r2 )

n 个矩形的公式取决于 n 个未知变量。所以你需要计算n个偏导数。玩得开心! (或考虑蛮力,因为您已经获得了一个网格并且不需要进行迭代;-))

【讨论】:

  • 我目前正在使用蛮力。当我处理半径为 5000 的圆时,我必须放入 50 个矩形,蛮力失败,因为它需要大量时间。我需要一些计算算法来执行这个。我以 100 圆直径为例来展示这个问题
  • 我知道我的答案不是 100% 正确,但我仍然认为它很接近。将它与 +-n 步的邻居搜索结合起来应该会给你一个好的(甚至是确切的)结果。我一定会试一试的。顺便说一句:计算如何用 50 个矩形填充一个圆会占用一些 CPU 时间,除非你找到了完美的算法,没有很少的迭代,我真的不知道它是否存在。
  • 我什至尝试了这种方法,在这种方法中,我得到了可以使用 newton rhapson 方法为每个步骤提供最佳结果的因素。然后我检查这些因素的上限和下限。但即便如此我无法获得最佳输出。此外,当涉及到 50 个矩形时,我必须经过 2^50 个组合。
  • 这个过程是模拟的一部分,用户运行大约 500 万次迭代,如果在每次迭代中我运行 2^50 次组合,它会消耗大量时间。我正在寻找某种算法这样我就可以大大限制组合的数量
【解决方案2】:

蛮力算法

计算量:

levels   calculations
1        19
2        19 + 19*18 = 361
...
5        19 + 19*18 + 19*18*17 + 19*18*17*16 + 19*18*17*16*15 = 1494559
...
10       3.7e11
15       6.3e15
19       3.3e19

C#(或 C++):

double dDia = 100;
int nSizes = 20;
int nmax = 2; // number of rectangles

int main()
{
  int n = 1;
  double dArea = 0.0;

  dArea = CalcMaxArea (n, 0);
}

double CalcMaxArea (int n, double dSizeYParent)
{
  double dArea    = 0.0;
  double dAreaMax = 0.0;

  for (int iRun = nSizes-n; iRun >= 1; iRun--)
  {
    double dSizeX = iRun * 5;
    double dSizeY = Math.Sqrt(dDia * dDia - dSizeX * dSizeX) - dSizeYParent);
    double dAreaThis = dSizeX * dSizeY;

    double dAreaOthers = 0.0;
    if (n < nmax)
      dAreaOthers = CalcMaxArea (n+1, dSizeY);
    if (dArea > dAreaMax)
      dAreaMax = dArea;
  }
}

VBA,用于 MS Excel

Dim dDia As Double
Dim nmax As Integer
Dim nSizes As Integer

Sub main()

dDia = 100
nmax = 2
nSizes = 20

Dim n As Integer
Dim dArea As Double

n = 1
dArea = CalcMaxArea(n, 0)

End Sub

Function CalcMaxArea(n As Integer, dSizeYParent As Double) As Double
  Dim dArea As Double
  Dim dAreaMax As Double
  dArea = 0

  For iRun = nSizes - n To 1 Step -1
    Dim dSizeX As Double
    Dim dSizeY As Double
    Dim dAreaThis As Double
    Dim dAreaOthers As Double

    dSizeX = iRun * 5
    dSizeY = Sqr(dDia * dDia - dSizeX * dSizeX) - dSizeYParent
    dAreaThis = dSizeX * dSizeY

    dAreaOthers = 0
    If n < nmax Then
      dAreaOthers = CalcMaxArea(n + 1, dSizeY)
    End If
    dArea = dAreaThis + dAreaOthers
    If dArea > dAreaMax Then
      dAreaMax = dArea
    End If
  Next

  CalcMaxArea = dAreaMax
End Function

用给定的值在 VBA 中测试,得到相同的结果:6173.87。
可能会添加更多代码以记住达到的最大值。

【讨论】:

  • 我不能使用蛮力,因为当圆直径和我需要放置的矩形数量很大时消耗的时间真的很长
  • 您可以结合使用蛮力和我的其他答案。蛮力部分将是通过近似算法的迭代。
【解决方案3】:

我再次阅读了这个问题,并意识到我完全错过了您帖子中的几个关键点。这张照片让我很困惑,但这不是一个好的借口。我之前在 cmets 中的建议完全是个坏主意。对不起,我希望你没有花很多时间调查它。如果我必须解决这个问题,我会这样做,无论对错。

所以我一直在思考这个问题。我能想到的最佳解决方案是使用 A* 之类的搜索算法。 A* 它本身的实现相当简单。我假设您已经有了计算面积的方法,这对我来说似乎是最难的部分。我知道如何继续计算重叠矩形的面积,但这就是为什么我没有编写一个可以证明我的建议是好的程序的原因。

我要做的是拥有所有潜在矩形的主列表。 将不在当前路径中的所有矩形的副本添加到您的边界,作为放置的第​​ n 个矩形。这将允许您设置宽度,从而计算要填充的圆圈的面积。继续这样做,每次从前沿选择成本最低的路径,并且在探索了 m 个节点之后,你应该有最佳拟合。其中 m 是您必须放置的矩形总数。

对于成本评估,使用剩余空间来填充似乎是一个自然的选择。不过要注意的一件事是,剩余的面积会随着时间的推移而减少,而您将需要一个增加的面积。我认为将剩下的区域除以剩下的矩形数量应该会给你一个很好的成本函数来找到到圆圈中剩余最小区域的最低成本路径。那个对我来说听起来不错,但我敢肯定还有其他可以使用的。

关于启发式,如果没有启发式函数,您仍然可以获得最佳的首次搜索,所以我希望它比盲目的蛮力技术表现更好。有了一个好的启发式函数,我预计性能会显着提高。在考虑什么是一个好的启发式函数时,我认为估计矩形将填充的圆的数量可能会很好。例如,矩形面积的 10% 除以要放置的矩形数量。由于没有预先确定的目标状态,任何估计都必须完全基于下一个矩形的区域。我们知道矩形的整个区域不会有助于解决方案。就解决方案而言,第一个矩形之后的每个矩形的大部分都是浪费空间,这就是我提出该启发式的方式。与成本函数一样,对我来说这似乎是一个合理的想法,但如果有人能想到更好的方法,那就更好了。

A* 上有各种各样的网站,但这里有一个看起来写得很好。 http://web.mit.edu/eranki/www/tutorials/search/

希望对你有所帮助。

【讨论】:

    【解决方案4】:

    我知道设计一个可行的算法很复杂,但这是我想到的方法: 在给定直径的圆中,只能有一个矩形占据最大面积。

    1. 找出可以放入圆形的矩形的最大宽度和高度。有很多相同的解决方案。例如看:Find Largest Inscribed Rectangle 这个矩形将结束最大区域的主要部分。

    2. 接下来的任务是用不同大小的矩形填充圆的剩余部分。找出最适合的矩形,如下图所示。这可以通过检查圆点是否位于指定高度和宽度的矩形内来完成

    我再次同意这很难实现。

    【讨论】:

    • 我相信矩形重叠,一个直接在另一个之上。这也是让我困惑的部分。我想是因为他使用了图片中的渐变。但我相信矩形 1 是灰色矩形。最重要的是,矩形 2 是紫绿色矩形,等等...
    • 没有一个矩形相互重叠。它们都是单独的矩形。
    • 不和你争论,但问题的第二句是Piled one over the other.
    • :) 同意,但你不认为两个重叠的三角形不会“加起来”它们各自的面积吗?
    • 我不能以这种方式放置矩形。它们必须像问题中那样放置在另一个之上
    猜你喜欢
    • 2017-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多