对于学校作业,我们需要在 C# 中实现一个 7-Riffle 算法方法,该方法对魔方的面部进行洗牌。不幸的是,网络上没有足够的资源来显示它应该如何编码。我已经实现了秒表来计算不同魔方大小所需的刻度。
这段代码适用于随机位,但它所花费的时间似乎没有意义,因为它比 Fisher Yates 更快。
Random rand = new Random();
for (int i = rubikCubeArray.Length - 1; i > 7; i--)
{
int n = rand.Next(i + 1);
int temp = rubikCubeArray[i];
rubikCubeArray[i] = rubikCubeArray[n];
rubikCubeArray[n] = temp;
}
请帮忙吗?
-
常见的起始种子是个好主意(正如JDWENG指出的那样)
我只是需要修复那个错别字,因为菜鸟可能不知道应该
seen
seed
。这样,两种比较的算法将具有相同的条件。 -
嵌套的循环
不熟悉 7-Riffle 随机算法,但回溯求解器应该嵌套循环。现在你得到了一个循环9次(为什么?
如果您有
N=7
轮洗立方体,则需要 7 个嵌套的循环,每个循环遍历所有可能的轮次3*3*2=18
。如果N
正在更改,则需要动态嵌套循环以获取更多信息,请参阅:- 动态嵌套用于循环
nested_for
或可屏蔽嵌套的循环,最高可达神数 (
20
)。每次迭代中的每个 for 循环都会通过选定的移动来转动前一个循环状态立方体,并且在最后一个循环中还应该检测已解决的情况并在找到时中断。
所以像这样(求解器):
cube0=solved_cube(); for (cube1=cube0,i1=0; i1<18; i1++,cube1=turn_cube(cube0,i1)) for (cube2=cube1,i2=0; i2<18; i2++,cube2=turn_cube(cube1,i2)) ... for (cube7=cube6,i7=0; i7<18; i7++,cube7=turn_cube(cube1,i7)) if (cube7 == solved_cube()) return { i1,i2,...,i7 }; // solution found return false; // unsolved
其中
turn_cube(cube a,int turn)
将返回由turn
转动的立方体a
其中turn
选择哪个切片朝哪个方向转动(18 个可能的转弯中的哪一个)...... - 动态嵌套用于循环
您也可能对此感兴趣:
- 四元数旋转不工作,例外
[编辑1] 洗牌机
正如我提到的,我不熟悉 7 个 riffle shuffle 算法,所以如果你只是想让一个立方体从解决状态 7 圈,那么你几乎是对的。你应该有单for
循环,但在内部你需要进行有效的随机移动
cube=solved_cube();
for (i=0; i<7; i++)
cube=turn_cube(cube,Random(18));
现在真正的问题是编写turn_cube函数。为了帮助解决这个问题,我们需要更多地了解你如何在内部表示你的魔方。
那么它是1D,2D还是3D阵列?拓扑是什么?元素值是什么(十六进制颜色可能是或只是0..5
或某个枚举或转换矩阵)?
在上面的链接中是地雷求解器的示例,其中包含源代码以运行 voidRubiCube::cube_rotate(int axis,int slice,double ang)
这或多或少是cube_turn应该做的。有 18 个可能的回合:
- 3 轴 (
axis
) - 每个轴有3个切片(
slice
) - 我们可以将 CW 或 CCW 旋转 90 度(
ang
请注意我的 ang 以弧度为单位,并在我为转弯制作动画时允许 arbitarry 角度)
因此,您需要将这 18 个案例映射到int turn = <0,17>
这些案例将在cube_turn中进行处理并应用于您的多维数据集......