给定一个大的稀疏矩阵(比如说10k +乘以1M +),我需要找到形成密集矩阵(所有非零元素)的行和列的子集,不一定是连续的。我希望这个子矩阵在一些宽高比约束中尽可能大(不是最大的和,但是最大的元素数)。
这个问题是否有任何已知的确切或aproxamate解决方案?
对谷歌的快速扫描似乎给出了很多接近但不完全的结果。 我应该寻找哪些条款?
编辑:只是为了澄清;子矩阵不必是连续的。实际上,行和列顺序完全是任意的,因此邻接完全无关紧要。
基于Chad Okere的想法的想法
答案 0 :(得分:2)
我认为你想要这样的东西。你有一个像
这样的矩阵1100101
1110101
0100101
你想要第1,2,5,7列和第1行和第2行,对吗?该子矩阵将具有8个元素的4x2。或者你可以使用第1,2,7列,第1,2,3行,这将是一个3x3矩阵。
如果你想要一个'近似'方法,你可以从一个非零元素开始,然后继续寻找另一个非零元素并将其添加到你的行和列列表中。在某些时候,你会遇到一个非零元素,如果它的行和列被添加到你的集合中,你的集合将不再完全非零。
因此对于上面的矩阵,如果你添加了1,1和2,2你的集合中会有1,2行和1,2列。如果您尝试添加3,7,则会导致问题,因为1,3为零。所以你无法添加它。你可以添加2,5和2,7。创建4x2子矩阵。
您基本上会迭代,直到找不到要添加的新行和列。这将使你太局部最小化。您可以存储结果并使用另一个起始点(可能是一个不适合您当前解决方案的起点)重新开始。
然后在一段时间后再找不到时再停下来。
显然,这需要很长时间,但我不知道你是否能够更快地完成它。答案 1 :(得分:1)
EDIT。这跟下面的问题不一样。我的不好......
但根据下面的最后一条评论,它可能等同于以下内容:
那么你要找的水平区域是适合这两对点的矩形吗?
这个确切的问题在Jon Bentley的一本名为“Programming Pearls”的书的宝石中讨论过,而且我记得,虽然在一个维度上有一个解决方案,但对于2-d或更高的维度没有简单的答案维度变体......
1 = D问题实际上是找到一组数字中连续子集的最大总和:
遍历元素,跟踪特定前一个元素的运行总计,以及到目前为止看到的最大小计(以及生成它的开始和结束元素)...在每个元素处,如果maxrunning小计是大于目前为止看到的最大总数,到目前为止看到的最大值和重要值被重置...如果最大运行总量低于零,则将start元素重置为当前元素,并将运行总计重置为零...
2-D问题来自于尝试生成可视图像处理算法,该算法试图在表示2色图像中的像素的亮度值流中找到“内部最亮”的矩形区域。图片。即,找到具有最高亮度值总和的所包含的2-D子矩阵,其中“亮度”通过像素的亮度值与整个图像的总体平均亮度之间的差异来测量(因此许多元素具有负值)
编辑:为了查找一维解决方案,我挖掘了本书第二版的副本,其中,Jon Bentley说:“这个版本打印时,二维版本仍未解决...... “这是在1999年。
答案 2 :(得分:1)
这是Netflix problem吗?
MATLAB或其他一些稀疏矩阵库可能有办法处理它。
你打算自己写吗?
也许每行的1D方法对您有所帮助。算法可能如下所示:
此时我开始模糊(对不起,不是算法设计师)。我尝试循环遍历每一行,排列起点的索引,寻找我可能的最大非零列索引。
您不指定密集矩阵是否必须是正方形。我不会假设。
我不知道这是多么有效或者它的Big-O行为是什么。但这是一种蛮力的方法。
答案 3 :(得分:1)
我知道你不再在这方面工作,但我认为将来可能会有人和我有同样的问题。
所以,在意识到这是一个NP难题(通过缩减为MAX-CLIQUE)之后,我决定提出一种迄今为止对我有用的启发式方法:
给定 N x M 二进制/布尔矩阵,找到一个大的密集子矩阵:
第一部分:生成合理的候选子矩阵
最初,每个 v_i 向量都是单个群集。上面的步骤3(聚类)给出了矢量应该组合成子矩阵的顺序。因此,分层聚类树中的每个内部节点都是候选子矩阵。
第二部分:对候选子矩阵进行评分和排名
我还考虑了需要从初始完整矩阵中保留的最小行数,并且在选择max D的子矩阵之前,我会丢弃任何不符合此条件的候选子矩阵强>价值。