Jakub Adamski 444341 6.5 Zadanie 0.1 ------------------------------------- Wykorzystany przykład events03.tcl oraz events03a.tcl. Polecenie fiber to korutina. Możemy np przełączać procesor na kolejne fibery poleceniem fiber yield. Nie załączam kodu - jest na stronie. /// wydruk events03.tcl 0: aaaaaaaaa 1: aaaaaaaaa 2: aaaaaaaaa 0: bbbbbbbbb 1: bbbbbbbbb 2: bbbbbbbbb /// koniec wydruku events03.tcl /// wydruk events03a.tcl #% 2 0 1 3 #% 1 0 3 2 #% 1 0 2 3 #% 0 3 2 1 #% 0 2 3 1 #% 0 3 1 2 #% 0 2 1 3 #% 0 1 3 2 #% 0 1 2 3 /// koniec wydruku events03a.tcl Zadanie 0.2 ------------------------------------- Uruchomiłem przykład z tutoriala do symulatora dotyczący "Przyklad symulacji modelu synchronicznego w tym przykładzie po sieci krąży token zawierający zmienną typu "int", której wartość zwiększa się o 1 po każdym skoku". ///kod source symul_lib.tcl; # ladowanie symulatora # tworzymy graf komunikacyjny (w tym wypadku cykl) set liczbaWierz 5 set sasiedzi(0) {4 1} set sasiedzi(1) {0 2} set sasiedzi(2) {1 3} set sasiedzi(3) {2 4} set sasiedzi(4) {3 0} # główny program na każdym wierzchołku/fiberze... fiber create $liczbaWierz { if {$id==0} {wyslij 1 0} fiber yield; # oznacza koniec rundy while {$run} { # zmienna run pozwala zakonczyć działanie symulacji if {$kom(0)!=""} { set x $kom(0) incr x wyslij 1 $x } fiber yield; # oznacza koniec rundy } } Inicjalizacja; # koniecznie trzeba to wywołać !!! proc wizualizacja {} { fiber_iterate {_puts "$id: $kom0, $kom1"} # petla fiber_iterate iteruje po wszystkich fiberach # proc wizualizacja wywolujemy z konsoli po kazdej rundzie } # !!! do tego miejsca wszystko wykonać !!!!!!!!!!!!!!!!!!!!! fiber yield; runda; wizualizacja # wykonuje kolejna runde... # procedura runda dostarcza wysłane komunikaty if 0 { # to się czasem przydaje: set_run 0; fiber yield; runda; set_run 1; fiber delete # usuwanie fiberów set_run 0; fiber yield; runda; set_run 1; fiber restart # restart kodu fiberów fiber error # wyświetla stan fiberów ({}, ended, error) fiber_eval 0 {set id} # wykonanie kodu w fiberze 0 # UWAGA: fiber_eval wykonuje kod na poziomie globalnym # "fiber0 eval {set id}" wykonuje kod tam gdzie fiber zostal zamrozony... } ///koniec kodu /// wydruk 0: , 1: 0, 2: , 3: , 4: , 0: , 1: , 2: 1, 3: , 4: , 0: , 1: , 2: , 3: 2, 4: , 0: , 1: , 2: , 3: , 4: 3, /// koniec wydruku Zadanie 1 ------------------------------------- Algorytm asynchroniczny wyboru lidera, ring zorientowany. /// kod load ./q3.so source symul_lib.tcl; # definuje wierzchołki set liczbaWierz 5 set sasiedzi(0) {4 1} set sasiedzi(1) {0 2} set sasiedzi(2) {1 3} set sasiedzi(3) {2 4} set sasiedzi(4) {3 0} fiber create $liczbaWierz { set lider ?; # lider to niewiadoma wyslij 0 $id; fiber yield; while {$run} { if {$kom(1)!=""} { set x $kom(1); if {$lider==1} { } elseif {$x>$id} { wyslij 0 $x; } elseif {$x==0} { wyslij 0 $x; set lider 0; # nie jest liderem } elseif {$x==$id} { # tutaj ustawiam lidera set lider 1; wyslij 0 0; } elseif {$x < $id} { } } fiber yield; } } Inicjalizacja; # wizualizacja procedury proc wizualizacja {} { fiber_iterate {_puts "$id: $lider, $kom(1)"} } fiber yield; runda; wizualizacja /// koniec kodu //wydruk 0: ?, 1 1: ?, 2 2: ?, 3 3: ?, 4 4: ?, 0 0: ?, 2 1: ?, 3 2: ?, 4 3: ?, 0 4: 0, 1 0: ?, 3 1: ?, 4 2: ?, 0 3: 0, 4: 0, 2 0: ?, 4 1: ?, 0 2: 0, 3: 0, 4: 0, 3 0: ?, 0 1: 0, 2: 0, 3: 0, 4: 0, 4 0: 0, 1: 0, 2: 0, 3: 0, 0 4: 1, 0 /// koniec wydruku Zadanie 1a ------------------------------------- Algorytm asynchroniczny wyboru lidera, ring niezorientowany. Ring nie jest teraz zorientowany. Muszę napisać dodatkowe warunki /// kod load ./q3.so source symul_lib.tcl; # definuję wierzchołki set liczbaWierz 5 set sasiedzi(0) {4 1} set sasiedzi(1) {0 2} set sasiedzi(2) {1 3} set sasiedzi(3) {2 4} set sasiedzi(4) {3 0} fiber create $liczbaWierz { set lider ?; wyslij 0 $id; # wysyłam w jedną stronę wyslij 1 $id; # wysyłam w drugą stronę fiber yield; while {$run} { if {$kom(0)!="" && $kom(1)!=""} { set x ?; if {$kom(0) > $kom(1)} { # warunek 1 set x $kom(0); if {$lider==1} { } elseif {$x==0} { wyslij 1 0; set lider 0; } elseif {$x>$id} { wyslij 1 $x; } elseif {$x==$id} { #lider set lider 1; wyslij 0 0; wyslij 1 0; } elseif {$x < $id} { } fiber yield; } else { # warunek przeciwny set x $kom(1); if {$lider==1} { } elseif {$x==0} { wyslij 0 $x; set lider 0; } elseif {$x>$id} { wyslij 0 $x; } elseif {$x==$id} { set lider 1; # lider wyslij 0 0; wyslij 1 0; } elseif {$x < $id} { } fiber yield; } } elseif {$kom(0)!=""} { # następny warunek set x $kom(0); if {$lider==1} { } elseif {$x==0} { wyslij 1 0; set lider 0; } elseif {$x>$id} { wyslij 1 $x; } elseif {$x==$id} { set lider 1; # lider wyslij 0 0; wyslij 1 0; } elseif {$x < $id} { } fiber yield; } else { # ostatni warunek set x $kom(1); if {$lider==1} { } elseif {$x==0} { wyslij 0 $x; set lider 0; } elseif {$x>$id} { wyslij 0 $x; } elseif {$x==$id} { set lider 1; wyslij 0 0; wyslij 1 0; } elseif {$x < $id} { } fiber yield; } } } Inicjalizacja; # wizualizacja proc wizualizacja {} { fiber_iterate {_puts "id: $id: lider: $lider, kom0: $kom0, kom1: $kom1"} } fiber yield; runda; wizualizacja /// koniec kodu ///wydruk id: 0: lider: ?, kom0: 4, kom1: 1 id: 1: lider: ?, kom0: 0, kom1: 2 id: 2: lider: ?, kom0: 1, kom1: 3 id: 3: lider: ?, kom0: 2, kom1: 4 id: 4: lider: ?, kom0: 3, kom1: 0 id: 0: lider: ?, kom0: , kom1: 2 id: 1: lider: ?, kom0: 4, kom1: 3 id: 2: lider: ?, kom0: , kom1: 4 id: 3: lider: ?, kom0: , kom1: id: 4: lider: ?, kom0: , kom1: id: 0: lider: ?, kom0: , kom1: id: 1: lider: ?, kom0: , kom1: 4 id: 2: lider: ?, kom0: 4, kom1: id: 3: lider: ?, kom0: , kom1: id: 4: lider: ?, kom0: , kom1: 2 id: 0: lider: ?, kom0: , kom1: 4 id: 1: lider: ?, kom0: , kom1: id: 2: lider: ?, kom0: , kom1: id: 3: lider: ?, kom0: 4, kom1: id: 4: lider: ?, kom0: , kom1: id: 0: lider: ?, kom0: , kom1: id: 1: lider: ?, kom0: , kom1: id: 2: lider: ?, kom0: , kom1: id: 3: lider: ?, kom0: , kom1: id: 4: lider: ?, kom0: 4, kom1: 4 id: 0: lider: ?, kom0: 0, kom1: id: 1: lider: ?, kom0: , kom1: id: 2: lider: ?, kom0: , kom1: id: 3: lider: ?, kom0: , kom1: 0 id: 4: lider: 1, kom0: , kom1: id: 0: lider: 0, kom0: , kom1: id: 1: lider: ?, kom0: 0, kom1: id: 2: lider: ?, kom0: , kom1: 0 id: 3: lider: 0, kom0: , kom1: id: 4: lider: 1, kom0: , kom1: id: 0: lider: 0, kom0: , kom1: id: 1: lider: 0, kom0: , kom1: 0 id: 2: lider: 0, kom0: 0, kom1: id: 3: lider: 0, kom0: , kom1: id: 4: lider: 1, kom0: , kom1: /// koniec wydruku Zadanie 1b ------------------------------------- Wybór lidera, więcej niz 1 lider. Dodatkowy warunek na istnienie lidera, lider pośredni. /// kod load ./q3.so source symul_lib.tcl; set liczbaWierz 5 set sasiedzi(0) {4 1} set sasiedzi(1) {0 2} set sasiedzi(2) {1 3} set sasiedzi(3) {2 4} set sasiedzi(4) {3 0} fiber create $liczbaWierz { set lider ?; wyslij 0 $id; fiber yield; while {$run} { if {$kom(1)!=""} { set x $kom(1); if {$lider==1} { } elseif {$x==$id+2} { set lider 1; #lider 1 wyslij 0 0; } elseif {$x>$id} { wyslij 0 $x; } elseif {$x==0} { wyslij 0 $x; set lider 0; } elseif {$x==$id} { set lider 1; # lider 2 wyslij 0 0; } elseif {$x < $id} { } } fiber yield; } } Inicjalizacja; # wizalizacja proc wizualizacja {} { fiber_iterate {_puts "id: $id, lider: $lider, $kom(1)"} } fiber yield; runda; wizualizacja /// koniec kodu ///wydruk id: 0, lider: ?, 1 id: 1, lider: ?, 2 id: 2, lider: ?, 3 id: 3, lider: ?, 4 id: 4, lider: ?, 0 id: 0, lider: ?, 2 id: 1, lider: ?, 3 id: 2, lider: ?, 4 id: 3, lider: ?, 0 id: 4, lider: 0, 1 id: 0, lider: 1, 0 id: 1, lider: 1, 0 id: 2, lider: 1, 0 id: 3, lider: 0, id: 4, lider: 0, 0 /// koniec wydruku Zadanie 2 ------------------------------------- 8-kolorowanie wierzchołkowe drzewa ukorzenionego. Mam problem z zaimplementowaniem algorytmu. /// kod load ./q3.so source symul_lib.tcl; # tworzę graf, drzewo set liczbaWierz 9 set sasiedzi(0) {1 2 3} set sasiedzi(1) {0} set sasiedzi(2) {0 4 5 6} set sasiedzi(3) {0} set sasiedzi(4) {2} set sasiedzi(5) {2 7 8} set sasiedzi(6) {2} set sasiedzi(7) {6} set sasiedzi(8) {6} set obslugaBitow { # postać binarna proc bity x { usun0 [binary scan [binary format I $x] B* x; set x] } } fiber create $liczbaWierz { set c $id; wyslij 0 c; fiber yield; while {$run} { if {$kom(0)!=kom(1)} { set c [expr kom(0) + kom(1)]; # pozycja bitu set bity [expr c * 2]; # razy 2 set lk c; # liczba bitów if{c < 3}{ wyslij 1 c; } } fiber yield; } } Inicjalizacja; proc wizualizacja {} { fiber_iterate {_puts "id: $id, c: $c, $kom(0)"} } fiber yield; runda; wizualizacja /// koniec kodu /// wydruk id: 0, c: 0, c id: 1, c: 1, c id: 2, c: 2, id: 3, c: 3, id: 4, c: 4, id: 5, c: 5, id: 6, c: 6, id: 7, c: 7, id: 8, c: 8, id: 0, c: 0, id: 1, c: 1, id: 2, c: 2, id: 3, c: 3, id: 4, c: 4, id: 5, c: 5, id: 6, c: 6, id: 7, c: 7, id: 8, c: 8, id: 0, c: 0, id: 1, c: 1, id: 2, c: 2, id: 3, c: 3, id: 4, c: 4, id: 5, c: 5, id: 6, c: 6, id: 7, c: 7, id: 8, c: 8, /// koniec wydruku Zadanie 0.3 ------------------------------------- Wizualizacja drzewa. Kolejne kroki opisuję w kodzie zamieszczonym ponizej w komentarzach. Nie zamieszczam wydruku - jest to graficzna wizualizacja. /// kod # inicjalizacja load ./q3.so source symul_graf_lib.tcl # budujemy drzewo set liczbaWierz 0 array unset sasiedzi G::sciezka2 0 10 G::gwiazda2 10 15 0 G::gwiazda2 15 20 1 G::gwiazda2 20 25 2 G::gwiazda2 25 30 3 G::gwiazda2 30 35 4 G::gwiazda2 35 40 5 G::gwiazda2 40 45 6 G::gwiazda2 45 50 7 # rysujemy graf w odpowiedniej kolejności G::rysujGraf -zero 1 # sposób na konfig. połączeń na podstawie ID i nr_połączenia proc tc_pol {id pol} { global sasiedzi set l1 "$id [lindex $sasiedzi($id) $pol]" set l1 [lsort -integer $l1] return "[lindex $l1 0]->[lindex $l1 1]" } # ustawiamy grubość krawędzi .t.c itemconf 1$tc_edge([tc_pol 0 0]) -width 5 .t.c itemconf 1$tc_edge([tc_pol 1 0]) -width 5 .t.c itemconf 1$tc_edge([tc_pol 2 0]) -width 5 .t.c itemconf 1$tc_edge([tc_pol 3 0]) -width 5 # kolorujemy .t.c itemconf 1$tc_node(5) -fill yellow .t.c itemconf 1$tc_node(10) -fill red .t.c itemconf 1$tc_node(15) -fill yellow .t.c itemconf 1$tc_node(20) -fill red /// koniec kodu Zadanie 3 ------------------------------------- Algorytm asynchroniczny wyboru lidera, uzywający O(n logn) komunikatów, dla ringu zorientowanego. Nie udało mi się wykonać zadania, załączam częściowo rozwiązane. /// kod # inicjalizacja load ./q3.so source symul_lib.tcl # ustawienie ringu set liczbaWierz 5 set sasiedzi(0) {4 1} set sasiedzi(1) {0 2} set sasiedzi(2) {1 3} set sasiedzi(3) {2 4} set sasiedzi(4) {3 0} proc reverse li { set len [llength $li] iterate i $len {lappend wynik [lindex $li [expr {$len-$i-1}]]} set wynik } fiber create $liczbaWierz { set lider ? wyslij 0 "$id_los 0 0" wyslij 1 "$id_los 0 0" fiber yield while {$run} { algorytm [czytaj 0] [czytaj 1] fiber yield } } Inicjalizacja; proc wizualizacja {} { _puts --- fiber_iterate {_puts "id: $id, wartosc: $id_los, lider: $lider; $kom0, $kom1"} } fiber_iterate { # + ta procedura jedynie przekazuje komunikaty... proc algorytm {m0 m1} { global id id_los stopien lider if {$m0!=""} { foreach {id0 i0 l0} $m0 break incr i0 wyslij 1 "$id0 $i0 0"; } if {$m1!=""} { foreach {id1 i1 l1} $m1 break incr i1 set i1 [expr {$i1+1}] if {$m1==$id}{ set lider 1; } wyslij 0 "$id1 $i1 0" } } } fiber yield; runda; wizualizacja; set licznikKom /// koniec kodu /// wydruk --- id: 0, wartosc: 498, lider: ?; {207 0 0}, {416 0 0} id: 1, wartosc: 416, lider: ?; {498 0 0}, {48 0 0} id: 2, wartosc: 48, lider: ?; {416 0 0}, {50 0 0} id: 3, wartosc: 50, lider: ?; {48 0 0}, {207 0 0} id: 4, wartosc: 207, lider: ?; {50 0 0}, {498 0 0} --- id: 0, wartosc: 498, lider: ?; {50 1 0}, id: 1, wartosc: 416, lider: ?; {207 1 0}, id: 2, wartosc: 48, lider: ?; {498 1 0}, id: 3, wartosc: 50, lider: ?; {416 1 0}, id: 4, wartosc: 207, lider: ?; {48 1 0}, --- id: 0, wartosc: 498, lider: ?; , id: 1, wartosc: 416, lider: ?; , id: 2, wartosc: 48, lider: ?; , id: 3, wartosc: 50, lider: ?; , id: 4, wartosc: 207, lider: ?; , --- id: 0, wartosc: 498, lider: ?; , id: 1, wartosc: 416, lider: ?; , id: 2, wartosc: 48, lider: ?; , id: 3, wartosc: 50, lider: ?; , id: 4, wartosc: 207, lider: ?; , /// koniec wydruku Zadanie 8 ------------------------------------- Suma ID w ringu. Zliczam sumę ID w ringu, losuję wartości wierzchołków. /// kod load ./q3.so source symul_lib.tcl; # definuję ring set liczbaWierz 6 set sasiedzi(0) {5 1} set sasiedzi(1) {0 2} set sasiedzi(2) {1 3} set sasiedzi(3) {2 4} set sasiedzi(4) {3 5} set sasiedzi(5) {4 0} fiber create $liczbaWierz { set suma $id_los # losowanie wartości set licz [expr $liczbaWierz - 1] # zmienna licz set wynik "" wyslij 1 $suma # wysyłam w jedną stronę fiber yield; while {$run} { if {$wynik!="end" && $kom(0)!=""} { # warunek konieczny if {$licz>0} { # jeśli nadal mogę liczyć set k $kom(0) set suma [expr $id_los + $k] set licz [expr $licz - 1] wyslij 1 $suma } else { set wynik "end" } } fiber yield; } } Inicjalizacja; # wizualizacja proc wizualizacja {} { fiber_iterate {_puts "id: $id wartosc: $id_los, suma: $suma, licz: $licz, $wynik"} } fiber yield; runda; wizualizacja /// koniec kodu ///wydruk id: 0 wartosc: 751, suma: 751, licz: 5, id: 1 wartosc: 546, suma: 546, licz: 5, id: 2 wartosc: 484, suma: 484, licz: 5, id: 3 wartosc: 872, suma: 872, licz: 5, id: 4 wartosc: 218, suma: 218, licz: 5, id: 5 wartosc: 228, suma: 228, licz: 5, id: 0 wartosc: 751, suma: 979, licz: 4, id: 1 wartosc: 546, suma: 1297, licz: 4, id: 2 wartosc: 484, suma: 1030, licz: 4, id: 3 wartosc: 872, suma: 1356, licz: 4, id: 4 wartosc: 218, suma: 1090, licz: 4, id: 5 wartosc: 228, suma: 446, licz: 4, id: 0 wartosc: 751, suma: 1197, licz: 3, id: 1 wartosc: 546, suma: 1525, licz: 3, id: 2 wartosc: 484, suma: 1781, licz: 3, id: 3 wartosc: 872, suma: 1902, licz: 3, id: 4 wartosc: 218, suma: 1574, licz: 3, id: 5 wartosc: 228, suma: 1318, licz: 3, id: 0 wartosc: 751, suma: 2069, licz: 2, id: 1 wartosc: 546, suma: 1743, licz: 2, id: 2 wartosc: 484, suma: 2009, licz: 2, id: 3 wartosc: 872, suma: 2653, licz: 2, id: 4 wartosc: 218, suma: 2120, licz: 2, id: 5 wartosc: 228, suma: 1802, licz: 2, id: 0 wartosc: 751, suma: 2553, licz: 1, id: 1 wartosc: 546, suma: 2615, licz: 1, id: 2 wartosc: 484, suma: 2227, licz: 1, id: 3 wartosc: 872, suma: 2881, licz: 1, id: 4 wartosc: 218, suma: 2871, licz: 1, id: 5 wartosc: 228, suma: 2348, licz: 1, id: 0 wartosc: 751, suma: 3099, licz: 0, id: 1 wartosc: 546, suma: 3099, licz: 0, id: 2 wartosc: 484, suma: 3099, licz: 0, id: 3 wartosc: 872, suma: 3099, licz: 0, id: 4 wartosc: 218, suma: 3099, licz: 0, id: 5 wartosc: 228, suma: 3099, licz: 0, id: 0 wartosc: 751, suma: 3099, licz: 0, end id: 1 wartosc: 546, suma: 3099, licz: 0, end id: 2 wartosc: 484, suma: 3099, licz: 0, end id: 3 wartosc: 872, suma: 3099, licz: 0, end id: 4 wartosc: 218, suma: 3099, licz: 0, end id: 5 wartosc: 228, suma: 3099, licz: 0, end /// koniec wydruku