Rubik的Cube求解器,用于非常大的立方体。
求解从1到65536的任何大小的任何立方体。可以轻松修改代码以处理更大的立方体。但是,主要的限制是系统上的内存量以及解决的时间长度。求解时间增长了〜n^2,这意味着要在每个维度中求解大2倍的立方体需要4-5倍。
1024个分层的立方体可以在约1.5秒内解决。大约20分钟内可以解决16384分层的立方体。
YouTube:求解65536层YouTube:求解32768层
32768立方体前面的图像
解决中心,然后边缘边缘
中心在15个阶段解决,每个阶段将某些颜色的所有碎片从一个脸部移动到所需的脸部。例如:一个阶段将白色脸上的所有绿色碎片移到绿色的脸上。重复所有颜色和面孔。
求解器使用此处描述的换向器,该换向器可以将中心碎片从一个脸部的一个象限到另一个脸上的震撼力。该换向器的一个非常重要的属性是可以修改以同时将许多零件移动。对于非常大的立方体,这意味着它可以在一次操作中移动数百件甚至数千件。 k =(2 * p + 5) / p的平均移动数是p是可以移动每个操作的零件数。随着立方体尺寸的增加,K迅速接近2。
使用基本的蛮力方法来解决角落,以将角移动到位,然后旋转直到正确定向。威尔·史密斯(Will Smith
通过将每对边缘移动到前面,然后从左边缘到右边缘交换所需的碎片来解决边缘。需要解决或防止奇偶校验问题的许多功能。
面部旋转基本上是免费的。求解器没有将所有片段(n^2片)移动到旋转上,而是更改用于读/写入面的坐标系。这样可以节省大量数据交换。
// Virtually rotate this face by q * 90 degrees
inline void Face::RotatefaceCW ( const int q)
{
orientation = (orientation + q) & 3 ;
}
// Gets the value of this face at coordinates r = row, c = column
inline const byte Face::GetRC ( const uint r, const uint c) const
{
switch (orientation) {
case 0 :
return data[(r << BS) + c];
case 1 :
return data[(c << BS) + (R1 - r)];
case 2 :
return data[((R1 - r) << BS) + (R1 - c)];
case 3 :
return data[((R1 - c) << BS) + r];
default :
return 0 ;
}
}
此代码包括一个简单的图像出口商,该出口商将每个脸部呈现到图像中。
https://www.nayuki.io/page/tiny-png-output
https://github.com/nayuki/nayuki-web-publishered-code
Tiny PNG输出是一个小型独立库,可在C和C ++中使用,它采用RGB8.8.8像素并写入PNG文件。
可以使用简单公式估算移动总数。假设多维数据集是足够随机的,我们可以期望第一张脸能解决1/6,因此必须移动5/6的零件。第二个面将解决1/5,需要4/5的零件要移动。第三脸3/4,第四张2/3,第五脸1/2,最后一张面部将完全解决。可以在实验上估计〜2.1的平均移动数(K)。随着立方体的大小增加,K的值降低。该值永远不会小于2,因为换向器需要至少2次移动每件。
该算法针对非常大的立方体进行了优化。但是,对于小立方体来说是可怕的。主要的优化集中在尽可能快地解决中心,并且没有考虑解决边缘。但是,随着立方体尺寸的增加,与中心相比,边缘的大小微不足道。下图显示了如何使用较大的立方体减少每件的平均移动次数。注意:这不是k的图。它是(总动作) /(零件数)的图表
cmake -B build -S .
cd build
cmake --build .
RCube/RCube