ŘEŠENÍ KOLIZÍ FREKVENCE SÍTĚ VYSÍLAČŮ

Transkript

ŘEŠENÍ KOLIZÍ FREKVENCE SÍTĚ VYSÍLAČŮ
Obrázky a loga
mají být vektorové
nebo aspoň v dostatečném
rozlišení...
ŘEŠENÍ KOLIZÍ FREKVENCE SÍTĚ
VYSÍLAČŮ
Semestrální práce z předmětu KIV/PC
Alena Švelchová (A12B0526P)
3.1.2015
Obsah
1 Zadání
1
2 Analýza úlohy
2.1 Interpretace dat . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2 Graf kolizí . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3 Obarvování grafu . . . . . . . . . . . . . . . . . . . . . . . . .
2
2
3
4
3 Popis implementace
5
3.1 Funkce main() . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.2 Knihovna input.h . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.2.1 int freq in(FILE *input, int **p) . . . . . . . . . . . . 6
3.2.2 int radius in(FILE *input) . . . . . . . . . . . . . . . . 6
3.2.3 int trans in(FILE *input, struct trans **last, int r, int f) 6
3.3 Knihovna trans.h . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.3.1 Struktury . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.3.2 void add trans(struct trans **list, int id, float x, float y,
int f) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.3.3 void new neigh(struct trans *list, int r) . . . . . . . . . 7
3.3.4 Uvolňování paměti . . . . . . . . . . . . . . . . . . . . 7
3.4 Knihovna color.h . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.4.1 void coloring(struct trans *last, int freq) . . . . . . . . 7
3.4.2 void color print(struct trans *last, int *pole) . . . . . . 8
3.4.3 void error(int i) . . . . . . . . . . . . . . . . . . . . . . 8
4 Uživatleská přírůčka
4.1 Přeložení aplikace . . . .
4.1.1 Pro OS Windows
4.1.2 ProOS Linux . .
4.2 Ovládání aplikace . . . .
4.3 Výstup aplikace . . . . .
5 Závěr
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
9
9
9
9
9
9
10
1
Zadání
Naprogramujte v ANSI C přenositelnou konzolovou aplikaci, která jako vstup
načte z parametru na příkazové řádce název textového souboru, který obsahuje informaci o pozici vysílačů na mapě a přidělí těmto vysílačům frekvenci,
tak aby jeho signál nekolidoval s vysílači v blízkém okolí. Dostupné frekvence
a radius vysílání jsou součásti vstupního souboru.
Program se bude spouštět příkazem freq.exe <soubor>. Symbol <soubor>
zastupuje jméno vstupního souboru.
Výsledkem práce programu bude výpis do konzole se seznamem přidělených frekvencí každému vysílači ze vstupního souboru. V případě chyby nebo
neřešitelné situace skončí program výpisem příslušné chybové hlášky
Pokud nebude funkce spuštěna právě s jedním argumentem, vypište chybové hlášení a stručný návod k použití programu v angličtině podle běžných
zvyklostí (viz např. ukázková semestrální práce na webu předmětu Programování v jazyce C). Vstupem programu je pouze argument na příkazové
řádce – interakce s uživatelem pomocí klávesnice či myši v průběhu práce
programu se neočekává.
Kompletní zadání, včetně detailních požadavků a specifikací se nacházejí
v souboru dostupném na adrese :
http : //www.kiv.zcu.cz/studies/predmety/pc/doc/work/sw2014 − 01.pdf
1
2
2.1
Analýza úlohy
Interpretace dat
Vstupní data, získaná ze vstupního souboru je potřeba načíst a uložit do paměti ve formátu vhodném pro další využití. Vstupní soubor obsahuje seznam
frekvencí, poloměr vysílání a poté vysílače a jejich pozici. Přesný formát
vstupního souboru je vidět na obrázku č.1.
Frekvence je potřeba uložit tak, aby k nim byl snadný přístup, protože
právě je budeme přiřazovat vysílačům. Ideální způsob je pole. Bohužel nevíme
předem kolik frekvencí budeme mít k dispozici, takže je potřeba nastavit
velikost pole na dostatečnou velikost a ošetřit možnost, že nastane situace, že
alokovat
spíš:
bude nedostatečně velké, a nebo pole allokovat dynamicky, tj. napřed spočítat
nebude dostatečně počet frekvencí, vytvořit pole a až poté uložit jednotlivé frekvence. Dalším
způsobem je vytvoření spojového seznamu, ale musíme počítat s tím, že bude
velké
nutné procházet celý seznam, abychom se dostali ke konkrétní hodnotě, což
bude, zvláště při větším počtu frekvencí náročnější než práce s polem.
Radius neboli poloměr signálu je nejednodušší uložit do globální proměnné, neboť se ní bude pracovat v dalších částech programu.
Proč vkládáte text jako obrázek?
Navíc v malém rozlišení...
Obrázek 1: Příklad vstupního souboru
zvýrazňovat
K jednotlivým vysílačům bude potřeba snadný přístup jako k frekvencím
a stejně jako ony by se daly interpretovat pomocí pole nebo spojového seznamu. Kromě id a souřadnic vysílače, které získáme ze vstupního souboru
budou k jednotlivým vysílačům patřit další proměnné. Pole by pro takové
2
množství informací muselo být hodně obsáhlé a nebo dvou nebo více rozměrné a opět nastane problém s jeho allokací, neboť předem neznáme počet
vysílačů. Za předpokladu, že budou vysílače procházeny postupně a není potřeba je vyhledávat dle indexu, je ideální je ukládat do spojového seznamu
pomocí struktur, které obsáhnou všechny potřebné proměnné.
2.2
Graf kolizí
K řešení úlohy je potřeba sestavit graf kolizí. Platí pro něj, že každý vysílač
je reprezentován unikátním vrcholem, každý vrchol nese informaci o přiřazené frekvenci a jednotlivé vrcholy propojuje hrana pouze tehdy, když mezi
nimi může docházet ke kolizi signálu. Tato kolize signálu se zjistí pomocí
euklidovské vzdálenosti dvou bodů, která v tomto případě nesmí být menší
\times místo "x" než 2x poloměr signálu.
Výpočet kolize vysílačů A a B s poloměrem vysílání R. Zvýraznit!
q
(a1 + b1 )2 + (a2 + b2 )2 > 2R
(a1 - b1)^2 + (a2 - b2) ^ 2
!!!
Zjištěné kolize vysílačů a výsledný graf kolizí, lze interpretovat mnoha
způsoby jedním z nich je vytvářet graf jako seznam hran, tato implementace
vyžaduje ještě seznam grafů vytvořených z množiny vysílačů. Obdobně by
bylo možné použít pole a jako seznzam grafů využít pole ukazatelů na tyto
pole. Další možností,je hrany nebo přímo konkrétní sousedy přiřazovat rovnou do proměné patříci konkrétnímu vysílači.
spíš struktury
Chápu, že se Vám to nechtělo
překreslovat vektorově,
ale mohla jste udělat
screenshot alespoň
v pořádném rozlišení...
Po vytištění by tohle
vypadalo hrozně...
Obrázek 2: Vytvoření grafu kolizí na základě překrytí signálu znázorněného
modrými kruhy. (Zdroj: Zadání SP)
3
2.3
Obarvování grafu
Po vytvoření grafu kolizí, musíme nalézt vhodný algoritmus na obarvování
grafů. Samotné obarvování je přiřazení vrcholu barvy takové, kterou není
obarven ani jeden z jeho sousedů. Naším cílem je použít co nejméně barev,
volíme tedy vždy nejnižší možnou barvu. Největším problémem je vyhodnocení v jakém pořadí budou vrcholy grafu barveny.
Jednou z možností je obarvování podle dostupných barev, kdy pořadí
obarvování dosud neobarveních vrcholů závisí na tom, kolika barvami jsou
obarveni jeich sousedé. Přednost má vrchol s nejméně možnostmi, čili pokud
máme k dispozici pět barev a sousedi vrcholu A již jsou obarveni na dvě
z nich a sousedi vrcholu B čtyřmi, pak má předost vrchol B. Pokud narazíme
na případ, že má stejný počet možností více vrcholů, volíme ten, který má
nejvíce neobarvených sousedů. Pokud i nadále máme více kandidátů, můžeme
vybrat libovolný z nich.
Daší možností, je obarvování podle nazávislých množin. Z grafu vybereme
maximální množinu vzájemně nezávislých prvků a ty obarvíme na nejmenší
barvu. Ve zbylém podgrafu hledáme opět největší nezávisou podmnožinu a
tu obarvíme na následující barvu. Takto postupujeme dokud není celý graf
obarvený.
Další algoritmus provádí spojování nesousedních uzlů. Provádíme ho tak,
že ze dvou nesousedních uzlů A a B vytvoříme nový uzel AB, který spojíme
hranami se všemi sousedy uzlů A a B. Takto pokračujeme, dokud je možné
nějaké dva uzle propojit. Výsledný úplný graf pak nelze obarvit jinak, než
že každému jeho uzlu přiřadíme jinou barvu. Následně spojené uzly opět
rozpojíme na půlovdní uzly, kterým zůstane barva přidělená uzlu z úplného
grafu.
Existují i další algoritmy na barvení, nebo vylepšování výše uvedených
možností, ale tyto reprezentují nejčastější přístupy k problematice. Pro první
uvedený algoritmus, je třeba mít u každého vrcholu možnost přístupu k jeho
sousedům, kvůli zjišťování jejich počtu a použité barvy, aby bylo možné
správně určit pořadí. Naproti tomu druhý a třetí algoritmus vyžadují hlavně
správně zvolit reprezentaci vrcholů a jejich hran.
4
3
Popis implementace
Poté co funkce otevře vstupní soubor, načítá z něho jednotlivé řádky a ukládá
je do proměných. První část vstupního souboru jsou frekvence a ty ukládá
do pole frekvencí. Protože jejich počet nezná předem musí pole allokovat
dynmicky. Druhá část vstupního souboru je poloměr signálu vysílání, kteoru
uloží do globální proměné. Poslední a nejobsáhlejší částí vstupního souboru
jsou vysílače a jejich umístění. Ty ukládá pomocí struktrur do spojového
seznamu.
V okamžiku kdy načítá a ukládá nový vysílač, porovná jeho vzdálenost se
všemi doposud načtenými a pokud neplatí výše uvedená nerovnice (viz 2.2),
přidá do seznamu sousedů nového vysílače vysílač se kterým dochází ke kolizi
zvýraznit
a naopak. Každý vysílač, reprezentovaný strukturou trans, tak obsahuje seznam vysílačů se kterými sousedí. Zároveň s tím do proměnné zaznamenává
nárůst počtu sousedů, který později slouží k indikaci počtu neobarvených
sousedů.
Když je zjištěno, které vysílače mají mezi sebou hrany, mohu přistoupit
k přiřazování
frekvencí. Rozhodla jsem se použít první z algoritmů popsanerovnice
ných výše (viz 2.3). Všechny vysílače mají proměnnou index frekvence (in- zvýraznit
dex do pole kde jsou frekvence uloženy), který je defaultně nastavený na -1.
K tomu abych vysílače (vrcholy) mohla efektivně porcházet potřebuji zásobník, kam ukládám neobarvené vrcholy, které mají při obarvování přednost,
potože jsou sousedy již zpracovaného vysílače a patří do stejného podgrafu.
Obarvovací funkce projde seznam vrcholů a první neobarvený vrchol obarví
na nejnižší možnou hodnotu, která nekoliduje se sousedními vysílači. Poté
všechny jeho sousedy uloží do zásobníku.
Pokud zásobník není prázdný, vybere další vrchol z něj a opět ho obarví a
uloží jeho sousedy do zásobníku. Tento výběr provádí na základě dvou kritérií - podle počtu dostupných frekvencí a podle počtu neobarvených sousedů.
Když je zásobník prázdný čili je celý podgraf obarvený, vezme další neobarvený vrchol ze seznamu vysílačů a začne tak obarvovat další podgraf grafu
kolizí.
Samotné obarvoání řeší pomocí pole dostupných frekvencí, pole odpovídá
počtu dostupných frekvencí a při inicializaci je nastaveno na samé nuly. Vyhodnoty
sílači bude do proměné, kde je index frekvence, uložen místo
-1 index prvního psát v TeXu
výskytu 0 v poli dostupných vysílačů. Součástí funkce je zakázat sousedům matematicky $-1$
vrcholu použít stejnou frekenci. Když je frekvence přiřazena, zakáže se pou- nebo jinak zvýražít sousedům tak, že se hodnota příslušného indexu v jejich poli dostupných znit
frekvencí přepíše na 1 a zárověň se sníží počet jejich neobarvených sousedů.
Na závěr funkce vypíše naobrazovku sezam vysílačů a jejich frekvenci.
5
3.1
Zvýraznit
Funkce main()
Funkce main() je řídící část programu, která deklaruje globální proměné a
volá všechny další potřebné funkce. Mezi globální proměné programu patří
poloměr signálu (int r), počet frekvencí (int count f), počet vysílačů (int
count t), pole frekvencí (int *fr) a první položka seznmamu vysílačů (struct
trans *last). Napřed volá tři funkce z knihovny input.h - freq in(), radius in()
a trans in(). Ty načítají vstupní soubor a ukládají počáteční hodnoty. Poté
přijde nařadu samotné obarvování pomocí funkce coloring(), výpis výsledku
na konzoli má na svědomí funkce color print(). Na konci funkce main uvolňuje
funkcemi free() a free list() allokovanou paměť.
3.2
3.2.1
Knihovna input.h
int freq in(FILE *input, int **p)
Vstupními parametry jsou vstupní soubor a pole frekvencí. Pomocí funkce
fscanf() načítá vstupní soubor. Funkce počítá počet frekvencí, čili počet řádek kde jsou čísla a ne text a dle toho allokuje pole frekvencí. Pomocí funkce
rewind() se vrátí na začátek a vstupní soubor prochází znovu. Tetokrát načtené frekvence ukládá do allokovaného pole. Funkce vrací počet frekcencí.
3.2.2
int radius in(FILE *input)
Tato funkce ze vstupního souboru načte, uloží a vrací hodnotu poloměru
signálu. Využívá funkci fscanf().
3.2.3
int trans in(FILE *input, struct trans **last, int r, int f )
Poslední krok načítání dat ze vstupního souboru načítá samotné vysílače.
Jednotlivé vysílače jsou zastoupeny strukturou trans (viz 3.3.1). Struktura je
definovaná v knihovně trans.h. Nový vysílač po načtení funkcí scanf() ukládá
pomocí funkce add trans(), která vysílač přidá na konec seznamu vysílačů.
Zárověň nový vysílač porovná pomocí funkce new neigh() s již načtenými
vysílači, aby zjistila k jakým dochází kolizím. Funkce vrací počet načtených
vysílačů.
6
3.3
3.3.1
Knihovna trans.h
Struktury
Ve funkci jsou definovány dvě struktury -trans a neigh Struktura trans (vysílač) obsahuje id vysílače, jeho souřadnice, index přiřazené frekvence, pole
dostuoných frekvencí, počet sousedů a odkaz na seznam sousedů a odkaz
na následující vysílač v seznamu
Struktura neigh (soused) obsahuje odkaz na následujícího souseda v seznamu a na vysílač, se kterým má vysílač, kterému patří tento seznam sousedů, kolizi.
3.3.2
void add trans(struct trans **list, int id, float x, float y,
int f )
Funkce přidává na konec seznamu nejnovější načtený vysílač. Čísla id, x a
y přiřazuje položkám id,x a y nově vzniklé struktury a číslo f je velikost
pole availableFreq. Nová struktura má hodnotu count n nastavenou na 0
a freq index nastavenou na -1, a odkaz na sousedy a následující položkou
na NULL.
3.3.3
void new neigh(struct trans *list, int r)
Když přibyde nový vysílač do seznamu tato funkce počítá zda dochází ke kolizi s ostatními vysílači. V případě že k nějaké kolizi dojde, zavolá 2x funkci
add neigh() s opačnými parametry. Ta přiřazuje souseda do seznamu sousedů, takže na první zavolání přidá novému vysílači do seznamu sousedů
toho s kým má kolizi a napodruhé tomu s kým má kolizi do seznamu přiřadí
nový vysílač, a zároveň navýší proměnou count n (počet sousedů).
3.3.4
Uvolňování paměti
Tato knihovna ještě obsahuje funkce na uvolnění paměti seznamu vysílačů a
sousedů -free list() a free n().
3.4
3.4.1
Knihovna color.h
void coloring(struct trans *last, int freq)
Na začátku mají všechny vysílače index frekvence (index do pole kde jsou
frekvence uloženy) nastavený na -1. K tomu aby sousedící vysílače (vrcholy)
mohla funkce efektivně porcházet vytváří funkce frontu *front, kam ukládá
neobarvené vrcholy, které mají při obarvování přednost, potože jsou sousedy
7
již zpracovaného vysílače a jsou tedy součástí stejného podgrafu. Začne procházet seznam vrcholů. Když má vybraný vrchol freq index -1 zavolá funkci
color neigh(). Tato funkce projde pole dostupných frekvencí vrcholu (availableFreq) a najde nejnižší index který obsahuje 0. Poté všem vysílačům
ze seznamu sousedů tohoto vrcholu (pokud nějací jsou) hodnotu v poli dostupných frekvencí na tomto indexu změní na 1 a sníží hodnoctu count n.
Pokud má vysílač nějaké sousedy, přidá je funkcí frontadd() do fronty
(*front). Funkce zkontroluje jestli už vysílač v seznamu není a pokud ne, tak
ho přidá na konec seznamu.
Pokud seznam není prázdný vezme další vysílač k obarvování z něj pomocí funkce next colored().Ta provádí výběr na základě počtu nedostupných
frekvencí, tedy počtu jedniček v poli dostupných frekvencí. Přednost dostane
ten vrchol, který má v tomto poli nejvíce jedniček. Pokud má maxiální počet
jedniček více vrcholů, vezme ten který má větší count n - více neobarvených sousedů. Pokud i nadále zůstává více kandidátů obarvuje ten, který
byl v seznamu první. Funkce delete() odebere tento vrchol z fronty čekajících. Pokud seznam je prázdný vezme další neobarvený ze seznamu vysílačů
a začne tak obarvovat další podgraf. Takto seznam prochází dokud nejsou
obarvené všechny vrcholy.
3.4.2
void color print(struct trans *last, int *pole)
Prochází seznam vysílačů a vypíše do konzole id a frekvenci vysílače, kterou
získá z pole frekvencí pomocí freq index vysílače. Pokud narazí na vysílač,
který má tuto hodnotu -1 zavolá funkci error() s paramtertem 3, která ukončí
běh programu zdůvodu nedostatku frevencí.
3.4.3
void error(int i)
Tato funkce ošetřuje možné chybové stavy. Program je spustitelný právě s jedním argumentem a to vstupním textovým souborem, pokudt to tak není vypíše funkce ERR1: Missing argument! a ukončí se s návratovou hodnotou 1.
Další chyba může nastat při nedostatku paměti při allokování proměných
(ERR2: Out of memory!, 2). Pokud nastane situace kdy funkce není schopná
přiřadit barvu všem vrcholům, navrátí po ukončení hodnotu 3 s hláškou
ERR3: Non-existent solution!
8
4
4.1
Uživatleská přírůčka
Přeložení aplikace
Před použitím musíte aplikaci přeložit. Pro překlad potřebujete mít nainstalovaný překladač podporující ANSI C jako je například gcc (pro Windows
i Linux). Pokud již máte pžekladač nainstalovaný, překlad aplikace spustíte
tak, že ve složce se zdrojovými soubory otevřete konzoli a zadáte následující
příkaz.
4.1.1
Pro OS Windows
make -f makefile.win
4.1.2
ProOS Linux
make
4.2
Ovládání aplikace
Přeloženou aplikaci již můžeme spustit, její název je freq.exe. Aplikaci je
předáván vstupní textový soubor jako parametr při spuštění. Jiný způsob
ovládání aplikace není implementován. Spuštění aplikace s parametry musí
mít tvar graph.exe <soubor>. Kde <soubor> zastuuje název vstupního souboru (např. vyslilace-25.txt).
4.3
Výstup aplikace
Při správném zadání vstupních argumentů a dostatku paměti nám aplikace
do konzole vypíše seznam vysílačů s přiřazenou frekvencí.
Pokud zadané argumenty nejsou správné, nebo program v průběhu narazí na chybu či dojde paměť zařízení, vypíše aplikace chybovou hlášku v
angličtině a ukončí svůj běh. Chybové hlášení obsahuje popis příčiny vzniku
problému.
měření výkonu
9
5
Závěr
S jayzkem C jsem doposud neměla velké zkušenosti. Toto je druhá větší aplikace, kterou jsem v něm vytvářela a prakticky se při tom učila jak jazyk
funguje. Jsem si jistá, že v samotná aplikace není bez chybičky, například
algoritmus obarvování grafu jde nejspíše implementovat efektivněji a s měnšími nároky na paměť, navíc by bylo zajímavé vyzkoušet si i funkčonst a
náročnost implementace ostatních algoritmů uvedených v analytické části a
moci je mezi sebou porovnat.
Během práce jsem se nejvíce potýkala s nedostatkem znalosti jazyka C
a programátorské praxe, zvláště v oblasti implementace struktur a funkcí
naplánovaných a vymyšlených během analýzy problému, nezřídka jsem až
po několikahodinové práce zjistila, že musím problém zanalyzovat znovu a
zkusit to jinou cestou.
Velký praktický přínos této práce je pro mě psaní samotné dokumentace.
Díky tomu, že musí být napsaná pomocí typografického systému LATEX, jsem
se naučila s LATEXem pracovat alespoň na základní úrovni a příjemě mne
potěšilo co všechno s ním dokážu i jako nezkušený uživatel. Rozhodně ho
budu dále využívat.
10

Podobné dokumenty

Prevodník pH a redox ORP Liquisys CPM221 CPM 221

Prevodník pH a redox ORP Liquisys CPM221 CPM 221 Displej ukazuje současně momentální měřenou hodnotu a teplotu. Tím jsou k dispozici nejdůležitější provozní hodnoty na jeden pohled (současně). V konfiguračním menu pomáhají při nastavení parametrů...

Více

Katalog DuPont Personal Protection

Katalog DuPont Personal Protection Výběr vhodného ochranného oděvu pomáhá zabránit nejen úrazům, ale i nemocem z povolání, které se mohou projevit po dlouhé době. Vaši zaměstnanci mohou riskovat své zdraví. Proto potřebují ochranu, ...

Více

VisionBook 10Wi Pro

VisionBook 10Wi Pro často zobrazovaných stránek. Můžete připnout své oblíbené aplikace jako dlaždice a přizpůsobit si tak obrazovku Start. Na úvodní obrazovce také můžete změnit obrázek na pozadí.

Více

HOSPITALin 9/2015

HOSPITALin 9/2015 a rehabilitaci pro osoby s vážným duševním onemocněním v domácím prostředí. Je určena primárně lidem nemocným psychózou (F20 – F29), poruchami nálady (F30-F39) a obsedantně

Více

Návod k obsluze PUE7

Návod k obsluze PUE7 11.3. Úrovně přístupu (autorizace) ....................................................................................................................35 12. NAVIGACE V MENU ..........................

Více

1. Úvod .........................................................

1. Úvod ......................................................... 7. Struktury, unie, enumy, typedef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 7.1 enum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ...

Více

Přehrávání - Lan-Shop

Přehrávání - Lan-Shop proudem, nevystavujte přístroj dešti ani vlhkosti. UPOZORNĚNÍ Tento výrobek obsahuje optické zařízení, jehož nesprávné používání může způsobit poškození zraku. Při používání ovládacích prvků nebo p...

Více