使用Erlang查找N组子集之间的所有可能对

时间:2012-02-02 17:29:06

标签: erlang set combinations data-partitioning

我有一套S。它包含N个子集(其中包含一些不同长度的子集):

1. [[a,b],[c,d],[*]]
2. [[c],[d],[e,f],[*]]
3. [[d,e],[f],[f,*]]
N. ...

我还有L集合中包含的'{1}}个'唯一'元素:

S

我需要找到每个子集中每个子子集之间的所有可能组合,这样每个结果组合中只有一个元素来自列表a, b, c, d, e, f, * ,但是元素L的任意数量出现(这是一个通配符元素)。

因此,使用上述集合[*]所需函数的结果应为(不是100%准确):

S

所以,基本上我需要一个执行以下操作的算法:

  1. 从子集- [a,b],[c],[d,e],[f]; - [a,b],[c],[*],[d,e],[f]; - [a,b],[c],[d,e],[f],[*]; - [a,b],[c],[d,e],[f,*],[*]; 中获取子子集,
  2. 从子集1添加一个子子集,维护到目前为止获取的“唯一”元素列表(如果子子集包含{{1},则跳过对'唯一'列表的检查} element);
  3. 重复2,直到达到*
  4. 换句话说,我需要生成所有可能的“链”(如果是2则为对,如果N则为三倍),但每个“链”应该包含来自列出N == 2,但通配符元素N==3除外,它可以在每个生成的链中多次出现。

    我知道如何使用L执行此操作(这是一个简单的对生成),但我不知道如何增强算法以使用*的任意值。

    也许Stirling numbers of the second kind可以在这里提供帮助,但我不知道如何应用它们来获得理想的结果。

    注意:此处使用的数据结构类型对我来说并不重要。

    注意:此问题来自我之前的similar问题。

1 个答案:

答案 0 :(得分:0)

这些是一些指针(不是完整的代码)可能会带你走向正确的方向:

  1. 我不认为你需要一些高级数据结构(使用erlang list comprehensions)。您还必须探索erlang setslists模块。由于您正在处理集合和子集列表,因此它们似乎是理想的选择。
  2. 以下是列表推导的内容将如何轻松解决:[{X,Y} || X <- [[c],[d],[e,f]], Y <- [[a,b],[c,d]]].这里我只是生成一个{X,Y} 2元组列表但是对于您的用例,您将需要放置实际逻辑这里(包括你的明星案例)
  3. 进一步注意,使用列表推导,您可以使用一个生成器的输出作为后续生成器的输入,例如[{X,Y} || X1 <- [[c],[d],[e,f]], X <- X1, Y1 <- [[a,b],[c,d]], Y <- Y1].
  4. 同样,要从L = ["a", "b", "a"].内容列表中删除重复项,您可以随时执行sets:to_list(sets:from_list(L)).
  5. 使用上述工具,您可以轻松生成所有可能的链,并在生成这些链时强制执行您的逻辑。