Algorithm 桶置换算法
我正在寻找一个这样的算法Algorithm 桶置换算法,algorithm,permutation,Algorithm,Permutation,我正在寻找一个这样的算法 permutateBuckets([A,B,C]) 并给出以下结果: [ [[A,B,C]], [[A,B],[C]], [[A,C],[B]], [[B,C],[A]], [[A],[B,C]], [[B],[A,C]], [[C],[A,B]], [[A],[B],[C]], [[A],[C],[B]], [[B],[A],[C]], [[B],[C],[A]], [[C],[A],[B]], [[C],[B],[A]] ] 一般而言: [1,2,…,n
permutateBuckets([A,B,C])
并给出以下结果:
[ [[A,B,C]],
[[A,B],[C]], [[A,C],[B]], [[B,C],[A]], [[A],[B,C]], [[B],[A,C]], [[C],[A,B]],
[[A],[B],[C]], [[A],[C],[B]], [[B],[A],[C]], [[B],[C],[A]], [[C],[A],[B]], [[C],[B],[A]]
]
一般而言:
[1,2,…,n]的排列应包括1到n个包含输入值的存储桶的任何可能排列,存储桶中的值顺序不相关(例如[1,2]等于[2,1]),只有包含存储桶的顺序才重要(例如[1,2],[3]]不同于[3],[1,2]])
每个输入元素必须正好位于一个存储桶中,才能使结果有效(例如,[1,2]的输入不能给出[[1]](缺少2)或[[1,2],[1]](1出现两次)作为输出)。最简单的方法是递归:
Make [[A]] list
Insert new item in all possible places -
before current sublists
between all sublists
after current sublists
into every sublist
例如,列表[[B][A]]
生成5个带有项目C的新列表-插入C的位置为:
[ [B] [A] ]
^ ^ ^ ^ ^
三个二级列表产生5+5+3=13个三级列表
替代方式:生成从1…1到1…n的所有n长度非减量序列,并为每个序列生成唯一的置换。 这些排列上的值对应于每个项目的桶号。例如,122序列给出了3个对应于分布的排列:
1 2 2 [1],[2, 3]
2 1 2 [2],[1, 3]
2 2 1 [3],[1, 2]
在任何情况下,分布的数量都会迅速增加(有序钟形编号1、3、13、75541、468347293、5458357087261102247563…
)
在Delphi中实现迭代方法(完整的FP兼容代码at)
现在是Python递归实现()
编辑:@mhmnn在使用自定义项进行输出时克隆了此代码。递归方法当然更容易,但可能不是最有效的解决方案。您对这种递归方法满意吗?(我没有解决方案,只是想知道您的期望)。我还认为递归方法将是最有效的方法-我对递归或顺序都很好。我将尝试明天编写该方法的代码并发布我的结果,谢谢!我基于您的Python代码在JavaScript中实现了它,并通过接受一个带有被置换值的数组来扩展它。代码可以在这里找到:请随意将代码添加到您的答案中,以获得更高的可见性-请注意,Lodash.js用于cloneDeep函数。
procedure GenDistributions(N: Integer);
var
seq, t, i, mx: Integer;
Data: array of Byte;
Dist: TBytes2D;
begin
SetLength(Data, N);
//there are n-1 places for incrementing
//so 2^(n-1) possible sequences
for seq := 0 to 1 shl (N - 1) - 1 do begin
t := seq;
mx := 0;
Data[0] := mx;
for i := 1 to N - 1 do begin
mx := mx + (t and 1); //check for the lowest bit
Data[i] := mx;
t := t shr 1;
end;
//here Data contains nondecreasing sequence 0..mx, increment is 0 or 1
//Data[i] corresponds to the number of sublist which item i belongs to
repeat
Dist := nil;
SetLength(Dist, mx + 1); // reset result array into [][][] state
for i := 0 to N - 1 do
Dist[Data[i]] := Dist[Data[i]] + [i]; //add item to calculated sublist
PrintOut(Dist);
until not NextPerm(Data); //generates next permutation if possible
end;
import copy
cnt = 0
def ModifySublist(Ls, idx, value):
res = copy.deepcopy(Ls)
res[idx].append(value)
return res
def InsertSublist(Ls, idx, value):
res = copy.deepcopy(Ls)
res.insert(idx, [value])
return res
def GenDists(AList, Level, Limit):
global cnt
if (Level==Limit):
print( AList)
cnt += 1
else:
for i in range(len(AList)):
GenDists(ModifySublist(AList, i, Level), Level + 1, Limit)
GenDists(InsertSublist(AList, i, Level), Level + 1, Limit)
GenDists(InsertSublist(AList, len(AList), Level), Level + 1, Limit)
GenDists([], 0, 3)
print(cnt)