我有一个完整的无向图,其中节点表示平面上点的点,边是点之间的近似欧氏距离。我想把这个图“嵌入”二维空间。也就是说,我想将每个顶点转换为(x,y)位置元组,这样对于任意两个顶点v和w,边(v,w)的权重接近dist(v,w)。
例如,如果我有带有节点A,B,C和D的图形以及带有权重(A,B)的边:20; (A,C):22; (A,D):26; (B,C):30; (B,D):20,(C,D):19,然后你可以分配点A:(0,0); B:(10,0); C:(0,10); D:(10,10)。显然这是不完美的,但这是一个合理的近似值。
我不关心获得最佳解决方案,我只想在合理的时间内找到合理的解决方案。
(如果你想要解决这个问题的动机。我有一个物理系统,我对所有点对的距离进行噪声测量。距离测量是有噪声的,但往往在真实值的两倍之内我已完成所有这些测量,现在有一个包含数千个节点和数百万个边的图,并希望将这些点放在一个平面上。)
答案 0 :(得分:3)
您可以根据需要调整force-based图形绘制算法。
此算法尝试通过将G(V,E)
中的每个顶点视为笛卡尔点并将V
中的每个边视为线性弹簧来为无向图E
找到良好的布局。此外,在全局顶点之间计算成对排斥力(即库仑定律) - 这可以防止笛卡尔空间中的顶点聚类在G(V,E)
中不相邻。
在你的情况下,你可以设置弹簧的平衡长度等于你的边缘权重 - 这应该给出一个布局,其中成对的欧几里德顶点距离接近你的边缘权重。
该算法基于每个顶点处的力的总和以伪时间步进方式更新初始分布(可能是随机的)。当达到近似稳态时,算法终止。简化的伪代码:
while(not converged)
for i = vertices in V
F(i) = sum of spring + repulsive forces on ith vertex
endfor
Update vertex positions based on force vector F
if (vertex positions not changing much)
converged = true
endif
endwhile
可以应用许多优化来降低算法的复杂性。例如,空间索引(例如四叉树)可用于允许有效计算“近似”顶点之间的近似排斥力,而不是慢速全局计算。也可以使用多级图形聚集技术来提高收敛性和最优性。
最后,请注意,有几个很好的图形绘制库可以实现此算法的优化版本 - 例如,您可能需要查看Graphviz。
答案 1 :(得分:1)
首先,我想我会采用启发式搜索方式。
你实际上想要找到一组最小化函数的点p1,p2,...,p_n:
f(X) = Sum (|dist(p_i,p_j) - weight(n_i,n_j)|) [for each i,j ]
问题可以通过一些算法启发式解决,包括Hill Climbing和Genetic Algorithms。
我个人喜欢Hill Climbing,方法如下:
best <- [(0,0),(0,0),...,(0,0)]
while there is still time:
S <- random initialized vector of points
flag <- true
while (flag):
flag <- false
candidates <- next(S) (*)
S <- X in candidates such that f(X) <= f(Y) for each X in candidates (**)
if f(S) was improved:
flag <- true
if f(S) <= f(best):
best <- S
return best
(*)
next()生成候选列表。它可以利用关于函数梯度的信息(并且基本上衰减成类似于gradient descent的东西),或者采样一些随机的“方向”并将它们作为候选者(所有这些都在多维向量中,每个点都有是一个维度)。
(**)
在这里,您基本上选择了“最佳”候选者,并将其存储在S中,因此您将在下一次迭代中继续使用它。
请注意,该算法为any-time,因此您需要花费更多时间才能获得更好的效果。这种行为是通过起始点的随机初始化来实现的 - 这可能会改变结束结果,也可以通过随机选择候选点来实现。