生成一个独特排列的列表

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)

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


1
如果您正在寻找Pearson的corrmatrix函数,您可以在q-math中检查.math.st.corrm。 - Anton Dovzhenko
3个回答

2

你可能会发现另一种解决方案很有用:

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累加器创建符号列表的列表,每个列表都会去除第一个元素:

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

由于扫描操作在最后也会返回一个空列表,因此需要额外添加-1_。然后使用每个元素右连接到这个结果上:

{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

这种解决方案根本不需要扫描,从性能上来看与扫描解决方案非常相似!


1

我会尝试以下代码

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

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

虽然不是最有效的方法,但非常简洁。


0
如果我理解了问题(如果我漏掉了什么,请原谅)。下面应该会给你想要的东西。
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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接