2016-08-08 58 views
0

dupliziert I enthalten, können eine Reihe von verschachtelten Listen haben, die in drei Gruppen getrennt werden können:Erhalten DOT graphviz verschachtelter Listenelemente, welche Knoten

  • A (Subelemente sind Disjunktion, Linienfarben Grün), z.B.

    listA = { 
    ‘a1’: ['b1', 'a2'], 
    ‘a2’: ['c1', 'c2'] 
    } 
    
  • B (Subelemente werden Verbindung bestellt, Linienfarben orange), z.B.

    listB = { 
    ‘b1’: ['c4', 'c5', 'c7'], 
    ‘b2’:['c3', 'b1'] 
    } 
    
  • C (Endelemente - Astknoten)

Die Funktion combinations itereates durch die verschachtelten Listen und gibt alle möglichen Kombinationen (die nur am Ende der Elemente vom Typ C enthält, so Astknoten). Die Funktion write_nodes hilft beim Schreiben der Knoten mit farbigen Linien. Der Anruf write_nodes('task', inputlist) ist für die Erstellung der init Knoten:

def write_nodes(node, subnotes): 
    for k in subnotes: 
     if node in type_a: 
      text_file.write("{} -> {} [color=\"green\"]\n".format(node, k)) 
     elif (node in type_b) or (node is 'task'): 
      text_file.write("{} -> {} [color=\"orange\"]\n".format(node, k)) 

write_nodes('task', inputlist) 

def combinations(actions): 
    if len(actions)==1: 
     action= actions[0] 
     if action not in type_c: 
      root = action 
     try: 
      actions= type_a[action] 
      write_nodes(root, actions) 
     except KeyError: 
      try: 
       actions= type_b[action] 
       write_nodes(root, actions) 
      except KeyError: 
       #action is of type C, the only possible combination is itself 
       yield actions 
      else: 
       #action is of type B (conjunction), combine all the actions 
       for combination in combinations(actions): 
        yield combination 
     else: 
      #action is of type A (disjunction), generate combinations for each action 
      for action in actions: 
       for combination in combinations([action]): 
        yield combination 
    else: 
     #generate combinations for the first action in the list 
     #and combine them with the combinations for the rest of the list 
     action= actions[0] 
     for combination in combinations(actions[1:]): 
      for combo in combinations([action]): 
       yield combo + combination 

Beispiel Eingang (geordnete Verbindung):

['a1', 'b2', 'c6']

Beispiel Ergebnis:

['c4', 'c5', 'c7', 'c3', 'c4', 'c5', 'c7', 'c6'] 
['c1', 'c3', 'c4', 'c5', 'c7', 'c6'] 
['c2', 'c3', 'c4', 'c5', 'c7', 'c6'] 

Das Ergebnis Ich bin hergekommen m mein Code: enter image description here entsprechenden Punktdatei:

task -> a1 [color="orange"] 
task -> b2 [color="orange"] 
task -> c6 [color="orange"] 
b2 -> c3 [color="orange"] 
b2 -> b1 [color="orange"] 
b1 -> c4 [color="orange"] 
b1 -> c5 [color="orange"] 
b1 -> c7 [color="orange"] 
a1 -> b1 [color="green"] 
a1 -> a2 [color="green"] 
b1 -> c4 [color="orange"] 
b1 -> c5 [color="orange"] 
b1 -> c7 [color="orange"] 
a2 -> c1 [color="green"] 
a2 -> c2 [color="green"] 

Das Ergebnis ich will (Farben sind nicht vor eins): enter image description here

Fragen:

Wie kann ich damit umgehen, da gibt es einige duplizierte Knoten um ein Ergebnis zu erhalten erwähnt?

Danke für jede Hilfe.

+0

Kennen Sie das 'graphviz' Python-Paket? Was hast du probiert? Übrigens, es ist schlecht, 'try/except' für den normalen Programmablauf zu verwenden. –

+1

Ich habe meine Frage aktualisiert, was ich bisher habe. Ich denke _familiar_ ist das falsche Wort, ich kenne nur die Struktur einer Punktdatei. Vielleicht können Sie mir helfen, was ist eine bessere Möglichkeit, den Versuch/außer zu vermeiden. – eljobso

Antwort

1

Doppeltes Knoten Problem

das Duplikat zu vermeiden Knoten Problem sollten Sie jeden Knoten mit einem eindeutigen Namen nennen und ein label für den angezeigten Namen verwenden.Zum Beispiel:

b2 -> b1 [color="orange"] 
b1 -> c4 [color="orange"] 
b1 -> c5 [color="orange"] 
b1 -> c7 [color="orange"] 
a1 -> b1 [color="green"] 
b1 -> c4 [color="orange"] 
b1 -> c5 [color="orange"] 
b1 -> c7 [color="orange"] 

zu:

b21 [label="b2"] 
b11 [label="b1"] 
b21 -> b11 [color="orange"] 
c41 [label="c4"] 
b11 -> c41 [color="orange"] 
c51 [label="c5"] 
b11 -> c51 [color="orange"] 
c71 [label="c7"] 
b11 -> c71 [color="orange"] 
a11 [label="a2"] 
b12 [label="b1"] 
a11 -> b12 [color="green"] 
c42 [label="c4"] 
b12 -> c42 [color="orange"] 
c52 [label="c5"] 
b12 -> c52 [color="orange"] 
c72 [label="c7"] 
b12 -> c72 [color="orange"] 

Welche produzieren: res

Vermeiden try/except Flow

Es ist besser if/else zu verwenden und nicht try/except für den normalen Programmablauf. Zum Beispiel statt:

try: 
     actions= type_a[action] 
     write_nodes(root, actions) 
    except KeyError: 
     #do whatever you do 

Verwendung:

actions = type_a.get(action, None) #if the key doesn't exists assign None 
    if actions: 
     write_nodes(root, actions) 
    else: 
     #do whatever you do 

Graphviz Python-Paket

können Sie die graphviz python package anstelle der Punkt-Datei selbst zu schreiben.