Permutation 生成唯一排列的列表

Permutation 生成唯一排列的列表,permutation,kdb,Permutation,Kdb,假设我有一个包含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) 但是我

假设我有一个包含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)
但是我不知道如何生成非对角元素。

我会尝试下面的代码

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

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

如果我理解了这个问题(如果我遗漏了什么,请道歉),那么这不是最有效的方法。下面应该给你你想要的

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

您可能会发现另一个有用的解决方案:

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
这将使用创建符号列表,每个符号都会删除第一个元素:

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

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

如果你在找皮尔逊的corrmatrix函数,你可以查一下