【问题标题】:how to add links or update existing links property to a JUNG graph如何向 JUNG 图添加链接或更新现有链接属性
【发布时间】:2014-06-23 09:44:29
【问题描述】:

我有一个来自 mysql 数据库的结果集,我正在尝试使用这些值构建一个 JUNG 图。我已经将我的空图实例化为:

Graph<Node, Edge> g = new SparseMultigraph<>();

然后我添加了节点 (586)。我现在正在添加链接,现在事情变得更加复杂。我的自定义 Edge 的结构非常简单,它只有一个“时间”属性,例如:

Multiset<Timestamp> time;

链接的结果集包含 3273684 个表单项:

id  time                    sender  receiver
12  2014-03-20 09:26:04.000 2       99

现在,如果链接不存在,我想做的是从 id 为 2 的节点和 id 为 99 的节点创建一个链接,或者只是将时间戳添加到已经存在的链接。我要做的是:

while (resultSet.next()) {
    // retrieve sender
    Node sender = findNode(resultSet.getInt("sender"), g);
    // retrieve receiver
    Node receiver = findNode(resultSet.getInt("receiver"), g);
    // if they are already linked
    if(g.isPredecessor(sender, receiver)){
        // just add the new timestamp to the existing link
        Collection<Edge> outEdges = g.getOutEdges(sender);
        // find the right edge
        for(Edge e:outEdges){
            // if this edge is connected to receiver
            if(g.getDest(e).equals(receiver)){
                // add the new timestamp to this edge
                e.setTime(resultSet.getTimestamp("time"));
            }
        }
    } else { // else a new link is added
        Information e = new Information();
        e.setId(resultSet.getInt("id"));
        e.setTime(resultSet.getTimestamp("time"));
        g.addEdge(e, sender, receiver, EdgeType.DIRECTED);
    }
}

我的问题是这真的很慢,我不明白这是否正常,因为结果集很大,或者我错过了一种更清晰/更快的方式来实现我需要的东西。

为了清楚起见,我的 findNode() 方法是这样的:

private static Node findNode(int aInt, Graph<Node, Edge>g) {
    for(Node n:g.getVertices()){
        if(n.getId()== aInt){
            return n;
        }
    }
    return null;
}

【问题讨论】:

    标签: java mysql jung


    【解决方案1】:

    这很慢有两个原因:

    (1) 您没有有效的方法来查找给定 ID 的节点。对于这种大小的图表,我建议您在填充图表时构建一个地图,并使用该地图来实现 findNode()。

    (2) 一旦你有了两个节点并且你想获得连接它们的边(如果有的话),只需使用 Graph.findEdge()。

    (1) 是迄今为止您的代码运行缓慢的最大原因。 (2) 不会有太大帮助,但它也会使您的代码更易于阅读和更优雅。

    【讨论】:

    • 举个例子,没有。本质上,当您构建图形时,在某些时候您将刚刚构建了节点对象,因此您将获得节点及其 ID;那时把它们放在地图上。最简单的方法可能是让你的节点类在里面有一个静态的 Map 实例。这也意味着 findNode() 本身应该是节点类的静态方法。
    • 感谢 Joshua,我选择了一个 hashmap 在将节点添加到图表之前,我在其中放置了 ID 和节点......此时我不需要findNode() 方法了,当我需要找到正确的节点时,它只是哈希映射中的 get() ......这有点接近你在答案中的意思吗?
    • 顺便说一句,我在使用 Graph.findEdge() 时遇到问题...你看我测试 g.isPredecessor(sender, receiver) 但如果这是真的,我要求 g.findEdge(sender ,接收者)我得到一个空指针异常......
    • Simone@ findEdge() 问题听起来像是一个不同的问题。 :) 请将其作为一个单独的问题发布,其中包含堆栈跟踪和一个小的独立示例来演示它。
    • Simone@,我无法从你的描述中确定,但听起来你的地图解决方案基本上就是我描述的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多