C 生成对的所有置换,不包括单个元素的置换

C 生成对的所有置换,不包括单个元素的置换,c,algorithm,permutation,combinatorics,C,Algorithm,Permutation,Combinatorics,我想生成有序对(a,b)的所有置换,其中a!=b、 a,b是集合S的元素(假设S:={1..k}),但不包括S的单个元素的置换 例如,设置k=2,可能的有序对为(1,2),(2,1),给出2个可能的序列: (1,2)、(2,1) (2,1)、(1,2) 但是在{1->2,2->1}的置换映射下,它们实际上是重复的 对于k=3,将有6个可能的有序对,给出6!序列(包括重复序列)。但是有3个!=k个可能的置换,所需的唯一序列数为5!,只需取以对(1,2)开头的序列即可轻松生成 在一般情况下,会有

我想生成有序对(a,b)的所有置换,其中a!=b、 a,b是集合S的元素(假设S:={1..k}),但不包括S的单个元素的置换

例如,设置k=2,可能的有序对为(1,2),(2,1),给出2个可能的序列:

  • (1,2)、(2,1)
  • (2,1)、(1,2)
但是在{1->2,2->1}的置换映射下,它们实际上是重复的

对于k=3,将有6个可能的有序对,给出6!序列(包括重复序列)。但是有3个!=k个可能的置换,所需的唯一序列数为5!,只需取以对(1,2)开头的序列即可轻松生成

在一般情况下,会有k*(k-1)对,给出[k*(k-1)]!序列(包括重复的),并且会有k!置换,所以我应该以[k*(k-1)]结尾K序列


我只打算使用较小的k值,但我想知道是否有生成这些序列的好方法。我相当确定这是一个过滤出唯一序列[允许重复元素]的特殊情况,受这些序列中可能元素排列的影响,但也许我所寻找的东西有一些特别之处,比生成所有可能序列然后过滤的暴力方法更容易。

看看回溯算法:


生成置换是一个NPC问题,所以所有的解决方案都会具有指数复杂度。

< P>我认为你可以扩展你的方法,只生成从(1,2)开始的序列,只生成序列,如果你依次考虑每个数字,则要么:

  • 该数字与前一个数字匹配
  • 该数字是下一个看不见的数字
  • 所以像(1,2)(2,1)和(1,2)(3,4)这样的序列是允许的,但不允许(1,2)(4,5),因为4违反了规则(3是这个阶段下一个看不见的数字)

    考虑到这一点,您可以通过依次选择每一对来递归地生成所有组合,其中每一对都必须是新的对,并且满足规则

    e、 g.对于k=3

    (1,2) Only option for level 1
    (1,2) can be followed by (2,1) or (1,3) or (2,3) or (3,1) or (3,2)
    (1,2)(2,1) can be followed by (3,1) or (3,2) or (1,3) or (2,3)
    (1,2)(2,1)(3,1) can be followed by...
    

    (1) 问题也是多项式可解的问题。你可能是说。(2) 这不是NP完全问题,因为输出大小是指数的,所以即使P=NP,这个问题也没有多项式解。此外,OP已经描述了一种使用置换的方法,但是为了避免产生太多的排列并丢弃其中一个排列所带来的开销,枚举算法通常是根据产生每一个输出所需的时间来判断的。对于Peter的算法,这一时间是由一个k的多项式限定的。@JKB从我对问题的理解来看,他尝试创建所有置换并丢弃冗余。但这需要相当大的开销——创建最终不需要的记录。他正在寻找一种方法来直接计算期望的结果,而不需要这些开销。@amit你是对的,OP想要除去开销,但是如果他给出一些除去开销的方法,那么它将是batter。因此我们可以考虑他的方法如果他继续正确的方法,那么我们将伸出手来实现他的方法。很抱歉,我对OP立即做出了不必要的回应。下次我会记住这一点。我也已经删除了我之前的评论。再次感谢阿米特。这就是解决问题的方法。我们可以用它来证明这一点。该算法使用字典最小值作为其标准标号,构造该标号的隐式算法很简单:将第j个不同出现的元素映射到j。因为标记算法是在线的,所以上下对象的内容很简单。