【问题标题】:Generate a list of unique permutations生成唯一排列列表
【发布时间】:2020-03-02 03:21:06
【问题描述】:

假设我有一个包含 3 个符号的列表:

l:`s1`s2`s3

生成以下 n*(n+1)/2 排列列表的 q 方式是什么?

(`s1;`s1),(`s1;`s2),(`s1;`s3),(`s2;`s2),(`s2;`s3),(`s3;`s3)

这可以看作是在相关矩阵的上下文中,我想要相关矩阵的所有上三角部分,包括对角线。

当然我的初始列表的大小会超过3,所以我想要一个通用函数来执行这个操作。

我知道如何生成对角线元素:

q) {(x,y)}'[l;l]

(`s1`s1;`s2`s2;`s3`s3)

但我不知道如何生成非对角元素。

【问题讨论】:

  • 如果您正在寻找 Pearson 的 corrmatrix 函数,您可以查看 q-math 中的 .math.st.corrm

标签: permutation kdb


【解决方案1】:

另一个您可能会觉得有用的解决方案:

q)l
`s1`s2`s3
q){raze x,/:'-1_{1_x}\[x]}l
s1 s1
s1 s2
s1 s3
s2 s2
s2 s3
s3 s3

这使用scan accumulator 创建一个符号列表列表,每个符号列表删除第一个元素:

q)-1_{1_x}\[l]
`s1`s2`s3
`s2`s3
,`s3

需要额外的-1_,因为扫描最后也会返回一个空列表。然后使用 each-right 和 each 将列表中的每个元素连接到此结果中:

{x,/:'-1_{1_x}\[x]}l
(`s1`s1;`s1`s2;`s1`s3)
(`s2`s2;`s2`s3)
,`s3`s3

最后使用 raze 来获得不同的排列。

编辑:也可以使用

q){raze x,/:'til[count x]_\:x}l
s1 s1
s1 s2
s1 s3
s2 s2
s2 s3
s3 s3

根本不需要扫描,在性能方面与扫描解决方案非常相似!

【讨论】:

    【解决方案2】:

    我会尝试下面的代码

    {distinct asc each x cross x}`s1`s2`s3
    

    • cross 生成所有 (s_i, s_j) 对
    • asc each 按索引对每一对进行排序,因此 `s3`s1 变为 `s1`s3
    • distinct 删除重复项

    不是最有效的方法。

    【讨论】:

      【解决方案3】:

      如果我理解了这个问题(如果我遗漏了什么,请道歉)。下面应该给你你正在寻找的东西

      q)test:`s1`s2`s3`s4`s5
      q)(til cnt) _' raze (-1+cnt:count test)cut test,'/:test
      (`s1`s1;`s2`s1;`s3`s1;`s4`s1;`s5`s1)
      (`s2`s2;`s3`s2;`s4`s2;`s5`s2)
      (`s3`s3;`s4`s3;`s5`s3)
      (`s4`s4;`s5`s4)
      ,`s5`s5
      

      【讨论】:

        猜你喜欢
        • 2019-11-27
        • 2012-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-22
        相关资源
        最近更新 更多