Rozproszone_moje_zad/TEMAT_A/Temat-A.txt

1175 lines
25 KiB
Plaintext

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sprawozdanie PUBLIC "sprawozdanie" "http://mhanckow.vm.wmi.amu.edu.pl:20002/zajecia/file-storage/view/sprawozdanie.dtd">
<sprawozdanie przedmiot="Algorytmy rozproszone" temat="A">
<imie_nazwisko>Jakub Adamski</imie_nazwisko>
<nr_indeksu>444341</nr_indeksu>
<liczba_pkt>10.5</liczba_pkt>
<zadanie nr="0.1" pkt="0.5"></zadanie>
<zadanie nr="0.2" pkt="0.5"></zadanie>
<zadanie nr="1" pkt="1"></zadanie>
<zadanie nr="1a" pkt="1"></zadanie>
<zadanie nr="1b" pkt="0.5"></zadanie>
<zadanie nr="2" pkt="1.5"></zadanie>
<zadanie nr="0.3" pkt="0.5"></zadanie>
<zadanie nr="3" pkt="2"></zadanie>
<zadanie nr="5" pkt="1"></zadanie>
<zadanie nr="5a" pkt="1"></zadanie>
<zadanie nr="8" pkt="1"></zadanie>
</sprawozdanie>
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} {
#jesli mamy komunikat
if {$kom(1)!=""} {
set x $kom(1);
if {$lider==1} {
#jest juz liderem
} elseif {$x>$id} {
#przesylam wartosc dalej
wyslij 0 $x;
} elseif {$x==0} {
#nie jest liderem
wyslij 0 $x;
set lider 0;
} elseif {$x==$id} {
#jest liderem
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 ?;
# wysyłam w jedną stronę
wyslij 0 $id;
# wysyłam w drugą stronę
wyslij 1 $id;
fiber yield;
while {$run} {
if {$kom(0)!="" && $kom(1)!=""} {
#jesli obydwa komunikaty nie są puste
set x ?;
if {$kom(0) > $kom(1)} {
#komunikat 1 jest wiekszy od drugiego
set x $kom(0);
if {$lider==1} {
#jest juz lider
} elseif {$x==0} {
#nie jest liderem
wyslij 1 0;
set lider 0;
} elseif {$x>$id} {
#przeslij dalej
wyslij 1 $x;
} elseif {$x==$id} {
#jest liderem
set lider 1;
wyslij 0 0;
wyslij 1 0;
} elseif {$x < $id} {
}
fiber yield;
} else {
#jesli komunikat 2 jest wiekszy od pierwszego
set x $kom(1);
if {$lider==1} {
#jest juz lider
} elseif {$x==0} {
#nie jest liderem
wyslij 0 $x;
set lider 0;
} elseif {$x>$id} {
#przeslij dalej
wyslij 0 $x;
} elseif {$x==$id} {
#jest liderem
set lider 1;
wyslij 0 0;
wyslij 1 0;
} elseif {$x < $id} {
}
fiber yield;
}
} elseif {$kom(0)!=""} {
#jesli tylko komunikat pierwszy nie jest pusty
set x $kom(0);
if {$lider==1} {
#jest juz lider
} elseif {$x==0} {
#nie jest liderem
wyslij 1 0;
set lider 0;
} elseif {$x>$id} {
#przeslij dalej
wyslij 1 $x;
} elseif {$x==$id} {
#jest liderem
set lider 1;
wyslij 0 0;
wyslij 1 0;
} elseif {$x < $id} {
}
fiber yield;
} else {
#w przeciwnym wypadku
set x $kom(1);
if {$lider==1} {
#jest juz lider
} elseif {$x==0} {
#nie jest liderem
wyslij 0 $x;
set lider 0;
} elseif {$x>$id} {
#przeslij dalej
wyslij 0 $x;
} elseif {$x==$id} {
#jest liderem
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.
Nie udało mi się zrobić tego zadania w 100%
/// kod
#inicjalizacja
load ./q3.so
source symul_lib.tcl;
#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;
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.
/// kod
#inicjalizacja
load ./q3.so
source symul_lib.tcl;
# drzewo ukorzenione
set liczbaWierz 7
set sasiedzi(0) {0 1 2}
set sasiedzi(1) {0 3 4}
set sasiedzi(2) {0 5}
set sasiedzi(3) {1}
set sasiedzi(4) {1 6}
set sasiedzi(5) {2}
set sasiedzi(6) {4}
#przydatny kod do obsługi bitów
set obslugaBitow {
proc bity x { # postac binarna liczby
usun0 [binary scan [binary format I $x] B* x; set x]
}
proc usun0 x { # usuwa zera poczatkowe z repr bin liczby
set x [string trimleft $x 0]
if {$x==""} {set x 0}
set x
}
proc porownanieC {cv cu} { # porownuje 2 kolory, zwraca indeks oraz 2 bity...
set dlcu [string len $cu]
set dlcv [string len $cv]
if {$dlcu<$dlcv} {
set cu "[string repeat 0 [expr {$dlcv-$dlcu}]]$cu"
}
if {$dlcu>$dlcv} {
set cv "[string repeat 0 [expr {$dlcu-$dlcv}]]$cv"
}
set dl [string len $cu]
iterate i $dl {
set i1 [expr {$dl-$i-1}]
# KONIECZNIE trzeba numerowac bity od prawej gdyz
# dopisuje sie 0 z lewej i wtedy indeksy by sie zmienialy!
set bu [string index $cu $i1]
set bv [string index $cv $i1]
if {$bu != $bv} {return "$i $bv $bu"}
}
return {-1 ? ?}
}
proc wyrownaj {L x} { # dodaje 0 z lewej do L-bitow
set dl [string len $x]
if {$dl>$L} {error "wyrownaj"}
return "[string repeat "0" [expr {$L-$dl}]]$x"
}
proc bin2dec x { # do 32-bitow
binary scan [binary form B* [wyrownaj 32 $x]] I y
set y
}
proc iterate {zm liIter kod} { # wygodna petla
upvar $zm i
for {set i 0} {$i<$liIter} {incr i} {
set e [catch {uplevel $kod} x]
if {$e!=0} {return -code $e $x}
}
}
}
fiber create $liczbaWierz {
#zmienne
set new 0
set wielkosc 50
#tworze kolory
set kolor_pierwszy [wyrownaj $wielkosc [bity $id_los]]
set kolor_drugi 0
set b 0
set por 0
set c 0
#wyslij kolor pierwszy do lisci
for {set i 1} {$i < $stopien} {incr i} {wyslij $i $kolor_pierwszy}
fiber yield;
#główna pętla
while {$run} {
if {$kom(0)!=""} {
#komunikat pierwszy nie jest pusty
#ustawiam jako kolor drugi i porównuję z pierwszym
set kolor_drugi $kom(0)
set por [porownanieC $kolor_pierwszy $kolor_drugi]
#wynik porównania
set c [lindex $por 1]
set b [lindex $por 0]
#ustawiam nowy kolor
set nowy [wyrownaj $wielkosc "[bity $b]$c"]
set kolor_pierwszy $nowy
#wysyłam do liści
set wielkosc [expr {int(ceil(log($wielkosc)/log(2)) + 1)}]
for {set i 1} {$i < $stopien} {incr i} {wyslij $i $kolor_pierwszy}
}
if { $id == 0 } {
#jeśli pierwszy wierzchołek, ustalam kolor, porównuję
set kolor_drugi [wyrownaj $wielkosc [bity 0]]
set por [porownanieC $kolor_pierwszy $kolor_drugi]
#wynik porównania
set c [lindex $por 1]
set b [lindex $por 0]
#ustalam nowy kolor
set nowy [wyrownaj $wielkosc "[bity $b]$c"]
set kolor_pierwszy $nowy
#wysyłam komunikat do liści
set wielkosc [expr {int(ceil(log($wielkosc)/log(2)) +1)}]
for {set i 1} {$i < $stopien} {incr i} {wyslij $i $kolor_pierwszy}
}
fiber yield;
}
}
fiber_iterate $obslugaBitow
Inicjalizacja;
proc wizualizacja {} {
fiber_iterate {_puts "id: $id, kolor: $kolor_pierwszy"}
}
fiber yield; runda; wizualizacja
/// koniec kodu
/// wydruk
id: 0, kolor: 00000000000000000000000000000000000000001100010010
id: 1, kolor: 00000000000000000000000000000000000000000010101001
id: 2, kolor: 00000000000000000000000000000000000000001101011010
id: 3, kolor: 00000000000000000000000000000000000000000100001010
id: 4, kolor: 00000000000000000000000000000000000000000010111010
id: 5, kolor: 00000000000000000000000000000000000000001010100000
id: 6, kolor: 00000000000000000000000000000000000000001111011000
id: 0, kolor: 0000011
id: 1, kolor: 00000000000000000000000000000000000000000000000001
id: 2, kolor: 00000000000000000000000000000000000000000000000111
id: 3, kolor: 00000000000000000000000000000000000000000000000000
id: 4, kolor: 00000000000000000000000000000000000000000000000000
id: 5, kolor: 00000000000000000000000000000000000000000000000010
id: 6, kolor: 00000000000000000000000000000000000000000000000010
id: 0, kolor: 0001
id: 1, kolor: 0000010
id: 2, kolor: 0000101
id: 3, kolor: 0000000
id: 4, kolor: 0000000
id: 5, kolor: 0000000
id: 6, kolor: 0000011
id: 0, kolor: 001
id: 1, kolor: 0000
id: 2, kolor: 0101
id: 3, kolor: 0010
id: 4, kolor: 0010
id: 5, kolor: 0000
id: 6, kolor: 0001
id: 0, kolor: 001
id: 1, kolor: 000
id: 2, kolor: 101
id: 3, kolor: 011
id: 4, kolor: 011
id: 5, kolor: 000
id: 6, kolor: 001
/// 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 rozwiązane w połowie.
/// 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 ?
#wysyłam id dalej
wyslij 0 "$id_los 0 0"
wyslij 1 "$id_los 0 0"
fiber yield
while {$run} {
#wykonuje algorytm ponizej
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 {
#to ma przekazac komunikaty
proc algorytm {m0 m1} {
#ustwiamy zmienne globalny
global id id_los stopien lider
if {$m0!=""} {
#jesli pierwsza wartość nie jest pusta
foreach {id0 i0 l0} $m0 break
#zwiększam i przekazuje
incr i0
wyslij 1 "$id0 $i0 0";
}
if {$m1!=""} {
#jesli druga zmienna nie jest pusta
foreach {id1 i1 l1} $m1 break
#zwiększam i ustawiam
incr i1
set i1 [expr {$i1+1}]
if {$m1==$id}{
#jest lider
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 5 -------------------------------------
Algorytm kolorujący wierzchołkowo, stałą liczbą kolorów, grafy stałego stopnia,
działający w czasie O(log^*n).
Algorytm
1) Najpierw generujemy kolor.
2) Powtarzamy w pętli:
2a) Pobranie koloru.
2b) Otrzymujemy kolor sąsiadującego wierzchoka.
2c) Skracamy długość koloru.
2d) Odczytujemy ilość zer i jedynek.
2e) Generujemy zera i jedynki na podstawie otrzymanego koloru.
Zadanie 5a -------------------------------------
Algortym z zadania 5 dla ringu.
/// kod
#inicjalizacja
load ./q3.so;
source symul_lib.tcl;
# ring
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 {
#zmienne
set wielkosc 50
set por 0
set new 0
#ustawiam kolory
set kolor_pierwszy [wyrownaj $wielkosc [bity $id_los]]
set kolor_drugi 0
set b 0
set c 0
#wysyłam kolor pierwszy
for {set i 1} {$i < $stopien} {incr i} {wyslij $i $kolor_pierwszy}
fiber yield;
#główna pętla
while {$run} {
if {$kom(0)!=""} {
#jesli komunikat pierwszy nie jest pusty
set kolor_drugi $kom(0)
} else {
#jesli jest pusty
set kolor_drugi [wyrownaj $wielkosc [bity 0]]
}
#porownanie koloru drugiego z pierwszym
set por [porownanieC $kolor_pierwszy $kolor_drugi]
#wynik porownania
set c [lindex $por 1]
set b [lindex $por 0]
#ustawiamy nowy kolor
set new [wyrownaj $wielkosc "[bity $b]$c"]
set kolor_pierwszy $new
#przesylamy dalej
set wielkosc [expr {int(ceil(log($wielkosc)/log(2)) + 1)}]
for {set i 1} {$i < $stopien} {incr i} {wyslij $i $kolor_pierwszy}
fiber yield;
}
}
#obsługa bitów
set obslugaBitow {
proc bity x { # postac binarna liczby
usun0 [binary scan [binary format I $x] B* x; set x]
}
proc usun0 x { # usuwa zera poczatkowe z repr bin liczby
set x [string trimleft $x 0]
if {$x==""} {set x 0}
set x
}
proc porownanieC {cv cu} { # porownuje 2 kolory, zwraca indeks oraz 2 bity...
set dlcu [string len $cu]
set dlcv [string len $cv]
if {$dlcu<$dlcv} {
set cu "[string repeat 0 [expr {$dlcv-$dlcu}]]$cu"
}
if {$dlcu>$dlcv} {
set cv "[string repeat 0 [expr {$dlcu-$dlcv}]]$cv"
}
set dl [string len $cu]
iterate i $dl {
set i1 [expr {$dl-$i-1}]
# KONIECZNIE trzeba numerowac bity od prawej gdyz
# dopisuje sie 0 z lewej i wtedy indeksy by sie zmienialy!
set bu [string index $cu $i1]
set bv [string index $cv $i1]
if {$bu != $bv} {return "$i $bv $bu"}
}
return {-1 ? ?}
}
proc wyrownaj {L x} { # dodaje 0 z lewej do L-bitow
set dl [string len $x]
if {$dl>$L} {error "wyrownaj"}
return "[string repeat "0" [expr {$L-$dl}]]$x"
}
proc bin2dec x { # do 32-bitow
binary scan [binary form B* [wyrownaj 32 $x]] I y
set y
}
proc iterate {zm liIter kod} { # wygodna petla
upvar $zm i
for {set i 0} {$i<$liIter} {incr i} {
set e [catch {uplevel $kod} x]
if {$e!=0} {return -code $e $x}
}
}
}
fiber_iterate $obslugaBitow
Inicjalizacja;
#wizualizaca
proc wizualizacja {} {
fiber_iterate {_puts "$id : $kolor_pierwszy"}
}
#wykonanie
fiber yield; runda; wizualizacja
/// koniec kodu
/// wydruk
0 : 00000000000000000000000000000000000000001101100101
1 : 00000000000000000000000000000000000000000100110011
2 : 00000000000000000000000000000000000000000111110111
3 : 00000000000000000000000000000000000000001110100110
4 : 00000000000000000000000000000000000000000000000110
0 : 00000000000000000000000000000000000000000000000001
1 : 00000000000000000000000000000000000000000000000011
2 : 00000000000000000000000000000000000000000000000101
3 : 00000000000000000000000000000000000000000000000000
4 : 00000000000000000000000000000000000000000000001010
0 : 0000001
1 : 0000011
2 : 0000010
3 : 0000000
4 : 0000011
0 : 0010
1 : 0011
2 : 0000
3 : 0010
4 : 0001
0 : 000
1 : 001
2 : 000
3 : 011
4 : 001
/// 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 {
# losowanie wartości
set suma $id_los
#zmienna okreslajaca czy moge liczyc
set licz [expr $liczbaWierz - 1]
set wynik ""
# wysyłam w jedną stronę
wyslij 1 $suma
fiber yield;
while {$run} {
if {$wynik!="end" && $kom(0)!=""} {
#jesli nie mam jeszcze wyniku i mam komunikat pierwszy
if {$licz>0} {
# jeśli nadal mogę liczyć
set k $kom(0)
#obliczam sume
set suma [expr $id_los + $k]
set licz [expr $licz - 1]
wyslij 1 $suma
} else {
#ustawiam wynik
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