Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.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
Algorithm 如何计算所有唯一排列并保持相同的正相邻元素始终相邻?_Algorithm_Combinations - Fatal编程技术网

Algorithm 如何计算所有唯一排列并保持相同的正相邻元素始终相邻?

Algorithm 如何计算所有唯一排列并保持相同的正相邻元素始终相邻?,algorithm,combinations,Algorithm,Combinations,我有一个非负整数的列表或向量V。有些正整数是相等且相邻的,比如说V=[2,3,3,0,0]。(我不关心零整数。) 我想找到V的所有唯一排列,以便所有相同的正整数保持相邻。如何为此编写算法?(对于实现,可以选择Python、Matlab或任何其他语言。) 在Matlab下,以V=[2,3,3,0,0]为例,我得到了所有唯一的置换,如下所示: V = [2, 3, 3, 0, 0]; unique(perms([2, 3, 3, 0, 0]), 'rows') 我得到: 0 0

我有一个非负整数的列表或向量
V
。有些正整数是相等且相邻的,比如说
V=[2,3,3,0,0]
。(我不关心零整数。)

我想找到
V
的所有唯一排列,以便所有相同的正整数保持相邻。如何为此编写算法?(对于实现,可以选择Python、Matlab或任何其他语言。)

在Matlab下,以
V=[2,3,3,0,0]
为例,我得到了所有唯一的置换,如下所示:

V = [2, 3, 3, 0, 0];
unique(perms([2, 3, 3, 0, 0]), 'rows')
我得到:

 0     0     2     3     3
 0     0     3     2     3
 0     0     3     3     2
 0     2     0     3     3
 0     2     3     0     3
 0     2     3     3     0
 0     3     0     2     3
 0     3     0     3     2
 0     3     2     0     3
 0     3     2     3     0
 0     3     3     0     2
 0     3     3     2     0
 2     0     0     3     3
 2     0     3     0     3
 2     0     3     3     0
 2     3     0     0     3
 2     3     0     3     0
 2     3     3     0     0
 3     0     0     2     3
 3     0     0     3     2
 3     0     2     0     3
 3     0     2     3     0
 3     0     3     0     2
 3     0     3     2     0
 3     2     0     0     3
 3     2     0     3     0
 3     2     3     0     0
 3     3     0     0     2
 3     3     0     2     0
 3     3     2     0     0
你可能知道,我得到了30个这样的排列。在这些
30
中,有
18
不遵守邻接约束。例如,
[3,2,3,0,0]
不能出现在最终结果中,因为
3
不再与
3
相邻。最后,所有唯一排列可通过以下方式给出:

 0     0     2     3     3
 0     0     3     3     2
 0     2     0     3     3
 0     2     3     3     0
 0     3     3     0     2
 0     3     3     2     0
 2     0     0     3     3
 2     0     3     3     0
 2     3     3     0     0
 3     3     0     0     2
 3     3     0     2     0
 3     3     2     0     0
我想到的第一个想法(也是最简单的)是生成所有这样的唯一排列,然后,为每个排列验证约束。但是还有其他有效的算法吗?

一个简单的算法是:

1.遍历初始表格并创建另一个包含两行的表格,如:

input: V = [2, 3, 3, 0, 0];

new array: V2 = |2,3,0|
                |1,2,2|
正如您所看到的,V2来自于V,它只保留一次元素,并在第二行计算我们看到它们的次数

  • 现在生成列的所有排列
  • 对于每个结果,例如:

    V2 = |3,2,0|
         |2,1,2|    
    
    您保留了元素出现的次数。

    • 我们可以首先压缩给定的数组,使每个正数只有一个条目,同时保持每个数字出现的次数计数(零应保持原样)

    • 生成压缩数组的置换

    • 解压每个排列,只保留唯一的排列

    压缩 解压 将其组合在一起:压缩、置换、解压缩和保留唯一性 结果:
    你希望所有的正数都在一起还是只希望相同的正数在一起?我希望所有相同且相邻的正数都在一起(保持相邻)。将相邻元素的每个“运行”视为单个元素,然后使用任何标准排列算法。
    def compress(arr):
        counts = {}
        compressed = []
        curr_ele = arr[0]
        count_ele = 0
        for ele in arr:
            if ele != curr_ele or ele == 0:
                counts[curr_ele] = count_ele
                compressed.append(curr_ele)
                count_ele = 1
                curr_ele = ele
            else:
                count_ele += 1
        counts[curr_ele] = count_ele
        compressed.append(curr_ele)
        return compressed, counts
    
    def uncompress(arr, counts):
        res = []
        for ele in arr:
            if ele == 0:
                res.append(0)
                continue
            num_reps = counts[ele]
            for _ in range(num_reps):
                res.append(ele)
        return res
    
    import itertools
    ip = [2, 3, 3, 0, 0]
    ip_compressed, counts = compress(ip)
    set([tuple(uncompress(perm, counts)) for perm in itertools.permutations(ip_compressed)])
    
    {(0, 0, 2, 3, 3),
     (0, 0, 3, 3, 2),
     (0, 2, 0, 3, 3),
     (0, 2, 3, 3, 0),
     (0, 3, 3, 0, 2),
     (0, 3, 3, 2, 0),
     (2, 0, 0, 3, 3),
     (2, 0, 3, 3, 0),
     (2, 3, 3, 0, 0),
     (3, 3, 0, 0, 2),
     (3, 3, 0, 2, 0),
     (3, 3, 2, 0, 0)}