从邻接矩阵中找出前n个加权边

时间:2015-05-25 13:18:05

标签: java graph adjacency-matrix

我对图形和邻接矩阵感到困惑。我有一个包含大量节点和边缘的图形(例如5000个顶点和6000个边缘)。我必须给每个节点给予分数(使用jaccard算法)那是不相邻的。我使用gephi java doc.I用jaccard对每个节点进行评分。如何在最快的时间内从邻接矩阵中找到前n个边缘得分?

修改

  ArrayList<ArrayList<Double>> score = new ArrayList<ArrayList<Double>>();
    Node[] nodes = graph.getNodes().toArray();
    Jaccard jaccard= new Jaccard();

    for(Node f:nodes){
        for(Node g:nodes){
            if(!graph.isAdjacent(g, f) && g!=f ){
                score.get(f.getId()).set(g.getId(), jaccard.getScore(f, g));
            }else {
                score.get(f.getId()).set(g.getId(), 0.0);
            }
        }
    }

2 个答案:

答案 0 :(得分:0)

您需要 PriorityQueue

算法:将PQ的容量设置为 n 。继续添加对象(根据您定义的 Comparator 添加边缘,也应该告诉节点)(即根据您提供的分数比较边缘)。盲目插入边缘,直到插入 n 。当您点击容量 n 时,在插入之前进行比较( peek()),您会发现可比对象总是在PQ之上,因此比较的成本是一个很好的O(1)。如果新对象的得分较高,请执行连续的 poll() add()操作;否则继续直到比较所有边缘。

完成后,您的PQ将具有顶部的 n 加权边。在此处了解PQs

答案 1 :(得分:0)

当涉及到排序时,总是存在一个问题,即您打算排序的频率与打算访问排序值的频率。 Adjaceny矩阵执行查找的速度可能非常慢,因此如果您在不同的数据结构中表示配对节点和分数更适合排序和快速访问值,则排序和访问您的值可能会更快。我会尝试考虑一种方法来存储边缘分数,并在某种Collection中使用AdjacencyMatrix中的条目,并为该集合寻找有效的排序算法。由于您正在处理相当大的数据集,因此我想到了PriorityQueue,但可能有其他算法可能更适合您的需求,可以找到使用优先级队列在固定时间内对大型数据集进行排序的示例{ {3}}。对集合进行排序后,您可以从集合中获取顶部的'n'值,并检索邻接矩阵中对这些条目的引用,您可以使用这些条目来绘制图形或者有什么。

注意:除了缓慢的查找时间外,Adjaceny Matrices的数据存储内存成本也很高,因此这种可能的解决方案可能会对您产生其他性能影响,最终将取决于您将如何使用数据。

修改

好的,要解决您的评论,请说您的矩阵命名为A,并且您要插入的对节点为A[ i ][ j ],然后您可以使用Entry作为您设置为关键值的对象。当你看到

PriorityQueue < Entry < K, V>>

你要插入的'K'(你的键值)是另一个可以被认为是

的Entry对象
PriorityQueue < Entry < Entry < Integer,Integer>, V>>

因此,当您调用add时,您将(新的Entry(i,j),edgeScore)插入队列。 这有意义吗?

修改

为了解决你的第二个评论,如下所述,理论上的邻接矩阵是2D(nxn)布尔数组。它们不是最有效的内存,访问速度可能很慢,但在适当的情况下有一些用处。有关更详细的实现细节,您可以查看此here,其中显示了一个非常基本的实现方法,可以帮助您入门。您还可以尝试查看example of implementing an adjaceny matrix以查看其他人推荐的替代方法以及提高实施性能的方法,但基本上我认为利用优先级队列的最佳方法是构建队列AS将值插入到nxn布尔矩阵中,这将避免迭代矩阵本身,并为您提供优先级队列的排序能力,如果您之后添加更多节点,您还可以继续添加到PriorityQueue,它将照顾他们。