包装圈


21

看一下这张图片。具体而言,如何布置两端的孔。

在此处输入图片说明

图片来源

请注意,此图像中的管道是如何以六边形图案包装的。众所周知,在2D中,六边形格子是最密集的圆堆积。在这一挑战中,我们将专注于最大程度地减少圆包装的周长。可视化周界的一种有用方法是,想象将橡皮筋套在圆圈集合上。

任务

给定一个正整数n作为输入,请显示n尽可能紧密排列的一组圆圈。

规则和说明

  • 假设圆的直径为1个单位。
  • 要被最小化的变量是周长,其被定义为长度凸包的的中心组中的圆圈。看一下这张图片:

在此处输入图片说明

直线上的三个圆的周长为4(凸包是2x0矩形,对2计数两次),以120度角排列的圆的周长约为3.85,三角形的周长为只有3个单位。请注意,我忽略了实际周长的其他pi单位,因为我仅查看圆的中心,而不是圆的边缘。

  • 对于任何给定,可能(几乎肯定会有)多种解决方案n。您可以自行决定输出其中的任何一个。方向无关紧要。
  • 圆必须在六边形格子上。
  • 圆圈的直径必须至少为10像素,并且可以填充或不填充。
  • 您可以编写程序或函数。
  • 输入可以通过STDIN作为函数参数或最接近的等效参数进行。
  • 输出可以显示或输出到文件。

例子

下面我有n从1到10的有效无效输出示例(仅对前五个有效示例)。有效的例子在左边;右侧的每个示例都比相应的有效示例大。

在此处输入图片说明

非常感谢steveverrill编写此挑战的帮助。包装愉快!


3
等待六方,我打赌。; D
Addison Crump 2015年

@VoteToClose:我不认为Hexagony具有图形输出,但是MAN,那太棒了!
El'endia Starman

@ El'endiaStarman好吧,您可以在stdout上编写SVG,但我不认为我要...:P
Martin Ender 2015年

1
哇,之前没有人以粗体感谢我在沙盒中的评论。我脸红了:-D我当然评论了,因为我喜欢挑战,尽管我不确定我是否有时间回答。
Level River St

根据我与user81655的答案与Reto Koradi的讨论,我认为我们将看到的带有锐角的最大六边形是边长7d(8个圆)。总共N = 169个圆。您可以考虑将问题限制在该数字范围内,这将使您有更多机会获得正确答案(当前没有答案)并能够进行检查。在另一方面,它可能是更有趣离开这个问题打开了任意N.
级别圣河

Answers:


4

Mathematica 295950 字节

注意:此版本仍待解决,解决了史蒂夫·梅里尔(Steve Merrill)提出的有关我较早尝试的问题。

尽管它是对第一个版本的改进,但是它找不到要寻找圆形而不是六角形整体形状的最密集的手柄配置。

它通过建立一个完整的内部六边形(对于n> = 6)来找到解决方案,然后检查用于完成带有其余圆的外壳的所有配置。

有趣的是,正如史蒂夫·美林(Steve Merrill)在评论中指出的那样,n+1圆的解决方案并不总是由n个圆的解决方案组成,并添加了另一个圆。将给定的30个圆的解决方案与给定的31个圆的解决方案进行比较。(注意:有30个圈子的独特解决方案。)

m[pts_]:={Show[ConvexHullMesh[pts],Graphics[{Point/@pts,Circle[#,1/2]&/@ pts}], 
ImageSize->Tiny,PlotLabel->qRow[{Length[pts],"  circles"}]],
RegionMeasure[RegionBoundary[ConvexHullMesh[pts]]]};
nPoints = ((#+1)^3-#^3)&;pointsAtLevelJ[0] = {{0,0}};
pointsAtLevelJ[j_]:=RotateLeft@DeleteDuplicates@Flatten[Subdivide[#1, #2, j] &@@@
Partition[Append[(w=Table[j{Cos[k Pi/3],Sin[k Pi/3]},{k,0,5}]), 
w[[1]]], 2, 1], 1];nPointsAtLevelJ[j_] := Length[pointsAtLevelJ[j]]
getNPoints[n_] := Module[{level = 0, pts = {}},While[nPoints[level]<=n, 
pts=Join[pointsAtLevelJ[level],pts];level++];Join[Take[pointsAtLevelJ[level],n-Length[pts]],
pts]];ns={1,7,19,37,61,91};getLevel[n_]:=Position[Union@Append[ns,n],n][[1, 1]]-1;
getBaseN[n_] := ns[[getLevel[n]]];pack[1]=Graphics[{Point[{0,0}], Circle[{0, 0}, 1/2]}, 
ImageSize->Tiny];pack[n_]:=Quiet@Module[{base = getNPoints[getBaseN[n]], 
outerRing = pointsAtLevelJ[getLevel[n]], ss},ss=Subsets[outerRing,{n-getBaseN[n]}];
SortBy[m[Join[base,#]]&/@ss,Last][[1]]]

一些检查需要对单个值n(包括对称性)进行十万多个案例的比较。运行了总共34个测试用例大约花费了5分钟。不用说,采用更大的n's暴力手段很快将变得不切实际。肯定存在更有效的方法。

每个包装右边的数字是相应的蓝色凸包的周长。以下是的输出3 < n < 35。红色圆圈是在正六边形周围添加的圆圈。

磁盘



1
正如我在用户81655的答案中提到的那样,将22(以及17、25、28、31、34)上突出的单个圆圈更好地放置在它所在的那排圆圈的中间。
水平河圣

我也这样认为,但是后来我注意到带有凸起圆的9被认为是正确的。有时间时,我将比较(中心的)凸包的尺寸。
DavidC

在9中,沿平排的突出圆为1/4或3/4,因此没有区别。在17、22、25、28、31中,突出的圆沿方向为1 / 6、3 / 6或5/6,所以中间位置更好(想侧向拉弦:从中间拉出更容易,因为这样在34(和35)中,我们在弦线的扁平侧分别具有1 / 8、3 / 8、5 / 8和7/8,因此我们应该选择3/8和5/8 1/8和7/8之前。
等级河圣

您绝对正确,这已通过测量得到证实。
DavidC

这太棒了!过渡30-> 31表明,我们不能仅采用以前的形状并向外部添加一个圆(其周长为16.464。)在至少一种情况下,您可以向其中添加一个圆外部,但选择了其他安排:12-> 13
Level River St
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.