以(最多 2)个连续的 1 块为行的二进制矩阵,计算其平方的迹线

Posted

技术标签:

【中文标题】以(最多 2)个连续的 1 块为行的二进制矩阵,计算其平方的迹线【英文标题】:Binary matrix with (max 2) contiguous blocks of 1's as rows, calculate trace of its square 【发布时间】:2020-01-18 10:55:27 【问题描述】:

A 是一个nxn 二进制矩阵,其行的形式为0^k 1^l 0^m1^k 0^l 1^m。此外,A 沿对角线有零。维度 n 最大可达10^5。该矩阵将通过给出1 的块开始和结束的索引来给出。

换句话说,这些行是由0 包围的一系列1 或由1 包围的一系列0。一行可以全为零,但不能全为 1(对角线上的零)。

一个例子A:

[0, 0, 0, 0, 1, 1, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 1, 1, 0, 0]
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 0, 0, 0, 0, 1, 1, 1]
[1, 0, 0, 0, 0, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 0, 0, 0, 0, 1]
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 1, 1, 1, 0, 0, 0, 0, 1, 1]
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0]
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0]

如何高效计算A^2的踪迹(在O(n^2)时间下)?

这相当于找到A的特征多项式的(n-2)'nd系数,记为g_2(A),因为

tr(A^2) = (tr A)^2 - 2g_2(A) = -2g_2(A)

一点点这个问题出在哪里:

我们得到一个数字 [1..n] 的排列 p,并且对数量感兴趣

r(p) = #k | p^-1[k+1] < p^-1[k]

这里p^-1[k]表示kp中的索引。我们想计算两个将 r 减少 2 的元素的所有交换。这可以通过考虑每个索引 k 来完成,其中 p[k] 移动是有利可图的。它取决于p[k]-1p[k]+1 的位置(仅在边缘情况下位于其他位置),这就是行的形式的来源。但另一个元素的移动也应该是有利可图的,因此问题变成矩阵A中有多少元素同时A[i][j]A[j][i]等于1,我们被引导计算@987654351的踪迹@。此外,在最初的问题中,我们希望从中减去相邻数字 (|p[i]-p[j]|==1) 的对,因为这不会将 r 减少 2,而只会减少 1。但这可以在线性时间内完成,并且为简单起见是'不考虑这个问题。虽然,可能是原始问题对矩阵A 施加了一些进一步的限制,这可能有助于计算(?)

【问题讨论】:

这似乎应该是可能的,但并不容易。 A^2 的条目是 A 的行和列的每个标量积; A 的行遵循简单的结构,但列不遵循。我们需要一种方法来有效地计算给定范围内有多少行在给定列中有 1,因此从这个意义上说,这更像是一个数据结构问题而不是算法问题。 另一个想法是分解A = (L + M + R),其中L是行首只有1的矩阵,M只有行中间的1,R行尾只有 1。 A^2 = (L + M + R)(L + M + R) 的扩展需要 9 次乘法而不是 1 次,但每次乘法都采用更简单的形式,因此可能更容易找到次二次时间算法。 【参考方案1】:

这可以通过sweep-line algorithm 使用Fenwick tree 在 O(n log n) 时间内完成。

该算法按顺序计算产品对角线的条目。它维护一个包含当前列的 Fenwick 树。 Fenwick 树可以在 O(log n) 时间内更新一个条目,并在 O(log n) 时间报告一个子数组和。对于位置 i × j…j'-1 中的每一部分行,我们创建两个事件,(j, i, +1) 和 (j', i, -1)。按事件的第一个条目(列,也就是时间)对事件进行排序和分组。事件 (j, i, Δ) 表示在时间 j 将条目 i 增加 Δ。要计算对角元素索引 k,首先应用时间为 k 的所有事件,然后报告相应行中所有事件的间隔,并将它们相加。

【讨论】:

谢谢,这太棒了!不幸的是,我没有足够的声望给 +1。原始问题的解决时间从 19 分钟缩短到 6 秒:D

以上是关于以(最多 2)个连续的 1 块为行的二进制矩阵,计算其平方的迹线的主要内容,如果未能解决你的问题,请参考以下文章

大家都是怎么算矩阵行最简行的

SqlServer基本操作

将列转置为行 SQL Server

在 Django 模板中将卡片组划分为行的最佳方法 - Django

matlab怎样求矩阵每一行的平方和?

如何在骆驼中将文件拆分为行但以不同方式处理第一行