Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
特定条件下置换的Python实现_Python_Algorithm_Permutation - Fatal编程技术网

特定条件下置换的Python实现

特定条件下置换的Python实现,python,algorithm,permutation,Python,Algorithm,Permutation,在下列条件下,如何生成置换 有两个整数,例如1和4 给定的两个整数将是排列的一部分,其中每个整数最多出现N次,每个排列的大小为K 因此,假设对于N=3和K=5,正确的结果应该是: {1,1,1,4,4},{1,1,4,1,4},{4,4,4,1,1},等等 以下是无效或不正确的结果示例: {1,1,1,1,4}->1出现4次(1应不超过3次) {1,4,4,4,1,1}->列表的大小是6(大小应该正好是5) 此外,每个排列应该是唯一的,这意味着没有重复 我希望我能得到这个问题的最佳解决方案或算法

在下列条件下,如何生成置换

  • 有两个整数,例如1和4
  • 给定的两个整数将是排列的一部分,其中每个整数最多出现N次,每个排列的大小为K
  • 因此,假设对于N=3K=5,正确的结果应该是:

    {1,1,1,4,4},{1,1,4,1,4},{4,4,4,1,1},等等

    以下是无效或不正确的结果示例:

    {1,1,1,1,4}->1出现4次(1应不超过3次)

    {1,4,4,4,1,1}->列表的大小是6(大小应该正好是5)

    此外,每个排列应该是唯一的,这意味着没有重复

    我希望我能得到这个问题的最佳解决方案或算法


    提前感谢。:)

    看看这是否适合你

    >>> K=5
    >>> N=3
    >>> src=[['1']*n+['4']*(K-n) for n in xrange(K-N,N+1)]
    >>> set(x for s in src for x in itertools.permutations(s))
    set([('1', '4', '1', '4', '1'), ('4', '1', '4', '1', '1'), ('1', '1', '4', '4', '4'), ('1', '4', '4', '1', '1'), ('1', '4', '4', '4', '1'), ('4', '4', '4', '1', '1'), ('4', '1', '1', '4', '1'), ('4', '4', '1', '4', '1'), ('1', '4', '1', '1', '4'), ('4', '1', '4', '4', '1'), ('1', '1', '4', '4', '1'), ('1', '4', '4', '1', '4'), ('4', '1', '4', '1', '4'), ('4', '1', '1', '1', '4'), ('4', '4', '1', '1', '4'), ('1', '4', '1', '4', '4'), ('1', '1', '4', '1', '4'), ('4', '4', '1', '1', '1'), ('4', '1', '1', '4', '4'), ('1', '1', '1', '4', '4')])
    
    注**

    首先使用“1”和“4”创建所有可能的组合。请注意,限制了特定整数的最大N个实例,因此在一组K个数中,如果x有i个实例,那么对于两个数(x,y),y有(K-i)个实例。在这种情况下,i和x都应该在[K-N,N]范围内


    现在,下一步是使用生成器理解来创建上述集合的所有可能实例的所有可能迭代。我使用集合理解来删除任何副本,并且使用生成器来不存储中间副本结果

    这是思考这个问题的一种方式,尽管我想知道一个更优雅的解决方案:

    假设N=3,K=5,如上所述。 我将使用
    a
    b
    来代替你的'1'和'4',否则我会把自己弄糊涂:P

    由于每个符号(
    a
    b
    )最多只允许出现3次,这意味着我们希望获得以下所有排列:

    • 2
      a
      s在一个5
      b
      s的字符串中
    • 3
      a
      s在一个5
      b
      s的字符串中
    所以我们只需要找到
    {a,a,b,b,b}
    {a,a,a,b,b}
    的所有排列

    一般来说,您只需要找到
    {m lots a和(K-m)lots b}
    的排列,其中
    m
    位于
    {K-N,K-N+1,K-N+2,…N}

    一种方法是:

  • 设置N,K
  • 设置
    m=K-N
  • 用长度为K的
    b
    创建一个列表,称之为
    x
  • 将索引列表放入
    x
    (即
    0,1,2,…,K-1
    ),并将长度
    m
    的所有子集放入该列表。这些将是我们放置
    a
    s的位置
  • m=K-N,K-N+1,N
  • 要执行步骤4,我们使用模块
    itertools
    ,尤其是
    itertools.compositions

    因此:

    然后:


    另一种方法是使用
    itertools.permutations
    查找
    {m lots of symbol1,和(K-m)lots of symbol2}
    的所有置换。除了在那里得到重复(因为Python基于元素的唯一位置进行排列,而不是元素的唯一值)。然后你需要过滤掉它们,一旦
    K
    N
    变大,它们就会变得昂贵。这就是我选择上述方法的原因,因为它不存在重复的问题。

    对于较小的K值,我将从0计数到2^K-1,跳过二进制表示形式大于n0或大于n1的值,然后将0位转换为“1”,将1位转换为“4”

    对于较大的K值,可以使用回溯搜索-

    PseudoCode (int N, int K, int num1s, int num4s, String sofar)
      if (num1s > K)
         return
      if (num4s > K)
         return
      length(sofar) == N
         print sofar
         return
      PseudoCode (N, K, num1s + 1, num4s, sofar + "1")
      PseudoCode (N, K, num1s, num4s + 1, sofar + "4")
    
    从这里开始(如阿比吉特的回答)


    …然后,您可以为每个列表选择。另外,如果NN=max(N,K-N)

    来处理这个问题。呃,忽略这个答案,@Abhijit's更好:p。我不知道
    set
    。谢谢你的解释。无论如何,使用你的代码,我尝试了类似len(notQuitePermutations(50100,1,5))的东西,我得到了一个“MemoryError”,所以我想它对于较大的值是无效的。我想要的是一个有效的算法。不,不要忽略这个,它对更大的N和K更有效。嗨,我试过这个,我得到一个错误,说“s”没有定义。同样根据您的输出,4始终最多只出现2次,这样的排列->(4,4,4,1,1)也应该考虑。所以基本上你的输出是不完整的。。谢谢你的努力。@Manie,有个小问题我解决了。您现在应该得到类似于您提到的排列。顺便问一下,你使用的是什么版本的python?你能提供完整的堆栈跟踪吗?我看不出这有什么理由不起作用。只要尝试一下,如果失败了,请提供堆栈跟踪。嗨,我得到了它,我所做的是将集合(在itertools.permutations(s)for s in src)重新排列为set(x for s in src for x in itertools.permutations(s)),以获得正确的结果。是的,这是我的问题。您可以检查上面的修复。理解src时也有一个问题,现在已经解决了。@Manie,顺便说一句,如果这个解决方案有效,您可能希望选择这个答案作为接受的答案
    >>> notQuitePermutations(3,5,1,4)
    [[1, 1, 4, 4, 4], [1, 4, 1, 4, 4], [1, 4, 4, 1, 4],....    
    
    PseudoCode (int N, int K, int num1s, int num4s, String sofar)
      if (num1s > K)
         return
      if (num4s > K)
         return
      length(sofar) == N
         print sofar
         return
      PseudoCode (N, K, num1s + 1, num4s, sofar + "1")
      PseudoCode (N, K, num1s, num4s + 1, sofar + "4")
    
    >>> K=5
    >>> N=3
    >>> [['1']*n+['4']*(K-n) for n in xrange(K-N,N+1)]
    [['1', '1', '4', '4', '4'], ['1', '1', '1', '4', '4']]