Продолжение итерации по графу с использованием XML minidom

Это продолжение вопроса ( Ссылка)

Я собираюсь использовать XML для создания графа с использованием NetworkX. Рассматривая структуру DOM ниже, все узлы в одном и том же узле должны иметь границу между ними, и все узлы, которые посетили одну и ту же конференцию, должны иметь узел для этой конференции. Подводя итог, все авторы, которые работали вместе над документом, должны быть связаны друг с другом, и все авторы, которые посетили конкретную конференцию, должны быть подключены к этой конференции.

<conference name="CONF 2009">
<paper>
<author>Yih-Chun Hu(UIUC)</author>
<author>David McGrew(Cisco Systems)</author>
<author>Adrian Perrig(CMU)</author>
<author>Brian Weis(Cisco Systems)</author>
<author>Dan Wendlandt(CMU)</author>
</paper>
<paper>
<author>Dan Wendlandt(CMU)</author>
<author>Ioannis Avramopoulos(Princeton)</author>
<author>David G. Andersen(CMU)</author>
<author>Jennifer Rexford(Princeton)</author>
</paper>
</conference>

Я выяснил, как подключить авторов к конференциям, но я не уверен, как связать авторов друг с другом. С чем я сталкиваюсь, так это с тем, как перебирать авторов, которые работали над одним и тем же документом, и соединять их вместе.

    dom = parse(filepath)
    conference=dom.getElementsByTagName('conference')
    for node in conference:
        conf_name=node.getAttribute('name')
        print conf_name
        G.add_node(conf_name)

    #The nodeValue is split in order to get the name of the author 
#and to exclude the university they are part of

        plist=node.getElementsByTagName('paper')
        for p in plist:
            author=str(p.childNodes[0].nodeValue)
            author= author.split("(")
#Figure out a way to create edges between authors in the same <paper> </paper>

        alist=node.getElementsByTagName('author')
        for a in alist:
            authortext= str(a.childNodes[0].nodeValue).split("(")

            if authortext[0] in dict:
                edgeQuantity=dict[authortext[0]]
                edgeQuantity+=1
                dict[authortext[0]]=edgeQuantity
                G.add_edge(authortext[0],conf_name)

            #Otherwise, add it to the dictionary and create an edge to the conference.
            else:
                dict[authortext[0]]= 1
                G.add_node(authortext[0])
                G.add_edge(authortext[0],conf_name)
                i+=1

2 ответа

Решение

Я не уверен, как связать авторов друг с другом.

Вам нужно сгенерировать (автор, другой) пары, чтобы вы могли добавить их как ребра. Типичный способ сделать это - вложенная итерация:

for thing in things:
    for otherthing in things:
        add_edge(thing, otherthing)

Это наивная реализация, которая включает в себя самостоятельные циклы (предоставляя автору преимущество, связывающее себя с самим собой), что вы можете или не хотите; он также включает в себя (1,2) и (2,1), что, если вы делаете неориентированный граф, является избыточным. (В Python 2.6 встроенный permutations генератор также делает это.) Вот генератор, который исправляет эти вещи:

def pairs(l):
    for i in range(len(l)-1):
        for j in range(i+1, len(l)):
            yield l[i], l[j]

Я не использовал NetworkX, но, глядя на документ, кажется, можно сказать, что вы можете вызвать add_node на одном и том же узле дважды (во второй раз ничего не происходит). Если это так, вы можете отказаться от того, что вы использовали, чтобы отслеживать, какие узлы вы вставили. Также кажется, что если вы добавите ребро в неизвестный узел, он автоматически добавит этот узел для вас. Так что должна быть возможность сделать код намного короче:

for conference in dom.getElementsByTagName('conference'):
    var conf_name= node.getAttribute('name')
    for paper in conference.getElementsByTagName('paper'):
        authors= paper.getElementsByTagName('author')
        auth_names= [author.firstChild.data.split('(')[0] for author in authors]

        # Note author's conference attendance
        #
        for auth_name in auth_names:
            G.add_edge(auth_name, conf_name)

        # Note combinations of authors working on same paper
        #
        for auth_name, other_name in pairs(auth_names):
            G.add_edge(auth_name, otherauth_name)

Я не совсем уверен, что вы ищете, но на основе вашего описания я составил график, который, я думаю, включает в себя отношения, которые вы описываете.

https://imgur.com/o2HvT.png

я использовал openfst, чтобы сделать это. Я считаю, что гораздо проще четко расположить графические отношения, прежде чем погрузиться в код для чего-то вроде этого.

Кроме того, вам действительно нужно создать явное преимущество между авторами? это похоже на проблему обхода.

Другие вопросы по тегам