如何找到将列表分解为大小大于 2 的块的所有可能分解的列表
对于给定的 N,我有一个从 0 到 N-1 的所有数字的列表
A = list(range(0,N));
,并且我想找到所有可能分解为大小为 2 或更大的列表的列表,而不重复。例如,对于 N=4 我有
A = [0,1,2,3];
并且我想要的输出是
OUT = [[[0, 1, 2, 3]], [[0, 1], [2, 3]], [[0, 2], [1, 3]], [[0, 3], [1, 2]]];
Up to N=5,将初始列表分解为仅两部分(长度为 2 和 3)使问题变得非常简单。但是,我找不到一种方法来实现更高的 N,因为长度为 4 的列表必须进一步分成两个长度为 2 的列表。
有谁对如何解决这个问题有任何建议吗?我觉得一定有一个简单的递归技巧来做到这一点,但我已经尝试了一天了,我有点卡住了!
谢谢!
PS:N小于6的结果是:
N=1) OUT = [[[0]]];
N=2) OUT = [[[0, 1]]];
N=3) OUT = [[[0, 1, 2]]];
N=4) OUT = [[[0, 1, 2, 3]], [[0, 1], [2, 3]], [[0, 2], [1, 3]], [[0, 3], [1, 2]]];
N=5) OUT = [[[0, 1, 2, 3, 4]], [[0, 1], [2, 3, 4]], [[0, 2], [1, 3, 4]], [[0, 3], [1, 2, 4]], [[0, 4], [1, 2, 3]], [[1, 2], [0, 3, 4]], [[1, 3], [0, 2, 4]], [[1, 4], [0, 2, 3]], [[2, 3], [0, 1, 4]], [[2, 4], [0, 1, 3]], [[3, 4], [0, 1, 2]]];
PPS:我是一名物理学家,有一段时间没有编程了;代码可能看起来很糟糕,而且问题可能很简单......对此感到抱歉!
For a given N, I have a list of all numbers from 0 to N-1
A = list(range(0,N));
and I want to find a list of all possible decompositions into lists of sizes two or higher, without repetitions. For example, for N=4 I have
A = [0,1,2,3];
and the output I want is
OUT = [[[0, 1, 2, 3]], [[0, 1], [2, 3]], [[0, 2], [1, 3]], [[0, 3], [1, 2]]];
Up to N=5, the decomposition of the initial list into only two pieces (of length 2 and 3) makes the problem very easy. However, I can't find a way to do it for higher N, since the lists of length four must be further split into two lists of length 2.
Does anyone have any suggestions on how to solve this? I feel there must be a straightforward recursive trick to do this, but I have been trying for a day now, and I am a little stuck!
Thanks!
PS: the results for N smaller than 6 are:
N=1) OUT = [[[0]]];
N=2) OUT = [[[0, 1]]];
N=3) OUT = [[[0, 1, 2]]];
N=4) OUT = [[[0, 1, 2, 3]], [[0, 1], [2, 3]], [[0, 2], [1, 3]], [[0, 3], [1, 2]]];
N=5) OUT = [[[0, 1, 2, 3, 4]], [[0, 1], [2, 3, 4]], [[0, 2], [1, 3, 4]], [[0, 3], [1, 2, 4]], [[0, 4], [1, 2, 3]], [[1, 2], [0, 3, 4]], [[1, 3], [0, 2, 4]], [[1, 4], [0, 2, 3]], [[2, 3], [0, 1, 4]], [[2, 4], [0, 1, 3]], [[3, 4], [0, 1, 2]]];
PPS: I am a physicist and haven't been programming for a while; the code probably looks terrible, and the problem might be very easy... sorry for that!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
考虑最后一项,即
N-1
,假设我们有两组组合。一种用于list(range(0,N-1))
,另一种用于list(range(0,N-2))
。现在,如果您想将最后一项放入这些组合中,则应该对每个组合采用不同的方法,我在下面对此进行了解释:list(range(0, N-1))
:要将最后一个项目放入这些组合中,您别无选择,只能将其放入已经可用的集合之一中,以便更好地理解这一点,考虑到您拥有所有四个组合,现在您想向此组合添加 5 个。所以你有:<代码>[[[0, 1, 2, 3]], [[0, 1], [2, 3]], [[0, 2], [1, 3]], [[0 , 3], [1, 2]]]
将最后一项(即 4)添加到这些组合中将使我们得到如下所示的结果:
<代码>[[[0, 1, 2, 3, 4]], [[0, 1, 4], [2, 3]], [[0, 1], [2, 3, 4 ]], [[0, 2, 4], [1, 3]], [[0, 2], [1, 3, 4]], [[0, 3, 4], [1, 2]], [[0, 3], [1, 2, 4]]]
我们在每个组合中放入 4 个,并用它们组成新的组合。因此,对于这一部分,我们需要对
N-1
进行递归调用。正如您在这种情况下所看到的,N-1
所在的每个集合至少包含三个项目。这是因为我们扩展了我们的集合,该集合已经存在并且至少有两个项目。N-2
项的组合:当N-1
位于只有两项的集合中时,我考虑过这种情况。要找到这些组合,我们需要选择其余N-1
项中的一项,并将该选定项与项N-1
视为一组,并找到所有其他组合其余的N-2
项。再次举个例子,请考虑N = 5
,因此最后一项是4
。如果我们想将最后一个项目与3
配对,我们可以构建(0, 1, 2)
的所有组合,并将(3, 4 )
来混合。N=5
的情况如下:<代码>[[[0 , 1 , 2] , [3 , 4]] , [[0 , 1 , 3] , [2 , 4]] , [[0 , 2 , 3] , [1 , 4]] , [[ 1 , 2 , 3] , [0 , 4]]]
我已经使用 python 中的递归函数实现了这一点。我不是 python 开发人员,因此实现中可能有一些增强,但算法工作正常:
您可以在 Colab
编辑:我已添加记忆稍微提高了性能,但我的
build_from_memory
不是O(1)
,所以如果我可以提高该函数的性能,改进可能会更好。Consider the last item i.e
N-1
, suppose we have two sets of combinations. one forlist(range(0,N-1))
and one forlist(range(0,N-2))
. Now, if you want to put the last item in these combinations, you should have a different approach for each one of them, which I've explained below:Combinations of
list(range(0, N-1))
: To put the last item in these combinations, you have no choice other than to put it in one of the sets that are already available to understand this better consider that you have all combinations for four and now you want to add 5 to this combination. So you have :[[[0, 1, 2, 3]], [[0, 1], [2, 3]], [[0, 2], [1, 3]], [[0, 3], [1, 2]]]
Adding last item( i.e 4) to these combination would get us something like bellow:
[[[0, 1, 2, 3, 4]], [[0, 1, 4], [2, 3]], [[0, 1], [2, 3, 4]], [[0, 2, 4], [1, 3]], [[0, 2], [1, 3, 4]], [[0, 3, 4], [1, 2]], [[0, 3], [1, 2, 4]]]
We put 4 in every combination and make new combinations out of them. So for this part, we need a recursive call for
N-1
. As you can see in this situation, each sets thatN-1
is in has at least three items. That's because we expanded our set, which already existed and had at least two items.Combinations of
N-2
items: I've considered this for whenN-1
is in a set with only two items. To find these combinations, we need to select one of the restN-1
items and consider that selected item with itemN-1
as one set and find every other combination for the rest ofN-2
items. To give you an example again, considerN = 5
so the last item is4
. If we want to pair the last item with3
, we could build all combinations for(0, 1, 2)
and put pair of the(3, 4)
to the mix. It would be something like this forN=5
:[[[0 , 1 , 2] , [3 , 4]] , [[0 , 1 , 3] , [2 , 4]] , [[0 , 2 , 3] , [1 , 4]] , [[ 1 , 2 , 3] , [0 , 4]]]
I've implemented this using recursive functions in python. I'm not a python developer, so there may be some enhancements in implementations, but the algorithm is working fine:
You could run this code on Colab
Edit: I've added memorization to improve the performance a little bit, but my
build_from_memory
is notO(1)
, so the improvement could be much better if I could improve the performance of that function.