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)}