这是我想到的一种方法:
- “稀疏化”矩阵,以便只有“足够接近”的邻居在矩阵中具有非零值。
- 使用Cuthill-McKee algorithm 压缩稀疏矩阵的带宽。
- 使用第 2 步的结果对原始矩阵进行对称重新排序。
示例
我将使用 Octave(我所做的一切也应该在 Matlab 中工作),因为它内置了 Reverse Cuthill-McKee (RCM) 实现。
首先,我们需要生成一个距离矩阵。此函数创建一组随机点及其距离矩阵:
function [x, y, A] = make_rand_dist_matrix(n)
x = rand(n, 1);
y = rand(n, 1);
A = sqrt((repmat(x, 1, n) - repmat(x', n, 1)).^2 +
(repmat(y, 1, n) - repmat(y', n, 1)).^2);
end
让我们用它来生成和可视化一个 100 分的例子。
[x, y, A] = make_rand_dist_matrix(100);
surf(A);
从上方查看曲面图会得到下图(当然,您的会有所不同)。
暖色代表比冷色更远的距离。矩阵中的行(或列,如果您愿意)i 包含点 i 和所有点之间的距离。点i 和点j 之间的距离在条目A(i, j) 中。我们的目标是对矩阵进行重新排序,使与点i 对应的行靠近与距离i 不远的点对应的行。
稀疏化A 的一种简单方法是使所有条目大于某个阈值零,这就是下面所做的,尽管更复杂的方法可能会更有效。
B = A < 0.2; % sparsify A -- only values less than 0.2 are nonzeros in B
p = symrcm(B); % compute reordering by Reverse Cuthill-McKee
surf(A(p, p)); % visualize reordered distance matrix
现在,矩阵的排序方式使矩阵中的附近点更靠近。当然,这个结果并不是最优的。稀疏矩阵带宽压缩是使用启发式计算的,而 RCM 是一种非常简单的方法。正如我上面提到的,用于生成稀疏矩阵的更复杂的方法可能会产生更好的结果,并且不同的算法也可能会针对该问题产生更好的结果。
只是为了好玩
查看发生了什么的另一种方法是绘制点并连接一对点,如果它们在矩阵中的对应行是相邻的。您的目标是让线连接彼此靠近的点对。为了获得更戏剧化的效果,我们使用了比上面更多的点。
[x, y, A] = make_rand_dist_matrix(2000);
plot(x, y); % plot the points in their initial, random order
显然,连接无处不在,并且发生在各种距离上。
B = A < 0.2; % sparsify A
p = symrcm(B);
plot(x(p), y(p)) % plot the reordered points
重新排序后,连接的距离往往更小且更有序。