【问题标题】:Is there a name for this set/array operation?这个集合/数组操作有名字吗?
【发布时间】:2013-04-08 18:55:04
【问题描述】:

给定输入数组

[a,b,c,d,e]

还有一个“加入”功能(a,b) => (a+b)

我的代码返回以下数组数组,其中包含通过将连接函数应用于各种元素对而获得的每个可能的变化,同时保持顺序:

[
  [a,b,c,d,e],
  [a,b+c,d,e],
  [a,b+c+d,e],
  [a,b,c+d,e],
  [a+b,c,d,e],
  [a+b,c+d,e],
  [a+b+c,d,e],
  [a+b+c+d,e],
  [a,b,c,d+e],
  [a,b+c,d+e],
  [a,b+c+d+e],
  [a,b,c+d+e],
  [a+b,c,d+e],
  [a+b,c+d+e],
  [a+b+c,d+e],
  [a+b+c+d+e],
]

在视觉上,我想要做的是:

代码有效,但我不知道该叫什么 - 如果存在这样的名称,我想使用其他熟悉此操作的开发人员会理解的名称。它不是一个幂集,但它是类似的……这个特定的集合/数组操作有名字吗?

编辑:好的。它们不是排列;排列都是不同顺序的 5 元素数组[[a,b,c,d,e], [e,d,c,b,a], [a,d,b,c,e], ...]

它们不是分区,因为任何子集只能包含输入的相邻元素。 - 换句话说,分区将允许这样做:

(这可能源于没有有序集合概念的纯集合论。)

它们不是组合,因为输出的每个元素只使用输入集的每个成员一次。

我认为myArray.OrderedPartitions((a,b) => (a+b)) 可能是一个合适的简洁和解释性。

【问题讨论】:

  • 为什么[a+b+c+d+e] 不见了?
  • @Landei 我的错误 :) 编辑了问题以包含缺失的排列。
  • 这与部分总和或分段总和有关,但是,这不是准确的描述。
  • 它们绝对是不是任何种类的排列!根据定义,排列是对同一组项目的重新排序。但是,这里没有两个具有相同项目的列表。
  • 我称之为Order-dependent Integer Partition。它基本上等同于您可以将数字写为整数和的所有方式:1+1+1+1+1 1+1+1+2 1+1+2+1 1+1+3 1+2+1+1 1+2+2 ...

标签: arrays algorithm math powerset set-theory


【解决方案1】:

正如 mbeckish 在评论中所说,这些集合(一旦原始集合上的顺序固定)同构于顺序相关的整数分区,显然通常称为compositions。每组恰好有 2n-1 个组合。对于每个 1knn 元素的 (n-1) choose (k-1) 组合到 k 集合中,保持您开始使用的集合的顺序。为了可视化它,请考虑按顺序排列的集合中的元素以及按该顺序相邻的元素之间的空间;将您的示例视为A|B|C|D|E。您会注意到恰好有n-1 可能的边界。要创建 k-composition,您只需从那些可能的边界中选择k-1,这可能是也可能不是您生成集合的方式。将 k1n 的所有 (n-1) choose (k-1) 相加,然后得到 2n-1 作为可能组合的数量。

【讨论】:

  • 很好的解释。值得补充的是,总和等于2^(n-1)
  • 它们确实看起来是组合物。谢谢你:)
【解决方案2】:

编辑后 - 这些都是数组的分区(它们的计数为 2^(n-1),因为您可以用连接符 (+) 替换任何分隔符(冒号))。

注意 - 这些是数组分区,而不是设置分区。

【讨论】:

    【解决方案3】:

    myArray.possibleChainings() 或 myArray.possibleLinkings() 怎么样?

    这个想法是看起来你至少在链接或链接 两个元素在一起。我发现它也很直观,因为你不能 将不相邻的元素链接或链接在一起。

    【讨论】:

      【解决方案4】:

      它是一个指向远离根节点的有向树:

      请务必注意,您并没有声明您的集合的顺序很重要,只是每个集合都保持该顺序。通过“加入”生成“分区”的 python 代码:

      A = map(list, list('abcde'))
      
      def join(A):
          B = []
          for x1,x2 in zip(A,A[1:]):
              B.append((x1,x2,sorted(list(set(x1+x2)))))
          return B
      def label(x):
          return '+'.join(x)
      
      # Draw the graph with networkx
      import networkx as nx
      G = nx.DiGraph()
      
      while len(A)>1:
          B = join(A)
          for x1,x2,pair in B:
              print label(x1), label(pair)
              G.add_edge(label(x1),label(pair))
              G.add_edge(label(x2),label(pair))
          A = [x[2] for x in B]
      
      nx.write_dot(G,'test.dot')
      
      # Render the graph to an image
      import os
      os.system('dot -Tpng test.dot > test.png')
      

      【讨论】:

        【解决方案5】:

        [海报的主要编辑使我的答案过时了,这是关于发布的原始问题:] 整数序列的在线百科全书将这些简单地称为“区间子集”。 (http://oeis.org/A000124) 我会坚持这个,它很有描述性。

        【讨论】:

        • 我不会说它是对它正在做什么的描述(如果我看到这个名字,我不知道我期望这个函数做什么 - 我可以看到如何这个名字经过了很多次之后才合适)。
        猜你喜欢
        • 1970-01-01
        • 2013-06-03
        • 2022-01-26
        • 1970-01-01
        • 1970-01-01
        • 2016-08-27
        • 2019-08-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多