1

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

QIdioms wiki中,我找到了使用命令通过控制台k运行时出现错误的语言解决方案:qk)'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

k^akashape动词丢失了,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 wikiq逆问题的解决方案:从 adj.list 到 adj.matrix。

4

1 回答 1

5

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

例如,从 3.4t 2015.12.13 开始X _vs Y,X 和 Y 是整数原子或旧 k2 中的列表在 kdb+ 中X vs Y 的行为: http ://code.kx.com/q/ref/lists/#vs :

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

另一个例子。在 k2 中确实^有一个形状运算符,但它不再是了。In k2^m会从您的示例中返回2 3一个矩阵,而据我所知m,当前实现的行为类似于q's 。not null

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

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

或者

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

更新:这是它的工作原理。如果我们要使用任何“详细”语言构建邻接列表,我们将执行以下操作:

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)可以“翻译”成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

但这当然取决于你。

于 2016-04-12T13:30:47.707 回答