我正在寻找一种算法,给定一组数字{0,1,2,4,5 ...}和一组关于每个元素的相对位置的条件,将检查是否存在有效的排列。条件始终为“原始数组中位置i中的元素必须与位置j或z中的元素相邻(相邻)”。
排列中的最后一个元素和第一个元素被认为是相邻的。
这是一个简单的例子:
让数字为{0,1,2,3} 和一组条件:a0必须在a1旁边,a0必须在a2旁边,a3必须在a1旁边 这个例子的有效解决方案是{0,1,3,2}。
请注意,此解决方案的任何旋转/对称也是有效的解决方案。我只需要证明存在这样的解决方案。
使用相同集合的另一个例子:
a0必须在a1旁边,a0必须在a3旁边,a0必须在a2旁边。
此示例没有有效的解决方案,因为数字只能与2个数字相邻。
我现在能想出的唯一想法就是使用某种回溯方式 如果存在解决方案,则应该快速收敛。如果没有解决方案,我无法想象有任何方法可以避免检查所有可能的排列。 正如我已经说过的,旋转或对称不会影响给定排列的结果,因此应该可以减少可能性的数量。
答案 0 :(得分:1)
基本上你想知道你是否可以创建数字链。将每个数字放入一个链中,跟踪数字和最多两个邻居。使用规则将链连接在一起。当你加入两个链条时,你最终会得到一个带有两个松散末端(邻居)的链条。如果你能够完成所有规则而不会耗尽松散的结果,那么它就可以了。
答案 1 :(得分:1)
将此表示为图形问题。连接每对需要彼此相邻的数字。您将最终得到一堆连接组件。每个组件都有许多排列(让我们称之为迷你排列),你可以对组件进行排列。
创建图形时,请确保每个组件遵循一系列规则:没有循环,没有顶点超过两个顶点等。
答案 2 :(得分:0)
我已经稍微修改了图表解决方案。
如果某个节点有太多邻居,算法会丢弃一条边并再次检查图形。 然后我使用回溯来回滚并检查是否可以放下下一个边缘...... 这种方法给出了与我写的蛮力方法相同的结果。
就复杂性而言,这个解决方案似乎比蛮力更好,尽管我不能在20多个数字上运行它(蛮力只有8个)。在敏感中,这是合乎逻辑的,因为这样的图实际上可以一次生成有效置换的子集,而在最坏的情况下,它等同于在边集上找到一些合成。毕竟它是回溯。
鉴于旋转对排列的有效性没有任何影响,我正在考虑将a0固定在第一个位置(这可以通过简单地旋转有效排列直到a0位于第一个位置来实现)然后尝试从那里构建解决方案。
使用DP我可能会获得比指数复杂性更好的东西。但我必须说,我仍然不确定从哪里开始:)