• Nie Znaleziono Wyników

Wykład 7Grafy -wybrane algorytmy

N/A
N/A
Protected

Academic year: 2021

Share "Wykład 7Grafy -wybrane algorytmy"

Copied!
30
0
0

Pełen tekst

(1)

Wykład 7 Grafy - wybrane algorytmy

1. Podstawowe pojęcia

2. Reprezentacja grafów w komputerze 3. Podstawowe operacje na grafach 4. Wybrane algorytmy grafowe

4.1. Przechodzenie grafu "w głąb" (DFS – Depth First Search) 4.2. Przechodzenie grafu "wszerz" (BFS – Breadth First Search) 4.3. Badanie spójności grafu

(2)

1. Podstawowe pojęcia Grafem G jest para (V, E)

gdzie V - zbiór wierzchołków (węzłów), E - zbiór par (x, y) ε V2 krawędzi grafu

Rys. 7.1. Przykładowy graf nieskierowany

V = {A, B, C, D, E} E = {(A, B), (B, C), (B, D), (B, E), (C, D), (C, E)}

Zakładamy, że daną parę wierzchołków łączy co najwyżej jedna krawędź.

(3)

Jeżeli krawędziom grafu przypisano określony kierunek (początek, koniec), to mamy do czynienia z grafem skierowanym (zorientowanym, digrafem).

Rys. 7.2. Przykładowy graf skierowany

W niektórych przypadkach wygodnie jest korzystać z grafów, gdzie niektóre wierzchołki posiadają krawędzie skierowane do siebie. Przykład takiego grafu przedstawia rys.7.3.

(4)

Rys. 7.3. Przykład grafu skierowanego z pętlami

W niektórych zastosowaniach krawędziom grafu przypisuje się wartości – przeważnie

liczbowe. Mamy wtedy do czynienia z grafem ważonym, a jego formalna definicja zmienia się do postaci: (V, E, W) gdzie W jest zbiorem wartości przypisanych krawędziom.

Rys. 7.4. Przedstawia przykładowy graf skierowany ważony.

(5)

Rys. 7.4. Przykładowy graf skierowany z wagami

Graf, który zawiera "zdublowane" krawędzie, tzn. pary wierzchołków połączonych więcej niż jedną krawędzią to multigraf.

Graf nie zawierający pętli to graf prosty.

Graf prosty o n wierzchołkach posiada co najwyżej |E| = n*(n – 1)/2 krawędzi.

(6)

Stopień wierzchołka grafu to liczba krawędzi łączących ten wierzchołek z sąsiednimi.

Dla przykładu wierzchołek B grafu z rysunku 7.2 lub 7.4 ma stopień 4, a wierzchołek D tego samego grafu ma stopień 2.

Podgrafem (grafem częściowym) nazywa się taki podzbiór wierzchołków danego grafu wraz z krawędziami je łączącymi, który tworzy graf.

Ścieżką (ang. path) w grafie jest ciąg wierzchołków, w którym każdy następny (oprócz pierwszego) wraz ze swoim poprzednikiem sąsiadują ze sobą w grafie.

Ścieżka prosta to taka ścieżka, w której wszystkie wierzchołki i krawędzie są różne.

Cyklem jest taka ścieżka prosta, w której pierwszy i ostatni wierzchołek są takie same.

W grafie z rys. 7.1 ścieżki proste to przykładowo ścieżki zawierające wierzchołki A, B, D, C i A, B, C, E.

Cyklem w tym samym grafie są np. ścieżki B, C, D i B, D, C, E, B.

Długością ścieżki jest liczba krawędzi wchodzących w jej skład.

(7)

Graf jest spójny, jeżeli dla każdej pary wierzchołków istnieje w nim ścieżka, która je łączy.

Graf, który nie posiada tej własności składa się ze spójnych składowych, z których każda jest maksymalnym podgrafem spójnym.

Maksymalny podgraf spójny oznacza, że nie istnieje ścieżka prowadząca od dowolnego wierzchołka podgrafu do innego wierzchołka grafu nienależącego do danego podgrafu.

(8)

2. Reprezentacja grafów w komputerze

W procedurach komputerowych stosuje się trzy różne sposoby reprezentacji grafów:

– macierz sąsiedztwa lista sąsiedztwa macierz incydencji

Macierz sąsiedztwa (ang. Adjacency matrix) jest reprezentowana w pamięci komputera jako dwy-wymiarowa nxn tablica, gdzie n – liczba wierzchołków grafu (n = |V|).

Kolumny i wiersze macierzy odpowiadają poszczególnym wierzchołkom grafu, a element w wierszu w i kolumnie k odpowiada istnieniu albo nie istnieniu krawędzi (w, k), przy czym wiersz w odpowiada wierzchołkowi początkowemu, a kolumna k – wierzchołkowi końcowemu krawędzi.

Wartości elementów macierzy T[w, k] spełniają zależność:

E k w jezeli q

E k w jezeli k

w

T

) , ( 0

) , ( ] 0

, [

Zależnie od "rodzaju" grafu wartość q jest równa:

1 w przypadku grafu niezorientowanego bez wag na krawędziach,

1 lub -1 w grafach zorientowanych (1 – krawędź w – k, -1 – krawędź k – w gdzie w < k wartość wagi krawędzi w przypadku grafów ważonych.

W grafach bez pętli wszystkie elementy macierzy sąsiedztwa na przekątnej głównej mają wartość 0.

(9)

Przykład – graf niezorientowany:

0 1 2 3 4

0 0 1 0 1 0

1 1 0 1 0 1

2 0 1 0 1 0

3 1 0 1 0 1

4 0 1 0 1 0

Przykład – graf zorientowany

Macierz sąsiedztwa jest symetryczna względem przekątnej głównej

0 1 2 3 4

0 0 1 0 0 0

1 0 0 1 0 0

2 0 0 0 1 0

3 1 0 0 0 1

4 0 1 0 0 0

Macierz sąsiedztwa nie jest symetryczna

(10)

Lista sąsiedztwa (ang. Adjacency lists)

Jest to tablica n elementowa A, gdzie n jest równe liczbie wierzchołków.

Każdy element tej tablicy jest listą. Lista reprezentuje wierzchołek startowy.

Elementami tej listy są numery wierzchołków końcowych, czyli sąsiadów wierzchołka startowego, z którymi jest on połączony krawędzią.

Przykład – graf skierowany: Przykład – graf niozorientowany:

0 1

1 2

2 3

3 0 4

4 1

0 1 3

1 0 4 2

2 1 3

3 0 2 4

4 1 3

(11)

Macierz incydencji (ang. Incidence matrix)

jest macierzą A o wymiarze n x m, gdzie n oznacza liczbę wierzchołków grafu, a m liczbę jego krawędzi. Każdy wiersz tej macierzy odwzorowuje jeden wierzchołek grafu. Każda kolumna odwzorowuje jedną krawędź. Zawartość komórki A[i,j] określa powiązanie (incydencję) wierzchołka vi z krawędzią ej w sposób następujący:

- jeżeli graf jest skierowany

0 1 2 3 4 5

0 1 0 0 -1 0 0

1 -1 1 0 0 -1 0

2 0 -1 1 0 0 0

3 0 0 -1 1 0 1

4 0 0 0 0 1 -1

(12)

- jeżeli graf jest nieskierowany

0 1 2 3 4 5

0 1 0 0 1 0 0

1 1 1 0 0 1 0

2 0 1 1 0 0 0

3 0 0 1 1 0 1

4 0 0 0 0 1 1

(13)

3. Podstawowe operacje na grafach

Jeżeli mamy dane dwa grafy G1 = (V, E1) oraz G2 = (V, E2) to możemy wykonać na nich następujące operacje:

- Suma grafów G3 = G1 + G2 = (V, E1, E2) (rys.6.6)

-

Rys. 7.6. Suma grafów

0 1 0 0 0

1 0 1 0 0

G1 = 0 1 0 1 1

0 0 1 0 0

0 0 1 0 0

0 1 0 0 0

1 0 0 1 1

G2 = 0 0 0 0 1

0 1 0 0 0

0 1 1 0 0

0 1 0 0 0

1 0 1 1 1

G3 = 0 1 0 1 1

0 1 1 0 0

(14)

- Transpozycja grafu skierowanego (ang. digraph transposition) polega na takim przekształceniu grafu skierowanego, że jego krawędzie mają zwrot przeciwny.

Aby transponować graf zadany macierzą sąsiedztwa, wystarczy wykonać transpozycję tej macierzy.

0 1 2 3 4

0 0 0 0 1 0

1 1 0 0 0 1

2 0 1 0 0 0

3 0 0 1 0 0

4 0 0 0 1 0

0 1 2 3 4

0 0 1 0 0 0

1 0 0 1 0 0

2 0 0 0 1 0

3 1 0 0 0 1

4 0 1 0 0 0

(15)

Operacja transpozycji grafu zadanego listami sąsiedztwa jest bardziej skomplikowana.

Lista kroków algorytmu transpozycji ma w tym przypadku postać:

Wejście

n – liczba wierzchołków w grafie,

A – n elementowa tablica list sąsiedztwa grafu wyjściowego Wyjście:

AT – n elementowa tablica list sąsiedztwa grafu transponowanego Elementy pomocnicze:

v – wierzchołek, p, r – wskaźniki elementu listy Lista kroków:

K01: vc ← true ; licznik wierzchołków

K02: Dla i = 0,1,...,m-1 wykonuj K03...K07 ; przeglądamy kolejne kolumny

K03: Dla j = 0,1,...,n-1 wykonuj K04...K07 ; przeglądamy komórki w kolumnie i-tej

K04: Jeśli A[j,i] = 0, to następny obieg pętli K03 ; pomijamy wierzchołki nieincydentne z krawędzią i-tą K05: A[j,i] ← (-A[j,i]) ; zmieniamy kierunek krawędzi

K06 vc ← ¬ vc ; negujemy vc, co pozwoli wykryć dwa wierzchołki

K07: Jeśli vc = true, to następny obieg pętli K02 ; po dwóch wierzchołkach przechodzimy do następnej kolumny K08: Zakończ

(16)

Transpozycja grafu o zadanej macierzy incydencji:

w macierzy incydencji zamieniamy wszystkie wartości 1 na -1 i na odwrót. Otrzymamy w ten sposób graf, w którym krawędzie posiadają odwrotne zwroty. Macierz incydencji możemy przeglądać

kolumnami (kolumna reprezentuje krawędź). W kolumnie szukamy dwóch niezerowych wartości i, gdy je znajdziemy, zmieniamy ich znaki na przeciwne. Dalsze przeglądanie kolumny można już zaniechać.

Opis algorytmu transponowania grafu zadanego macierzą incydencji

Wejście

n – liczba wierzchołków w grafie, m – liczba krawędzi w grafie,

A – n x m elementowa macierz incydencji grafu wyjściowego Wyjście:

A – n x m elementowa macierz incydencji grafu transponowanego Elementy pomocnicze:

vc – zmienna logiczna używana do przerywania pętli po dwóch wierzchołkach i,j – indeksy kolumn i wierszy, i,j C

Lista kroków:

K01: vc ← true ; licznik wierzchołków

K02: Dla i = 0,1,...,m-1 wykonuj K03...K07 ; przeglądamy kolejne kolumny

K03: Dla j = 0,1,...,n-1 wykonuj K04...K07 ; przeglądamy komórki w kolumnie i-tej

K04: Jeśli A[j,i] = 0, to następny obieg pętli K03 ; pomijamy wierzchołki nieincydentne z krawędzią i-tą K05: A[j,i] ← (-A[j,i]) ; zmieniamy kierunek krawędzi

K06 vc ← ¬ vc ; negujemy vc, co pozwoli wykryć dwa wierzchołki

K07: Jeśli vc = true, to następny obieg pętli K02 ; po dwóch wierzchołkach przechodzimy do następnej kolumny K08: Zakończ

(17)

Kwadrat grafu (ang. square of graph) powstaje z grafu wyjściowego przez dodanie krawędzi pomiędzy wierzchołkami, które w grafie wyjściowym są połączone ścieżką o długości maksymalnie dwóch

krawędzi. Inaczej, w kwadracie grafu znajduje się krawędź v→u, jeśli w grafie wyjściowym istnieje krawędź v→u lub w grafie wyjściowym istnieje wierzchołek w oraz krawędzie v→w i w→u.

Graf wyjściowy Kwadrat grafu wyjściowego

Wierzchołek u staje się sąsiadem wierzchołka v w kwadracie grafu, jeśli:

- Wierzchołek u jest sąsiadem v w grafie wyjściowym.

- Wierzchołek u jest sąsiadem wierzchołka w, który z kolei sam jest sąsiadem wierzchołka v.

Wynika z tego, że nowymi sąsiadami wierzchołka v stają się wszyscy sąsiedzi jego sąsiadów.

(18)

Zasada tworzenia macierzy sąsiedztwa kwadratu grafu jest następująca:

Najpierw tworzymy macierz AK o tym samym stopniu co macierz sąsiedztwa A grafu wyjściowego.

Następnie przechodzimy przez kolejne wierzchołki v grafu. Dla każdego wierzchołka v kopiujemy wiersz A[v] do wiersza AK[v]. Teraz przeglądamy wiersz A[v] kolumnami u. Jeśli v ≠ u i A[v,u] = 1, to u jest

sąsiadem wierzchołka v i do wiersza AK[v] należy dołączyć wiersz A[u] (czyli sąsiedzi u staną się sąsiadami v).

Algorytm wyznaczania kwadratu grafu zadanego macierzą sąsiedztwa Wejście

n – liczba wierzchołków w grafie,

A – macierz sąsiedztwa grafu o wymiarach n x n.

Wyjście:

AK – macierz sąsiedztwa kwadratu grafu o wymiarach n x n.

Elementy pomocnicze:

i,j,k – indeksy, i,j,k C

(19)

K01: Utwórz macierz AK o wymiarach n x n

K02: Dla i = 0,1,...,n-1 wykonuj K03...K08 ; przechodzimy przez kolejne wiersze K03: Dla j = 0,1,...,n-1 wykonuj K04 ; przechodzimy przez kolejne kolumny

K04 AK[i,j] ← A[i,j] ; kopiujemy wiersz wierzchołka bieżącego

K05: Dla j = 0,1,...,n-1 wykonuj K06...K08 ; teraz przeglądamy sąsiadów wierzchołka bieżącego

K06: Jeśli (i = 1) (A[i,j] = 0), to następny obieg pętli K05 ; pomijamy wierzchołki na przekątnej i takie, do których nie prowadzi krawędź

K07: Dla k = 0,1,...,n-1 wykonuj K08

K08: Jeśli A[j,k] = 1, to AK[i,k] ← 1 ; dołączamy wiersz sąsiada do wiersza bieżącego wierzchołka

K09: Zakończ ; wynik w AK

Lista kroków:

(20)

4. Wybrane algorytmy grafowe

4. 1. Przechodzenie grafu "w głąb" (DFS – Depth First Search)

Przejście grafu polega na przechodzeniu przez wierzchołki, do których prowadzą ścieżki. Algorytm przejścia daje nam pewność, że żaden taki wierzchołek nie zostanie pominięty. Poważnym problemem jest fakt, że w grafach krawędzie mogą tworzyć cykle lub pętle, czyli prowadzić do tego samego

wierzchołka. Rozwiązaniem jest wprowadzenie dla każdego wierzchołka znacznika, który będzie

informował algorytm, czy wierzchołek był już odwiedzony. Dzięki temu nie będziemy w kółko krążyć po wierzchołkach tworzących cykl. Znacznik ten nazwiemy visited i będzie on miał wartość logiczną false, gdy wierzchołek nie był odwiedzony, a true, gdy algorytm odwiedził dany wierzchołek. Do

przechowywania znaczników visited można wykorzystać osobną tablicę o tylu elementach, ile mamy wierzchołków w grafie. Przed rozpoczęciem przejścia elementy tablicy visited powinny mieć wartość false.

Zasada działania DFS jest następująca:

Zaznaczamy bieżący wierzchołek jako odwiedzony. Przechodzimy do kolejnych sąsiadów wierzchołka bieżącego i wykonujemy dla nich tą samą operację (tzn. zaznaczamy je jako odwiedzone i przechodzimy do ich sąsiadów). Przechodzenie kończymy, gdy zostaną w ten sposób odwiedzone wszystkie dostępne wierzchołki.

(21)

Przejście rozpoczynamy od wierzchołka v0. Wierzchołek v0oznaczamy jako odwiedzony (kolor zielony) i przechodzimy do jego sąsiada v1

Wierzchołek v1oznaczamy jako odwiedzony. Ponieważ nie

ma on sąsiadów, to ta gałąź przejścia jest ślepa. Przechodzimy do kolejnego sąsiada wierzchołka v0, czyli do v5

(22)

Wierzchołek ten ma dwóch sąsiadów: v1i v2. Do v1nie przechodzimy, ponieważ jest oznaczony jako już odwiedzony.

v0v1v5v2v3v4

Algorytm rekurencyjny DFS dla macierzy sąsiedztwa: DFS(v) Wejście:

n – liczba wierzchołków,

v – numer wierzchołka startowego,

visited – n-elementowa tablica logiczna z informacją o odwiedzonych wierzchołkach A – macierz sąsiedztwa o rozmiarze n x n

Wyjście:

Lista odwiedzonych wierzchołków grafu.

Elementy pomocnicze:

i – indeks

(23)

K01: visited[v] ← true ; odwiedź wierzchołek

K02: Przetwórz wierzchołek v ; przetwarzanie wstępne

K03: Dla i = 0,1,...,n-1:

wykonaj: Jeśli (A[v][i] = 1) (visited[i] = false), to DFS(i)

; odwiedź algorytmem DFS każdego nieodwiedzonego sąsiada

K04: Przetwórz wierzchołek v ; przetwarzanie końcowe

K05: Zakończ

(24)

4. 2. Przechodzenie grafu "wszerz" (BFS – Breadth First Search) Algorytm przechodzenia wszerz (ang. breadth-first search, BFS):

Zaczynamy odwiedzanie od wierzchołka startowego. Następnie odwiedzamy wszystkich jego sąsiadów. Dalej odwiedzamy wszystkich nieodwiedzonych jeszcze sąsiadów sąsiadów.

Itd.

Tutaj również wykorzystujemy dodatkowy parametr - znacznik visited, aby uniknąć

zapętlenia w przypadku napotkania cyklu. Określa on stan odwiedzin wierzchołka. Wartość false ma wierzchołek jeszcze nie odwiedzony, a wartość true – wierzchołek już odwiedzony.

Znaczniki te znajdują się w tablicy logicznej visited[], która posiada tyle elementów, ile jest wierzchołków w grafie. Element visited[i] odnosi się do wierzchołka grafu o numerze i.

Działanie tego algorytmu ilustruje procedura przejścia przykładowego grafu.

(25)

Rozpoczynamy od wierzchołka startowego.

odwiedzamy wszystkich jego sąsiadów pierwszego poziomu.

Sąsiadów pierwszego poziomu oznaczamy jako odwiedzonych i odwiedzamy wszystkich ich sąsiadów, którzy jeszcze nie byli

odwiedzeni. . . .

Sąsiada piątego poziomu oznaczamy jako odwiedzonego i odwiedzamy wszystkich jego sąsiadów, którzy jeszcze nie byli odwiedzeni. Do

odwiedzenia pozostały dwa ostatnie wierzchołki.

(26)

Oznaczamy jako odwiedzonych dwóch sąsiadów stopnia 6. W grafie nie ma już nieodwiedzonych wierzchołków. Przejście zostało zakończone.

Taki sposób odwiedzania wierzchołków wymaga użycia kolejki.

Na koniec kolejki wstawiamy wierzchołek startowy. Wewnątrz pętli wierzchołek ten zostanie odczytany z początku kolejki, po czym algorytm umieści w niej wszystkich nieodwiedzonych sąsiadów.

W kolejnych obiegach pętli sąsiedzi ci (sąsiedzi poziomu 1) zostaną odczytani z początku kolejki, a na jej koniec zostaną wstawieni sąsiedzi poziomu 2.

Gdy wszyscy sąsiedzi poziomu 1 zostaną przetworzeni, w kolejce pozostaną tylko sąsiedzi poziomu 2.

Teraz oni będą odczytywani z początku kolejki, a na jej koniec trafią sąsiedzi poziomu 3.

Całość będzie się powtarzała w pętli dotąd, aż algorytm przetworzy wszystkie dostępne wierzchołki w grafie.

(27)

Algorytm BFS dla macierzy sąsiedztwa

Wejście:

n – liczba wierzchołków,

v – numer wierzchołka startowego,

visited – wyzerowana tablica logiczna n elementowa z informacją o odwiedzonych wierzchołkach A – macierz sąsiedztwa o rozmiarze n x n

Wyjście:

Lista odwiedzonych wierzchołków grafu.

Elementy pomocnicze:

Q – kolejka i – indeks Lista kroków:

K01: Q.push(v) ; w kolejce umieszczamy numer wierzchołka startowego

K02: visited[v] ← true

K03: Dopóki Q.empty() = false, wykonuj K04...K10 ; tutaj jest pętla główna algorytmu BFS

K04: v ← Q.front() ; odczytujemy z kolejki numer wierzchołka

K05: Q.pop() ; odczytany numer usuwamy z kolejki

K06: Przetwórz wierzchołek v ; tutaj wykonujemy operacje na wierzchołku v

K07: Dla i = 0,1,...,n-1: wykonuj K08...K10 ; przeglądamy wszystkich sąsiadów v K08: Jeśli (A[v][i] = 0) (visited[i] = true), to następny obieg pętli K07 ; szukamy nieodwiedzonego sąsiada

K09: Q.push(i) ; numer sąsiada umieszczamy w kolejce

K10: visited[i] ← true ; i oznaczamy go jako odwiedzonego

K11: Zakończ

(28)

4.3. Badanie spójności grafu

Graf jest spójny (ang. connected graph), jeśli dla każdej pary jego wierzchołków istnieje ścieżka, które je ze sobą łączy.

W przeciwnym razie graf jest niespójny (ang. disconnected graph).

Spójność grafu (ang. graph connectivity) określa, czy jest on spójny, czy nie.

Algorytm badania spójności grafu nieskierowanego Wejście

n – liczba wierzchołków w grafie,

graf – zadany w dowolnie wybrany sposób, algorytm tego nie precyzuje Wyjście:

true – graf jest spójny false – graf nie jest spójny Elementy pomocnicze:

visited – n elementowa tablica logiczna odwiedzin wierzchołków vc – licznik odwiedzonych wierzchołków,

S – stos wierzchołków

v,u – numery wierzchołków w grafie.

(29)

K01: Utwórz tablicę visited o n elementach K02: Tablicę visited wypełnij wartościami false K03: Utwórz pusty stos S

K04: vc ← 0 ; inicjujemy licznik odwiedzonych wierzchołków

K05: S.push(0) ; przejście DFS rozpoczniemy od wierzchołka 0

K06: visited[0] ← true ; wierzchołek oznaczamy jako odwiedzony

K07: Dopóki S.empty() = false, wykonuj K08...K14 ; przechodzimy przez graf

K08: v ← S.top() ; pobieramy wierzchołek ze stosu

K09: S.pop() ; pobrany wierzchołek usuwamy ze stosu

K10: vc ← vc + 1 ; zwiększamy licznik odwiedzonych wierzchołków

K11: Dla każdego sąsiada u wierzchołka v, wykonuj K12..K14. ; przeglądamy kolejnych sąsiadów

K12: Jeśli visited[u] = true, to następny obieg pętli K11 ; szukamy sąsiadów jeszcze nieodwiedzonych

K13: visited[u] ← true ; oznaczamy sąsiada jako odwiedzonego

K14: S.push(u) ; i umieszczamy go na stosie

K15: Jeśli vc = n, to zakończ z wynikiem true ; wszystkie wierzchołki odwiedzone, graf jest spójny

K16: Zakończ z wynikiem false ; graf nie jest spójny

Lista kroków:

(30)

Graf spójny Graf niespójny

Badanie spójności grafu skierowanego

Graf skierowany jest spójny, jeśli po zastąpieniu wszystkich jego krawędzi skierowanych krawędziami nieskierowanymi, otrzymamy nieskierowany graf spójny.

Badanie spójności grafu skierowanego sprowadza się do:

-Do przekształcenia grafu skierowanego w graf nieskierowany.

- Badania spójności grafu nieskierowanego zgodnie z opisanym wyżej algorytmem.

Badamy spójność skonstruowanego grafu nieskierowanego za pomocą opisanego wcześniej algorytmu.

Na podstawie: http://eduinf.waw.pl/inf/alg/001_search/0122.php

oraz: Ross K.A. Ross, Ch. R.B. Wright – Matematyka dyskretna. Wyd. PWN, Warszawa, 1999

Cytaty

Powiązane dokumenty

Niemiecki samochód jechał, wywalili plecaki, to wszystko, gdzieś tam pojechali, to jeszcze plecaki się wzięło, te buty chociaż były, miało się.. A tak, no to konia

Wyznaczenie regu³ zestawiania maszyn i urz¹dzeñ w zestawach œcianowych (algorytm M2).... Wyznaczenie charakterystyk robót prowadzonych w przesz³oœci (algorytm

ogromnych problemów w obsza- rze finansów publicznych nie będą w stanie ratować wszystkich pod- miotów i skupią się jedynie na tych, których istnienie okazało się nie- zbędne

1/2 Francja Grecja Albania Egipt Cypr Hiszpania Belgia Dania. 1/3 Francja Albania Grecja Egipt Cypr Hiszpania

G= {V, E}, gdzie V jest zbiorem wierzchołków (węzłów) i E zbiorem krawędzi BIALY – kolor nadawany nie odwiedzonym wierzchołkom.. SZARY – kolor nadawany

Interpretowane – kod źródłowy jest tłumaczony na bieżąco i wykonywany przez dodatkowy program zwany interpreterem (środowiskiem uruchomieniowym). Przykładem

Inną metodą przedstawienia algorytmu jest użycie zapisu za pomocą pseudo-języka programowania. Zaletą tego podejścia jest bardzo łatwa implementacja algorytmu za pomocą

• Netica (copyrighted, komercyjny, darmowa wersja z ograniczeniami, Windows):