mvk-team42 / Veracitor

An application that studies the trust in a network of users, sources and articles
6 stars 2 forks source link

Globalt grafobjekt #6

Closed mrunelov closed 11 years ago

mrunelov commented 11 years ago

Vi behöver diskutera hur det globala grafobjektet ska fungera och implementeras. Vi behöver koda inläsningen av grafen från databasen. Vi tänkte att det lättaste är om de databasansvariga även ansvarar för att skapa det globala grafobjektet och ser till att hålla uppdaterat när ändringar sker i databasen (just hur uppdaterat det ska vara kom vi kanske överens om men det har vi glömt).

Som hjälp på vägen får ni en mall på hur grafen ska konstrueras som pythonobjekt:

Här har ni en länk till networkx tutorial om skapandet av grafer: http://networkx.github.com/documentation/latest/tutorial/tutorial.html

Vi kommer att använda DiGraph, som är en riktad graf. Användbara kommandon när man jobbar med python dicts är:

import networkx as nx
nx.to_dict_of_dicts(Graph)  #ger en dict-representation av grafen Graph
Graph = nx.DiGraph(dict) #skapar en graf från en dict.

Exempel1 (OBS pseudokod) : Grafen är en vanlig nestad python-dict. Ytterst har man noden som sätter betyg (node_id), sedan har man en dict av dess grannar (neighbour_one_id osv). Varje granne har en dict av betyg som den fått från node_id, med tag-namn och tillhörande betyg.

{
    node_id:{
        neighbour_one_id:{
            'crime': 1, 'cooking': 4
        }, 
        neighbor_two_id:{
            'crime':5
        }
    }
}

Exempelgraf:

{1: {2: {'cooking': 10, 'crime': 4}, 3: {'cooking': 8, 'crime': 7}, 4: {'cooking': 9, 'crime': 6}}, 2: {5: {'cooking': 9, 'crime': 9}}, 3: {5: {'cooking': 10, 'crime': 5}, 6: {'cooking': 10, 'crime': 6}, 7: {'cooking': 7}}, 4: {5: {'cooking': 8, 'crime': 7}, 6: {'cooking': 9, 'crime': 6}}, 5: {7: {'cooking': 8, 'crime': 5}}, 6: {7: {'cooking': 6, 'crime': 7}}, 7: {}}

Man kan även skapa grafer med hjälp av networkx-funktioner så här:

graph = nx.DiGraph()
graph.add_edges_from([(1,2,dict(cooking=10, crime=4)),
                      (1,3,dict(cooking=8, crime=7)),
                      (1,4,dict(cooking=9, crime=6)),
                      (2,5,dict(cooking=9, crime=9)),
                      (3,5,dict(cooking=10, crime=5)),
                      (3,6,dict(cooking=10, crime=6)),
                      (3,7,dict(cooking=7)),
                      (4,5,dict(cooking=8, crime=7)),
                      (4,6,dict(cooking=9, crime=6)),
                      (5,7,dict(cooking=8, crime=5)),
                      (6,7,dict(cooking=6, crime=7)),
                      ])

Viktigt att ni noterar är att det alltid bara finns en kant mellan två givna noder. I denna kant sparas alla tag-ratings som gjort från nod A till nod B. Lägger man till en kant i networkX som redan finns kommer de nya tag-ratings som man definierar där att tryckas in på rätt ställe - tror jag. Testa gärna.

Frågor???

Edit: Tog bort 'weight'-attributen från exempelgrafen på grund av att de inte behövs.

JonathanMurray commented 11 years ago

Ser bra ut! Ska börja kolla på implementation senare. En fråga: vad menar ni med 'weight':1? Har 'weight' någon särskild betydelse? Det är väl inte en tag i stil med 'cooking' o 'crime'?

Ang. uppdateringar tror jag vi sa så här:

Använder ni en kopia av nätverket i TidalTrust, förresten? Annars kanske det är problematiskt om man modifiererar nätverket från annat håll mitt under en körning?

mold commented 11 years ago

Ah, de 'weight':1-attribute som står ska egentligen inte vara där. De var bara med som en garanti på att allt skulle fungera eftersom vissa networkX-algoritmer använder det (av networkX "ägda") attributet, till exempel kortaste viktade stigen. Inga sådana algoritmer används dock så kanter behöver inte ha ett weight-attribut - förutsatt att de har taggade ratings istället.

Angående kopior använder vi oss nog inte av det men en vettig regel skulle vara att alla moduler garanterar att input-variablerna inte förstörs av funktionsanrop.

(Tog bort weight-attributen nu)

Alfred26 commented 11 years ago

"Varje gång en grafrelaterad modifiering av databasen sker i EntityModel-paketet (typ add/remove producer/user/information samt add/remove/change trust-rating), så anropas motsvarande listener-metod i GlobalNetwork, och grafen uppdateras mha nx-metodanrop."

Vi slopade alltså helt tanken med intervalluppdateringar. Däremot så borde det kanske köras nya avbildningar av databasen i perioder för säkerhets skull så att det inte uppstår några synkproblem(?). Ska notifieringsmetoderna köras så fort något ändras i entitymodel eller ska de köras vid .save()?

mold commented 11 years ago

Intervalluppdateringslösningen tror jag vi kom överens om att slopa, men det finns inget skriftligt som styrker det.

JonathanMurray commented 11 years ago

Vi slopade definitivt intervallupdateringslösningen! :) Finns inget skriftligt som antyder dess existens heller tror jag. Nya avbildningar av databasen ska inte vara nödvändigt om vi skriver buggfri kod tror jag. Om det uppstår synkproblem får vi nog förbättra koden, helt enkelt. Vad menar du (Alfred) med den sista frågan? Jag tror inte det kommer finnas några usecases där man "ändrar" i entitymodel utan att också spara ändringarna! Det får man ju inte ut något av. Mitt svar är alltså "vid .save() men man kommer alltid anropa .save() när man ändrat ngt". Har ni tänkt på nåt annat sätt?

mrunelov commented 11 years ago

Vi borde reda ut exakt hur GUIt ska fungera m.a.p. detta. också

-------- Original message -------- From: JonathanMurray notifications@github.com Date: 2013/03/19 21:37 (GMT+01:00) To: mvk-team42/Veracitor Veracitor@noreply.github.com Cc: mrunelov martin.runelov@gmail.com Subject: Re: [Veracitor] Globalt grafobjekt (#6)

Vi slopade definitivt intervallupdateringslösningen! :) Finns inget skriftligt som antyder dess existens heller tror jag. Nya avbildningar av databasen ska inte vara nödvändigt om vi skriver buggfri kod tror jag. Om det uppstår synkproblem får vi nog förbättra koden, helt enkelt. Vad menar du (Alfred) med den sista frågan? Jag tror inte det kommer finnas några usecases där man "ändrar" i entitymodel utan att också spara ändringarna! Det får man ju inte ut något av. Mitt svar är alltså "vid .save() men man kommer alltid anropa .save() när man ändrat ngt". Har ni tänkt på nåt annat sätt?

— Reply to this email directly or view it on GitHub.