algorithm - 是否存在可以生成所有可能排列的交换序列?

标签 algorithm permutation

<分区>

给你一个数字列表 1, 2, ... ,n - 是否有 n!-1 swap 的序列> 将生成列表的所有 n! 排列的操作,其中 swap (i, j) 交换单元格 ij 中的元素?当输入列表未按开头排序和/或列表中有重复时,一般情况如何?

上下文:我正在解决一个问题,如果您已经知道交换 2 个元素的分数并且我想蛮力计算数组的“分数”很容易(使用 C++ next_permutation()) 所有可能的排列。

最佳答案

当然,17 世纪的敲钟人就知道了。那么对于一些组合历史来说怎么样?

参见 the Steinhaus Johnson Trotter algorithm或咨询您本地的变更电话小组。


我对你问题的第二部分做了一些研究,即是否可以用重复的元素来做到这一点。我相信答案是“是的,但没那么容易”。此外,不可能通过仅相邻交换来置换具有重复元素的列表,对于集合 {0, 0, 1, 1} 可以很容易地看出这一点。但是,仅进行一次交换是可能的。

基本方法是使用基本的更改振铃算法,但是是在一组相同的元素上而不是在单个元素上。对于一组 k 相同的元素,您需要能够对列表 0n-k1k 的组合进行算法(其中 n 是基集的总大小)。存在许多这样的算法,但我找不到任何真正简单的算法;最简单的方法是(粗略地说)为整个组分配一个方向,也为每个 1 分配一个方向(以类似于 Shimon Even 算法的方式)。向左移动组时,最左边的元素来回扫过;每次它改变方向时,右边的下一个移动元素都会移动一个;等等。这最终将整个组从列表的右侧移动到左侧,之后它的整体方向被翻转并返回到原始配置,现在最右边的元素领导扫描。

由于在这种情况下方向反转的次数可能是偶数,因此上述算法可能无法追踪出排列循环,但我相信可以使用更复杂的算法来生成循环。实际上,您正在寻找由每个排列可能的单次交换引起的哈密顿循环——置换面体的变体——但是,虽然哈密顿循环确实存在,但它们并不容易找到,因为图形是相当大。

关于algorithm - 是否存在可以生成所有可能排列的交换序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13205573/

相关文章:

最大化矩阵的最小对角线元素的算法

python - numpy - 使用 numpy 一维数组的置换副本构建二维数组的最快方法

python - 如何在 Scipy Python 稀疏矩阵中实现 CSR_Matrix 的循环置换(左移和右移)?

algorithm - 在 F# 中计算排列

algorithm - 合并 2 个二叉搜索树

python - NetworkX:如何为现有的 G.edges() 添加权重?

algorithm - n log n 是 O(n)?

algorithm - 2人游戏的最优策略

c - 用 C 为所有可能的排列设计一个算法,包括零

c++ - 在数组中查找整数的有效分配(具有给定顺序的排列)