[kdb + / q]:将邻接矩阵转换为邻接列表

时间:2016-04-12 10:54:01

标签: kdb q-lang k

给定(矩形)邻接矩阵m,如何用q语言构造邻接表?

QIdioms wiki我已找到k语言的解决方案,当q控制台通过k)命令运行时,我发现'vs错误:

m:(1 0 1;1 0 1)
k) (^m)_vs &,/m
'vs

结果应该是:

0 0 1 1
0 2 0 2

这是我能够在q中复制的内容:

k) &,/m
0 2 3 5
q) where raze m
0 2 3 5
{p> k ^ a.k.a。shape动词在q中丢失,所以我刚刚做了:

k) (^m)
000b
000b
q) 2 3#0b
000b
000b

现在,因为:

q) parse "vs"
k) {x\:y}

我试过两次都失败了:

q) (2 3#0b) _vs where raze m
'
q) (2 3#0b) _\: where raze m
'type

请注意,QIdioms wiki对于反问题有q solution:从adj.list到adj.matrix。

1 个答案:

答案 0 :(得分:5)

你有错误,因为原始的Q成语是用k2写的 - 现代kdb +版本不支持的旧版本的k。当前版本的k是k4,并且它与k2不向后兼容。

例如,X _vs Y其中X和Y是整数原子或旧k2中的列表表现得像X vs Y 表现为kdb +从3.4t开始2015.12.13:{ {3}}:

  

从3.4t开始2015.12.13:对于整数类型,计算基数X中Y的基本表示。

另一个例子。确实,k2中的^是一个形状算子,但它不再存在。在k2中,^m会从您的示例中返回2 3矩阵m,而当前实现的行为类似于q' s not null理解。

现在,回到原来的问题,"如何用q语言构建邻接列表"。一种方法是:

q)lm:{flip raze(til count x),''where each x}

k)lm:{+,/(!#x),''&:'x}

更新:以下是它的工作原理。如果我们要使用任何" verbose"来构建一个邻接列表。语言我们会做这样的事情:

for i = 0 to <number of rows> - 1            <---- (1)
    for j = 0 to <number of columns> - 1     <---- (2)
        if M[i;j] <> 0                       <---- (3)
            print i, j

在q (1)这样的数组语言中,可以&#34;翻译&#34;进入til count M因为count将返回顶级元素的数量,即行数。 (2)(3)组合在一起可以由where each M表示。实际上,对于每一行,我们返回非零元素的位置。给定一个原始矩阵m,我们将得到:

til count m -> 0 1
where each m -> (0 2; 0 2)

我们需要做的就是连接行索引和列索引。我们无法仅使用,',因为它会将0与第一个0 21与第二个0 2结合,从而导致(0 0 2; 1 0 2) }。我们需要更深层次,将左边的每个元素与右边的嵌套列表(0 2; 0 2)的每个元素的每个元素连接起来,因此,''中有双撇号。

我希望现在有道理。

就我个人而言,我不会使用flip(或k中的+),我无法以这种形式阅读邻接矩阵:

0 0 1 1
0 2 0 2

我认为这更具可读性:

0 0
0 2
1 0
1 2

但它当然取决于你。