Budowanie grafu z listy par

Budowanie grafu z listy par
Paweł Tometczak
  • Rejestracja:ponad 6 lat
  • Ostatnio:ponad rok
  • Postów:31
0

Hej,

mam taką przykładową listę list słów:

Kopiuj
[['rowerowy', 'rower']
['rowerzysta', 'rower']
['domeczek',  'domek']
['domek', 'dom']
['rowerzystka', 'rowerzysta']]

i potrzebuję złączyć wyrazy w grupy zależności, czyli robimy graf połączeń między formami:

Kopiuj
rowerowy --> rower <-- rowerzysta <--- rowerzystka
domeczek --> domek --> dom

Jak zostaną nie podpięte do żadnego grafu pary w relacji to one tworzą graf z jedną krawędzią.

Jakieś pomysły ?

edytowany 2x, ostatnio: Riddle
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:2 minuty
  • Lokalizacja:Laska, z Polski
  • Postów:10074
LukeJL
  • Rejestracja:około 11 lat
  • Ostatnio:3 minuty
  • Postów:8423
4

Ja bym tak spróbował, żeby przechodząc po każdej parze stworzyć ten graf.
graf mógłby być słownikiem indeksowanym po słowie (np. rower)

jego węzły mogłyby być słownikami z kluczem name (np. rower) oraz kluczem links, gdzie byłaby lista połączeń do innych węzłów

graf mógłbyś stworzyć tak:

dla każdej pary A-B:
sprawdź, czy węzeł dla nazwy A istnieje, jeśli nie istnieje to stwórz go
sprawdź, czy węzeł dla nazwy B istnieje, jeśli nie istnieje to stwórz go
dodaj węzeł A do B['links']
dodaj węzeł B do A['links']

czy to, co mówię, ma sens?


edytowany 3x, ostatnio: LukeJL
_13th_Dragon
Bez ostatniego kroku, z semigraficznego rysunku wynika że graf skierowany.
PaulGilbert
  • Rejestracja:około 7 lat
  • Ostatnio:około 6 godzin
  • Postów:929
1

A dlaczego rowerzystka połączona do rowerzysta a nie do rower? Podobnie domeczek do domek a nie do dom? Nie widzę tu jakiejś wyraźnej reguły. Chyba że te grupy mają znaczenie? Ty sam tworzysz te pary czy to masz jakieś gotowe skądś?

Edit:
Pamiętam, że do grafów była w Pythonie taka biblioteka NetworkX. Nie pamiętam już co ona tam dokładnie robiła, ale może zerkniesz sobie na nią.

edytowany 3x, ostatnio: PaulGilbert
Riddle
Graf jest zbudowany na podstawie listy par, a to co jest w liście par to przecież nie ma znaczenia.
Paweł Tometczak
  • Rejestracja:ponad 6 lat
  • Ostatnio:ponad rok
  • Postów:31
0

Prawa to derywat, lewa to baza derywacyjna.
Relacje zawsze idą OD DERYWATU DO BAZY.

_13th_Dragon
Zaraz cię feministki za coś tam powieszą ... rowerzysta <--- rowerzystka czemu nie rower <--- rowerzystka?
Patryk27
@_13th_Dragon: ponieważ rowerzystka pochodzi od słowa rowerzysta, a nie rower :-P imo to nie jest żadna tajemnica i książki poruszające tę tematykę (np. Feminatywum w uwikłaniach językowo-kulturowych, o ile dobrze jeszcze pamiętam zawartość) też w taki sposób opisywały odmianę (w szczególności sposób w jaki formant -ka jest, uhm, overloaded w języku polskim).
_13th_Dragon
@Patryk27, nie mówiłem że wieszać będą lingwiści :-P
Patryk27
tak, ale biorąc pod uwagę kontekst (istniejące już feministyczne książki poruszające morfologię języka polskiego), to zaraz cię feministki za coś tam powieszą brzmi zwyczajnie jak próba dowalenia grupie osób, zupełnie bez ładu i składu wrzucając politykę do pełni neutralnego wątku 🙃
S7
  • Rejestracja:prawie 5 lat
  • Ostatnio:3 dni
  • Postów:354
0

Na czym polega problem skoro masz juz pary wierzcholkow, na zbudowanie grafu?
Prostym sposobem jest zamenieniem tej listy na slownik:

Kopiuj
lista = [
    ['rowerowy', 'rower'],
    ['rowerzysta', 'rower'],
    ['domeczek',  'domek'],
    ['domek', 'dom'],
    ['rowerzystka', 'rowerzysta'],
]

graf = {}

for para in lista:
    if para[1] not in graf:
        graf[para[1]] = ""
    graf[para[0]] = para[1]

print(graf)
print()
print(graf[graf["domeczek"]])

wyjscie:

Kopiuj
{'rower': '', 
'rowerowy': 'rower', 
'rowerzysta': 'rower', 
'domek': 'dom', 
'domeczek': 'domek', 
'dom': '', 
'rowerzystka': 'rowerzysta'}

dom

Competitive Google searcher
Zobacz pozostałe 10 komentarzy
Riddle
No faktycznie to graf skierowany.
S7
Narysowanie grafu to jest problem który trzeba rozwiązać? Bo OP pisze dosyć niejasno, jakby jedynym problemem było reprezentowanie grafu
Riddle
No jak dla mnie taki skierowany graf nie za bardzo rozwiąże problem z wątku.
S7
A jaki jest problem wątku? Bo ja go najwidoczniej nie rozumiem
_13th_Dragon
Do czegokolwiek by ten graf nie był potrzebny, podane w tym poście rozwiązanie nie da lepszego wyniku niż zapis źródłowy.
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
0

Do czego potrzebujesz tego grafu:

  • Wyświetlenia?
  • Szukania ścieżek?
  • Inne zabawy ...?

Kolejka na bazarku po ogórki.
- Co Pani podać?
- Poproszę ten grubszy.
- Proszę. A Pani co podać?
- Poproszę ten dłuższy.
- Proszę. A Panu co podać?
- A mi wszystko jedno, mi na sałatkę.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
Paweł Tometczak
  • Rejestracja:ponad 6 lat
  • Ostatnio:ponad rok
  • Postów:31
0
_13th_Dragon napisał(a):

Do czego potrzebujesz tego grafu:

  • Wyświetlenia?
  • Szukania ścieżek?
  • Inne zabawy ...?

Na razie muszę to wypisać.
Potem lengwiści z tym pracują.

S7
a jak duża jest ta baza, i jak ładne mają być te wizualizacje? cos w stylu https://csacademy.com/app/graph_editor/ ?
Paweł Tometczak
Plik ma niecałe 140 000 wierszy. Wystarczy proste wypisanie :)
S7
  • Rejestracja:prawie 5 lat
  • Ostatnio:3 dni
  • Postów:354
0

ale samo wypisanie moze byc problematyczne, gdy ten graf bedzie bardziej zlozony np taki graf
ab a
ac a
ad a
al a
ala al
all al

to wypisanie go to bedzie jakies:

Kopiuj
  <- ab
  <- ac
a <- ad
           ala
  <- al <-	
           all

Competitive Google searcher
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:2 minuty
  • Lokalizacja:Laska, z Polski
  • Postów:10074
0
Suchy702 napisał(a):

ale samo wypisanie moze byc problematyczne, gdy ten graf bedzie bardziej zlozony np taki graf
ab a
ac a
ad a
al a
ala al
all al

to wypisanie go to bedzie jakies:

Kopiuj
  <- ab
  <- ac
a <- ad
           ala
  <- al <-	
           all

Nie musi go graficznie wypisać.

Może wypisać listę node'ów (czyli dla grafu który ma 15 node'ów, byłoby 15 linijek), i przy niej wszystkie sąsiednie node'y.

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
2
Suchy702 napisał(a):

ale samo wypisanie moze byc problematyczne, gdy ten graf bedzie bardziej zlozony np taki graf
ab a
ac a
ad a
al a
ala al
all al

Ja wypisałbym to następująco (przy dobrej strukturze da się rekurencyjnie):

Kopiuj
<- a 
  <- ad
  <- ab
  <- ac
  <- al
    <- ala
    <- all
Kopiuj
source = \
[
    ['rowerowy','rower'],
    ['rowerzysta','rower'],
    ['domeczek','domek'],
    ['domek','dom'],
    ['rowerzystka','rowerzysta'],
]

def showtree(graph,node=None,deep=0):
    print(("\t"*deep+"<= " if deep else '')+str(node))
    deep+=1
    if node in graph:
        for sub in sorted(graph[node]):
            showtree(graph,sub,deep)

def showtreenoroot(graph,node=None,deep=0):
    for sub in sorted(graph[node]):
        print(("\t"*deep+"<= " if deep else '')+sub)
        if sub in graph:
            showtreenoroot(graph,sub,deep+1)

def maketree(source):
    graph={}
    for pair in source:
        nodein,nodeout=pair
        if nodeout in graph:
            graph[nodeout].add(nodein)
        else:
            graph[nodeout]={nodein}
    graph[None]=set(graph.keys()).difference(set.union(*graph.values()))
    return graph

showtree(maketree(source))
print()
showtreenoroot(maketree(source))
print()
showtreenoroot(maketree([['ab','a'],['ac','a'],['ad','a'],['al','a'],['ala','al'],['all','al']]))

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 7x, ostatnio: _13th_Dragon
S7
Miałoby taka strukturę jak foldery, ciekawe
Paweł Tometczak
  • Rejestracja:ponad 6 lat
  • Ostatnio:ponad rok
  • Postów:31
0

Wygląda ok ale przy dużych plikach wywale mi, że za dużo rekurencji :(

Może da się prościej:
ab -> a <- ab <- ac

S7
No a co w przypadku wierzchołka do którego wchodzą 3 inne? Jak to zaprezentujesz, chyba że takich nie ma.
_13th_Dragon
Jeżeli masz błąd "stack overflow" oznacza to że masz gdzieś Sepulka –> Sepulkaria, Sepulkaria -> Sepulenie, Sepulenie -> Sepulka czyli nie jest tak jak mówiłeś na początku.
S7
Możesz wysłać ten plik z danymi?
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
1
Paweł Tometczak napisał(a):

Wygląda ok ale przy dużych plikach wywale mi, że za dużo rekurencji :(

Może da się prościej:
ab -> a <- ab <- ac

Czym tobie przeszkadza rekurencja?
Wszystkie przedstawione algorytmy mają złożoność O(1) - tego nie przeskoczysz.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
Paweł Tometczak
  • Rejestracja:ponad 6 lat
  • Ostatnio:ponad rok
  • Postów:31
0

a jeszcze dopytam :-)

mam słownik:

Kopiuj
{'odsłuch': ['odsłuchiwać'],
 'zgoda': ['zgodzić się', 'zgodzić się', 'godzić'],
 'rzeczywisty': ['rzeczywistość', 'rzeczywistość'],
 'niezależność': ['niezależny', 'niezależny', 'niezależny'],
 'niezależny': ['niezależność', 'niezależność', 'niezależność'],
 'mineralny': ['minerał', 'minerał'],
 'pociotek': ['pociot'],
 'smutny': ['smutek', 'smuta'],
 'czerniowiecki': ['Czerniowce'],
 'lugrowy': ['lugier'],
 'obojętność': ['obojętny', 'obojętny', 'obojętny'],
 'szmer': ['szemrać', 'szemrać'],
 'akuszerka': ['akuszer', 'akuszerstwo', 'akuszeria']}

Jak najsensowniej wywalić duplikaty z list, które są wartościami słownika ?
set() coś nie idzie:-(

edytowany 1x, ostatnio: Paweł Tometczak
PaulGilbert
zamiast list nie możesz zrobić jako wartości zbiorów?
Paweł Tometczak
wolałbym zostawić listę
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:2 minuty
  • Lokalizacja:Laska, z Polski
  • Postów:10074
1
Paweł Tometczak napisał(a):

a jeszcze dopytam :-)

mam słownik:

Kopiuj
{'odsłuch': ['odsłuchiwać'],
 'zgoda': ['zgodzić się', 'zgodzić się', 'godzić'],
 'rzeczywisty': ['rzeczywistość', 'rzeczywistość'],
 'niezależność': ['niezależny', 'niezależny', 'niezależny'],
 'niezależny': ['niezależność', 'niezależność', 'niezależność'],
 'mineralny': ['minerał', 'minerał'],
 'pociotek': ['pociot'],
 'smutny': ['smutek', 'smuta'],
 'czerniowiecki': ['Czerniowce'],
 'lugrowy': ['lugier'],
 'obojętność': ['obojętny', 'obojętny', 'obojętny'],
 'szmer': ['szemrać', 'szemrać'],
 'akuszerka': ['akuszer', 'akuszerstwo', 'akuszeria']}

Jak najsensowniej wywalić duplikaty w list, które są wartościami słownika ?
set() coś nie idzie:-(

Jeśli słownik jest w zmiennej my_dict, to:

Kopiuj
without_duplicates = {key: list(set(value)) for key, value in my_dict.items()}
edytowany 1x, ostatnio: Riddle
Zobacz pozostałe 6 komentarzy
Riddle
@Paweł Tometczak: Pokaż cały kod jaki masz
Paweł Tometczak
To jutro bo wyszedłem z pracy.
Paweł Tometczak
Ok, zadziałało z 'list'. Daję poniżej kod.
Riddle
Znaczy, dokładniej mówiąc to set() usuwa duplikaty. list() jest po to żeby wynikowa kolekcja miała list, a nie zbiory, tak jak napisałeś wyżej.
Paweł Tometczak
Dzięki :-), Teraz pomyślę jak to sensownie wizualizować.
Paweł Tometczak
  • Rejestracja:ponad 6 lat
  • Ostatnio:ponad rok
  • Postów:31
0
Kopiuj
data = []


with open('extracted_plwn_deriv.tsv') as file:
    for line in file.readlines():
        if line not in ['\n']:
            if not 'GERUNDIUM' in line:
                line = line.strip("\n")
                a,b,c = line.split("\t")
                data.append([c,a])

out. skrócony:

Kopiuj
[['odsłuchiwać', 'odsłuch'],
 ['zgodzić się', 'zgoda'],
 ['rzeczywistość', 'rzeczywisty'],
 ['niezależny', 'niezależność'],
 ['niezależność', 'niezależny'],
 ['minerał', 'mineralny'],
 ['pociot', 'pociotek'],
 ['smutek', 'smutny'],
 ['Czerniowce', 'czerniowiecki'],

i dalej

Kopiuj
graph_group={}

for pair in data:
    nodein,nodeout = pair
    if nodeout in graph_group:
        graph_group[nodeout].append(nodein)
    else:
        graph_group[nodeout] = [nodein]
        
graph_group

out:

Kopiuj
{'odsłuch': ['odsłuchiwać'],
 'zgoda': ['zgodzić się', 'zgodzić się', 'godzić'],
 'rzeczywisty': ['rzeczywistość', 'rzeczywistość'],
 'niezależność': ['niezależny', 'niezależny', 'niezależny'],
 'niezależny': ['niezależność', 'niezależność', 'niezależność'],
 'mineralny': ['minerał', 'minerał'],
 'pociotek': ['pociot'],
 'smutny': ['smutek', 'smuta'],
 'czerniowiecki': ['Czerniowce'],
 'lugrowy': ['lugier'],
 'obojętność': ['obojętny', 'obojętny', 'obojętny'],...

i po usunięciu duplikatów z list

Kopiuj
without_duplicates = {key: list(set(value)) for key, value in graph_group.items()}
without_duplicates

out:

Kopiuj
{'odsłuch': ['odsłuchiwać'],
 'zgoda': ['godzić', 'zgodzić się'],
 'rzeczywisty': ['rzeczywistość'],
 'niezależność': ['niezależny'],
 'niezależny': ['niezależność'],
 'mineralny': ['minerał'],
 'pociotek': ['pociot'],
 'smutny': ['smuta', 'smutek'],
 'czerniowiecki': ['Czerniowce'],
 'lugrowy': ['lugier'],
 'obojętność': ['obojętny'],...
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
1
Kopiuj
graph_group={}
for pair in data:
    nodein,nodeout = pair
    if nodeout in graph_group:
        graph_group[nodeout].add(nodein) # zmiana 1
    else:
        graph_group[nodeout] = {nodein} # zmiana 2
       
graph_group

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
Paweł Tometczak
Tak wiem, że wówczas nie ma problemu z duplikatami ale wolałem to mieć w listach.
_13th_Dragon
Po zakończeniu budowy przerób na listę: graph_group = {key: list(value) for key, value in graph_group.items()}

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.