как добавить ссылки или обновить существующее свойство links в график ЮНГА

#java #mysql #jung

#java #mysql #юнг

Вопрос:

У меня есть результирующий набор, поступающий из базы данных mysql, и я пытаюсь построить график ЮНГА, используя эти значения. Я уже создал экземпляр своего пустого графика как:

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

затем я добавил узлы (586). Сейчас я нахожусь в процессе добавления ссылок, и теперь все становится еще сложнее. Структура моего пользовательского ребра очень проста, у него просто есть свойство «time», например:

 Multiset<Timestamp> time;
 

Результирующий набор для ссылок содержит 3273684 записи в форме:

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

Теперь, что я хочу сделать, это создать ссылку из узла с идентификатором 2 и узла с идентификатором 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;
}
 

Ответ №1:

Это происходит медленно по двум причинам:

(1) У вас нет эффективного способа поиска узла с заданным идентификатором. Для графика такого размера я бы рекомендовал создавать карту по мере заполнения графика и использовать эту карту для реализации findNode() .

(2) Если у вас есть два узла и вы хотите получить ребро, которое их соединяет (если таковое имеется), просто используйте Graph.findEdge() .

(1) на сегодняшний день является основной причиной того, что ваш код работает медленно. (2) не так сильно поможет, но это также сделает ваш код более удобным для чтения и более элегантным.

Комментарии:

1. Пример, нет. По сути, когда вы строите свой график, в какой-то момент вы только что построили свой объект node, и поэтому у вас будет под рукой узел и его идентификатор; поместите их на карту в этот момент. Навскидку самый простой способ сделать это, вероятно, состоял бы в том, чтобы в вашем классе node был экземпляр статической карты внутри него. Это также означало бы, что сам findNode() должен быть статическим методом вашего класса node.

2. Спасибо, Джошуа, я выбрал hashmap<целое число, узел>, где я помещаю идентификатор и узел непосредственно перед добавлением узла в график … на данный момент мне больше не нужен метод findNode(), это просто get() из хэш-карты, когда мне нужнонайдите правильный узел… Это несколько близко к тому, что вы имели в виду в своем ответе?

3. и, кстати, у меня проблемы с Graph.findEdge() … вы видите, я проверяю g.isPredecessor(отправитель, получатель), но если это правда, и я прошу g.findEdge(отправитель, получатель) Я получаю исключение нулевого указателя…

4. Simone@ проблема с findEdge () звучит как другая проблема. 🙂 Пожалуйста, опубликуйте его как отдельный вопрос с трассировкой стека и небольшим автономным примером, который его демонстрирует.

5. Симона @, я не могу сказать наверняка из вашего описания, но похоже, что ваше решение для Map<> по сути является тем, что я описал.