Language agnostic (有序)在固定大小的块中设置分区

Language agnostic (有序)在固定大小的块中设置分区,language-agnostic,math,recursion,combinatorics,Language Agnostic,Math,Recursion,Combinatorics,这是一个我想写的函数,但我无法写。即使你 不要/不能给出解决方案我将非常感谢您的提示。例如 我知道,有一个有序的代表之间的相关性 整数和有序集分区之和,但仅此一点并不能帮助我 找到解决办法。下面是我需要的函数的描述: 任务 创建一个高效的*函数 List<int[]> createOrderedPartitions(int n_1, int n_2,..., int n_k) 请注意,列表中的元素数为 (n_1+n_2+…+n_n选择n_1)*(n_2+n_3+…+n_n选择n_

这是一个我想写的函数,但我无法写。即使你 不要/不能给出解决方案我将非常感谢您的提示。例如 我知道,有一个有序的代表之间的相关性 整数和有序集分区之和,但仅此一点并不能帮助我 找到解决办法。下面是我需要的函数的描述:


任务 创建一个高效的*函数

List<int[]> createOrderedPartitions(int n_1, int n_2,..., int n_k)
请注意,列表中的元素数为
(n_1+n_2+…+n_n选择n_1)*(n_2+n_3+…+n_n选择n_2)**
(选择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)
创造


背景 我需要这个功能,使我的智囊团变化机器人更高效,更安全 最重要的是,代码更“漂亮”。查看
filterCandidates
在……中起作用。没有必要 /重复查询,因为我只是使用排列而不是 特别有序的分区。另外,我只是对如何写作感兴趣 这个功能


我对(丑陋的)“解决方案”的想法 创建
{0,…,n_1+…+n_k}
的powerset,过滤掉大小的子集
n_1、n_2等,并创建n个子集的笛卡尔积。然而
这实际上不起作用,因为会有重复的,例如。
({1,2},{1})

首先选择
x={0,…,n_1+n_2+…+n_n-1}
n_1
,并将它们放入 第一盘。然后选择
x的
n_2
,而不选择n_1元素 事先
等等。然后您可以得到例如
({0,2},{},{1,3},{4})
。属于 当然,必须创建每个可能的组合,以便
({0,4},{},{1,3},{2})
, 还有,等等。似乎很难实现,但可能实现


研究 我想 朝着我想要的方向发展,但我不知道如何利用它来实现我的目标 具体情况


你知道,表达你的想法通常有助于找到解决方案。似乎潜意识只是开始处理任务,并在找到解决方案时通知你。下面是我在Python中遇到的问题的解决方案:

from itertools import combinations

def partitions(*args):
    def helper(s, *args):
        if not args: return [[]]
        res = []
        for c in combinations(s, args[0]):
            s0 = [x for x in s if x not in c]
            for r in helper(s0, *args[1:]):
                res.append([c] + r)
        return res
    s = range(sum(args))
    return helper(s, *args)

print partitions(2, 0, 2)
输出为:

[[(0, 1), (), (2, 3)], [(0, 2), (), (1, 3)], [(0, 3), (), (1, 2)], [(1, 2), (), (0, 3)], [(1, 3), (), (0, 2)], [(2, 3), (), (0, 1)]]
它足以将算法转换为Lua/Java。这基本上是我的第二个想法


算法 正如我在问题末尾已经提到的,基本思想如下:

首先选择集合
n_1
元素
s:={0,…,n_1+n_2+…+n_n-1}
并将它们放入 结果列表中第一个元组的第一个集合(例如,
[({0,1,2},
,如果选择的元素是
0,1,2
)。然后选择集合
s\u 0:=s的
n\u 2
,而不事先选择n\u 1个元素
,等等。这样的元组可能是
({0,2},{},{1,3},{4})
当然,每一个可能的组合都被创建,所以
({0,4},{},{1,3},{2})
是另一个这样的元组,依此类推

实现 首先创建要使用的集合(
s=range(sum(args))
),然后将该集合和参数传递给递归帮助函数
helper

helper
执行以下操作之一:如果处理了所有参数,则返回“某种类型的空值”以停止递归。否则,迭代长度
args[0]
的传递集
s
的所有组合(在
helper
s
之后的第一个参数)。在每次迭代中,创建一个集合
s0:=s,但不包含c
中的元素(c
中的元素是从
s
中选择的元素),然后用于递归调用
帮助程序


因此,
helper
中的参数会一个接一个地处理。
helper
可能首先从
helper([0,1,2,3],2,1,1)
开始,然后在下一次调用中是
helper([2,3],1,1)
最后是
helper([])
。当然,另一个“树路径”是
助手([0,1,2,3],2,1,1)
助手([1,2],1,1)
助手([2],1)
助手([])
。所有这些“树路径”创建,从而生成所需的解决方案。

这可能更像是math.stackexchange.com的一个问题,因为从根本上来说,这是一个算法问题吗?或者甚至可能是cstheory.stackexchange.com?结果证明我根本不需要这个函数,因为在mastermind中有一种简单得多的过滤可能性的方法。尽管如此,它写这个算法很有趣。
from itertools import combinations

def partitions(*args):
    def helper(s, *args):
        if not args: return [[]]
        res = []
        for c in combinations(s, args[0]):
            s0 = [x for x in s if x not in c]
            for r in helper(s0, *args[1:]):
                res.append([c] + r)
        return res
    s = range(sum(args))
    return helper(s, *args)

print partitions(2, 0, 2)
[[(0, 1), (), (2, 3)], [(0, 2), (), (1, 3)], [(0, 3), (), (1, 2)], [(1, 2), (), (0, 3)], [(1, 3), (), (0, 2)], [(2, 3), (), (0, 1)]]