这是我想写的一个函数,但无法这样做。即使你
不/不能给出解决方案,如果有提示,我将不胜感激。例如,
我知道有序表示之间存在相关性
整数和有序集分区的总和,但仅此一点并不能帮助我
找到解决方案。所以这里是我需要的函数的描述:
任务
创建一个高效的*函数
List<int[]> createOrderedPartitions(int n_1, int n_2,..., int n_k)
,返回集合的所有集合部分的数组列表
{0,...,n_1+n_2+...+n_k-1}
位于 参数数量
大小的块中(在此
顺序)n_1,n_2,...,n_k
(例如n_1=2, n_2=1, n_3=1 -> ({0,1},{3},{2 }),...
)。
这是一个用法示例:
int[] partition = createOrderedPartitions(2,1,1).get(0);
partition[0]; // -> 0
partition[1]; // -> 1
partition[2]; // -> 3
partition[3]; // -> 2
请注意,列表中的元素数量是
(n_1+n_2+...+n_n 选择 n_1) * (n_2+n_3+...+n_n 选择 n_2) * ... *
(n_k 选择 n_k)
。此外,createOrderedPartitions(1,1,1)
将创建
{0,1,2}
的排列,因此会有 3! = 6
元素
列表。
* 通过高效我的意思是你不应该最初创建一个更大的列表
像所有分区一样,然后过滤掉结果。你应该直接这样做。
额外要求
如果参数为 0,则将其视为不存在,例如
createOrderedPartitions(2,0,1,1)
应该产生与以下相同的结果
createOrderedPartitions(2,1,1)
。但至少有一个参数不能为 0。
当然,所有参数必须 >= 0。
备注
提供的伪代码是准 Java,但解决方案的语言
没关系。事实上,只要解决方案相当通用并且可以
能用其他语言复制是理想的。
实际上,更好的是 List>
返回类型(例如,当
在 Python 中创建这样的函数)。然而,随后的论点有
不得忽略 0 值。 createOrderedPartitions(2,0,2)
然后
创建
[({0,1},{},{2,3}),({0,2},{},{1,3}),({0,3},{},{1,2}),({1,2},{},{0,3}),...]
背景
我需要这个功能来使我的 mastermind-variation 机器人更加高效和
最重要的是代码更“漂亮”。看一下 filterCandidates
我的源代码中的函数。有不必要的
/ 重复查询,因为我只是使用排列而不是
特别订购的分区。另外,我只是对如何写感兴趣
这个功能。
我对(丑陋的)“解决方案”的想法
创建 {0,...,n_1+...+n_k}
的幂集,过滤掉 size 的子集
n_1, n_2
等并创建 n 个子集的笛卡尔积。然而
这实际上行不通,因为会有重复项,例如
({1,2},{1})...
首先选择 x = {0,...,n_1+n_2+... 中的 n_1
+n_n-1}
并将它们放入
第一组。然后选择 x 中的 n_2
,不包含 n_1 个所选元素
事先
等等。然后您会得到例如 ({0,2},{},{1,3},{4})
。的
当然,必须创建每种可能的组合,因此 ({0,4},{},{1,3},{2})
,
也是如此,等等。似乎很难实施,但也许是可能的。
研究
我猜这个
朝着我想要的方向发展,但我不知道如何将它用于我的
具体场景。
http://rosettacode.org/wiki/Combinations
Here is a function I would like to write but am unable to do so. Even if you
don't / can't give a solution I would be grateful for tips. For example,
I know that there is a correlation between the ordered represantions of the
sum of an integer and ordered set partitions but that alone does not help me in
finding the solution. So here is the description of the function I need:
The Task
Create an efficient* function
List<int[]> createOrderedPartitions(int n_1, int n_2,..., int n_k)
that returns a list of arrays of all set partions of the set
{0,...,n_1+n_2+...+n_k-1}
in number of arguments
blocks of size (in this
order) n_1,n_2,...,n_k
(e.g. n_1=2, n_2=1, n_3=1 -> ({0,1},{3},{2}),...
).
Here is a usage example:
int[] partition = createOrderedPartitions(2,1,1).get(0);
partition[0]; // -> 0
partition[1]; // -> 1
partition[2]; // -> 3
partition[3]; // -> 2
Note that the number of elements in the list is
(n_1+n_2+...+n_n choose n_1) * (n_2+n_3+...+n_n choose n_2) * ... *
(n_k choose n_k)
. Also, createOrderedPartitions(1,1,1)
would create the
permutations of {0,1,2}
and thus there would be 3! = 6
elements in the
list.
* by efficient I mean that you should not initially create a bigger list
like all partitions and then filter out results. You should do it directly.
Extra Requirements
If an argument is 0 treat it as if it was not there, e.g.
createOrderedPartitions(2,0,1,1)
should yield the same result as
createOrderedPartitions(2,1,1)
. But at least one argument must not be 0.
Of course all arguments must be >= 0.
Remarks
The provided pseudo code is quasi Java but the language of the solution
doesn't matter. In fact, as long as the solution is fairly general and can
be reproduced in other languages it is ideal.
Actually, even better would be a return type of List<Tuple<Set>>
(e.g. when
creating such a function in Python). However, then the arguments wich have
a value of 0 must not be ignored. createOrderedPartitions(2,0,2)
would then
create
[({0,1},{},{2,3}),({0,2},{},{1,3}),({0,3},{},{1,2}),({1,2},{},{0,3}),...]
Background
I need this function to make my mastermind-variation bot more efficient and
most of all the code more "beautiful". Take a look at the filterCandidates
function in my source code. There are unnecessary
/ duplicate queries because I'm simply using permutations instead of
specifically ordered partitions. Also, I'm just interested in how to write
this function.
My ideas for (ugly) "solutions"
Create the powerset of {0,...,n_1+...+n_k}
, filter out the subsets of size
n_1, n_2
etc. and create the cartesian product of the n subsets. However
this won't actually work because there would be duplicates, e.g.
({1,2},{1})...
First choose n_1
of x = {0,...,n_1+n_2+...+n_n-1}
and put them in the
first set. Then choose n_2
of x without the n_1 chosen elements
beforehand
and so on. You then get for example ({0,2},{},{1,3},{4})
. Of
course, every possible combination must be created so ({0,4},{},{1,3},{2})
,
too, and so on. Seems rather hard to implement but might be possible.
Research
I guess this
goes in the direction I want however I don't see how I can utilize it for my
specific scenario.
http://rosettacode.org/wiki/Combinations
发布评论
评论(1)
您知道,表达您的想法通常有助于找到解决方案。似乎潜意识就开始处理任务,并在找到解决方案时通知你。所以这是我在 Python 中的问题的解决方案:
输出是:
它足以将算法翻译为 Lua/Java。这基本上是我的第二个想法。
算法
正如我在问题中已经提到的,基本思想如下:
首先选择集合
s := {0,...,n_1+n_2+...+ 的
并将它们放入n_1
个元素n_n-1}结果列表中第一个元组的第一组(例如,如果所选元素为
0,1,2
,则[({0,1,2},...
)然后选择集合s_0 := s 中的
,这样的元组可能是n_2
个元素,而无需事先选择 n_1 个元素({0,2。 },{},{1,3},{4})
。当然,每种可能的组合都会被创建,因此
({0,4},{},{1,3},{2})
是另一个这样的元组,依此类推。实现
首先创建要使用的集合(
s = range(sum(args))
)。然后这个集合和参数被传递给递归辅助函数helper
。helper
执行以下操作之一: 如果处理了所有参数,则返回“某种空值”以停止递归。否则,迭代传递的长度args[0]
的集合s
的所有组合(helper 中
s
之后的第一个参数)。在每次迭代中创建不包含 c 中的元素的集合s0 := s
(c
中的元素是从s
中选择的元素),其中然后用于helper
的递归调用。那么
helper
中的参数会被一一处理。helper
可能首先以helper([0,1,2,3], 2, 1, 1)
开头,在下一次调用中它是helper ([2,3], 1, 1)
,然后是helper([3], 1)
,最后是helper([])
。当然,另一个“树路径”是helper([0,1,2,3], 2, 1, 1)
,helper([1,2], 1, 1 ) 、
helper([2], 1)
、helper([])
。创建所有这些“树路径”,从而生成所需的解决方案。You know, it often helps to phrase your thoughts in order to come up with a solution. It seems that then the subconscious just starts working on the task and notifies you when it found the solution. So here is the solution to my problem in Python:
The output is:
It is adequate for translating the algorithm to Lua/Java. It is basically the second idea I had.
The Algorithm
As I already mentionend in the question the basic idea is as follows:
First choose
n_1
elements of the sets := {0,...,n_1+n_2+...+n_n-1}
and put them in thefirst set of the first tuple in the resulting list (e.g.
[({0,1,2},...
if the chosen elements are0,1,2
). Then choosen_2
elements of the sets_0 := s without the n_1 chosen elements beforehand
and so on. One such a tuple might be({0,2},{},{1,3},{4})
. Ofcourse, every possible combination is created so
({0,4},{},{1,3},{2})
is another such tuple and so on.The Realization
At first the set to work with is created (
s = range(sum(args))
). Then this set and the arguments are passed to the recursive helper functionhelper
.helper
does one of the following things: If all the arguments are processed return "some kind of empty value" to stop the recursion. Otherwise iterate through all the combinations of the passed sets
of the lengthargs[0]
(the first argument afters
inhelper
). In each iteration create the sets0 := s without the elements in c
(the elements inc
are the chosen elements froms
), which is then used for the recursive call ofhelper
.So what happens with the arguments in
helper
is that they are processed one by one.helper
may first start withhelper([0,1,2,3], 2, 1, 1)
and in the next invocation it is for examplehelper([2,3], 1, 1)
and thenhelper([3], 1)
and lastlyhelper([])
. Of course another "tree-path" would behelper([0,1,2,3], 2, 1, 1)
,helper([1,2], 1, 1)
,helper([2], 1)
,helper([])
. All these "tree-paths" are created and thus the required solution is generated.