This page was automatically generated by NetLogo 5.0.4.

The applet requires Java 5 or higher. Java must be enabled in your browser settings. Mac users must have Mac OS X 10.4 or higher. Windows and Linux users may obtain the latest Java from Oracle's Java site.


In order for this to work, this file, your model file (SchellingRozsireny.nlogo), and the files NetLogoLite.jar and NetLogoLite.jar.pack.gz must all be in the same directory. (You can copy NetLogoLite.jar and NetLogoLite.jar.pack.gz from the directory where you installed NetLogo.)

On some systems, you can test the applet locally on your computer before uploading it to a web server. It doesn't work on all systems, though, so if it doesn't work from your hard drive, please try uploading it to a web server.

You don't need to include everything in this file in your page. If you want, you can just take the HTML code beginning with <applet> and ending with </applet>, and paste it into any HTML file you want. It's even OK to put multiple <applet> tags on a single page.

If the NetLogoLite files and your model are in different directories, you must modify the archive= and value= lines in the HTML code to point to their actual locations. (For example, if you have multiple applets in different directories on the same web server, you may want to put a single copy of the NetLogoLite files in one central place and change the archive= lines of all the HTML files to point to that one central copy. This will save disk space for you and download time for your users.)

powered by NetLogo

view/download model file: SchellingRozsireny.nlogo

Co je to?

Jde o variaci na klasický Schellingův model prostorové segregace, který je rozšířený o nové prvky.

Jak to pracuje?

Model funguje vlastně velmi jednoduše. Každý aktér si spočítá ve svém okolí počet obyvatel svého a druhého etnika, podle těchto počtů bude se svým bydlištěm spokojený nebo nespokojený. V případě nespokojenosti se stěhuje na jiné místo.
V modelu se nastavuje mnoho parametrů, které výše uvedený jednoduchý proces ovlivňují:
zda se má aktér soustředit na své etnikum, na druhé, nebo obě dvě; jaké jsou kritické podíly osob v okolí pro spokojenost a nespokojenost; velikost populace; velikost hodnoceného okolí; podíl etnik v populaci; kolik je třeba minimálně spokojených, aby se zastavila simulace; algoritmus vyhledávání nového místa pro stěhování; zda se má spouštět ekonomický podprogram (možnosti stěhování vázané na velikost příjmu, chátrání neobydlených nemovitostí, cenová pásma nemovitostí); kolikrát se má simulovat jedno unikátní nastavení v experimentu atd.

Jak s tím pracovat?

Šedá tlačítka pro spouštění simulace:
INICIALIZACE = nastaví prostředí do stavu, ve kterém můžeme spustit simulaci
SIMULUJ! = spustí simulaci, až jeden běh simulace doběhne, tlačítko se vypne
EXPERIMENTUJ! = spustí kompletní simulaci, tak jak je naprogramovaná v podprogramu “experimentuj”
ČERNÉ POZADÍ = v kompletním experimentu je nefunkční, ale pokud si zkoušíme spouštět jednotlivé simulace a nepotřebujeme vidět neobyvatelné plochy a třídy bydlení, lze celé pozadí začernit, tj. po stlačení všechny šedé a růžové plošky zčernají; na barvu aktérů nemá tlačítko vliv

Co je třeba vést v patrnosti?

1) Po spuštění experimentu nedoporučuji manipulovat s posuvníky a tlačítky. Program experimentu je nastaví do výchozí potřebné polohy na začátku a pak dále předpokládá, že se s nimi nemanipuluje. Program experimentu pak s hodnotami posuvníků a nastavením tlačítek manipuluje systematicky podle plánu experimentu, pokud hodnoty změníme, dojde buď k opakování experimentu pro již jednou experimentovaná nastavení (ta pak budou ve výsledku nadreprezentovaná), nebo k vynechání některých kombinací nastavení z experimentu (ta pak budou chybět), nebo ke zkreslení výsledků (např. když zapneme modul EKONOMIKA, ačkoli experiment s tímto modulem nepočítá a proto jej vypne na počátku a dále již nekontroluje, zda nebyl náhodou v průběhu znovu zapnutý).

2) Je třeba na počátku s rozmyslem zvolit adresář, kam se budou ukládat výsledky. Jednak abychom snadno našli soubor s výsledky a také pokud bude zapnutý export obrázků s finálním rozmístěním aktérů (a jako zapnutý je tento export přednastavený), budou tyto obrázky celkem mít cca 400MB (při 900 bězích simulace).

3) je třeba s rozmyslem zacházet s posuvníkem OPAKOVANI, ktery určuje, kolikrát se má simulace zopakovat pro jedno unikátní nastavení parametrů. Nyní je testováno 300 unikátních kombinací těchto parametrů. Při OPAKOVANI=3 běží simulace cca hodinu (záleží na výkonu počítače) a vyprodukuje cca 400MB dat (především exportované obrázky s finálním rozmístěním aktérů). Pokud OPAKOVANI zvýšíme o 1, musíme počítat s tím, že se běh simulace prodlouží o dalších cca 20minut a vyprodukuje dalších cca 130MB dat. Pokud bychom chtěli zvýšit počet opakování na desítky, doporučuji vypnout export finálního rozmístění a také zvážit sledované parametry - např. při OPAKOVANI=60 poběží simulace zhruba celý den bez přestávky (pokud na příslušném počítači budeme ještě něco dělat, může se čas ještě prodloužit), pak je vhodné mít stroj vyhrazen buď pouze na tuto simulaci, nebo simulaci přeprogramovat tak, aby některý parametr nezohledňovala, resp. zafixovala na konstantní hodnotu, např. zafixování poloměru hodnoceného okolí zkrátí simulaci o 80% (nyní se pracuje s 5 hodnotami 1, 1.5, 2, 2.5 a 3), podobně zafixování poměru etnik zkrátí simulaci také o 80% (nyní je simulováno 5 poměrů 10:90, 20:80, 30:70, 60:40 a 50:50), zafixování poloměru okolí a zároveň i poměru zkrátí simulaci o 96% (nyní simulujeme 25 kombinací poloměru a poměru, když budeme oba parametry fixovat, budeme simulovat jen jednu z těchto 25 kombinací, tedy tato 1 zafixovaná kombinace tvoří 4% z těchto 25 kombinací).

Co je možné vyzkoušet?

Pomocí tlačítek INICIALIZACE a SIMULUJ! můžeme spouštět jeden běh simulace (první nastaví model, druhé jej jednou spustí). Pokud chceme spustit systematický experiment, můžeme využít tlačítko EXPERIMENTUJ!, experiment je ale třeba přeprogramovat, pokud nám současný program experimentu nevyhovuje. Nyní experiment pracuje s:
- poměrem etnik v populaci (10:90, 20:80, 30:70, 40:60 a 50:50)
- tolerancí (25%, 35%, 45%, 55%, 65% a 75% sousedů z jiného etnika v sousedství)
- poloměr okolí (1, 1.5, 2, 2.5 a 3 délky políčka)
- algoritmus (“náhodný” = nespokojený aktér si náhodně vybere jakékoli volné políčko a tam se přestěhuje; “nejlepší” = nespokojený si vybere políčko v jehož okolí je nejvíce aktérů jeho etnika)

Mimo tento popsaný experiment je možné testovat vliv zavedení neobyvatelných ploch (nastavením obou posuvníků NEOBYVATELNE-DOMY a NEOBYVATELNE-PLOCHY na nenulové hodnoty).
Dále je možné pracovat s velikostí populace, čímž se upraví poměr obydlených a neobydlených políček. Celkem je v modelu 5.041 políček, minimálně 41 bude vždy volných, model kontroluje, aby součet neobyvatelných políček a velikost populace nepřesáhl 5.000. Tedy, čím menší populace je a čím méně neobyvatelných políček je, tím je větší počet políček, kam je možné se stěhovat.

Dále je možné pracovat s posuvníkem MINIMALNI-PODIL-SPOKOJENYCH. Willenského model trvá na tom, aby simulace skončila až když je všech 100% aktérů spokojených. To nemusí být úplně realistické, proto je možné nastavit, že simulace skončí, už když je spokojeno 90-100% aktérů. Bylo by možné testovat, jak se tato cílová spokojenost podílí na segregaci.

Místo tolerance je možné použít podíl vlastního etnika v okolí (přepínač POUZIT-PODIL) a posuvníkem VYZADOVANY-PODIL-VLASTNIHO-ETNIKA nastavit vyžadovaný podíl. Je také možné experimentovat s kombinacemi tolerance a podílu vlastního etnika.

Teoreticky je možné připravený experiment spustit se zapnutým ekonomickým modulem. Přepínač EKONOMIKA zapne snižování nájmů u dlouho neobydlených bytů (za každých 18 měsíců neobydlení klesne třída bydlení o jeden stupeň). Dále se po sepnutí přepínače kontroluje, zda si aktér byt/dům může dovolit, tj. zda třída bydlení není vyšší než třída platu (obojí má 9 tříd). ODPOVIDAJICI-UROVEN-BYDLENI zase po zapnutí kontroluje, zda třída bydlení zhruba odpovídá třídě platu (obojí má 9 tříd), algoritmus toleruje, pokud je bydlení horší o dvě třídy než třída platu, např. pokud má někdo třídu platu 6, není možné, aby si pořídil bydlení třídy 9-7 (viz EKONOMIKA), třídy bydlení 6, 5 a 4 jsou maximálně o dvě třídy horší, což je v pořádku, a konečně, třídy 3-1 jsou příliš nízké (aktérovi se v nich “nechce bydlet”, když si může “dovolit” lepší). Přepínač PRIJEM-DLE-PRVNIHO-DOMU zajistí, aby třída platu odpovídala třídě bydlení. Pokud je vypnutý, stane se, že řada aktérů bude na počátku okamžitě nespokojených, a to z ekonomických důvodů: buď bude nájem vyšší než jejich příjem, nebo bude bydlení příliš nuzné ve srovnání s třídou platu. Zapnutý přepínač odpovídá spíše dnešní situaci, kdy jsou bydlení a příjem váce méně konzistentní. Pokud přepínač vypneme, bude simulace připomínat spíše situaci na počátku 90. let, kdy se měnil pracovní trh i trh bydlení, a tak se snadno stalo, že najednou aktér zjistil, že jeho bydlení a příjem si bolestně neodpovídají. Pokud bude přepínač vypnutý, odhadují, že scénáře s ekonomickým modulem budou trvat déle, již proto, že nesoulad tříd bydlení a platů vyprodukují na počátku více nespokojených, než kdybychom simulovali pouze nespokojenost s etnickou strukturou. Proto považuji za přiměřenější přepínač zapnout, tím pádem si budou třídy bydlení a platy odpovídat a vliv ekonomického modulu se projeví jen jako ztížení rozhodování.

Rozšíření modelu

Prezentovaný model se od původního Schellingova modelu i od Willenského modelo v bance základních modelů NetLoga liší v jednom ohledu:
vede v patrnosti prázdná pole v sousedství.
Jak Schelling tak Wilenski prázdná pole nezapočítávají, počítají pouze s poměrem aktérů, kteří se vyskytují v okolí. Jde jim tedy o to, zda vhodného poměru dosahuje zlomek (sousedé vlastního etnika / všichni sousedé). Prezentovaný model nabízí dvě jiné základní varianty:
1) Je ve sledovaném okolí dost sousedů mého druhu?
Tj. je alespoň minimální podíl okolních domů/bytů obsazen sousedy mého druhu, počet je pak dán velikostí okolí (nastavuje posuvník RADIUS) a minimálním požadovaným podílem sousedů mého druhu (nastavuje posuvník VYZADOVANY-PODIL-VLASTNIHO-DRUHU).
2) Není ve sledovaném okolí příliš sousedů jiného druhu?
Tj. není překročena maximální obsazenost okolních domů/bytů sousedy jiného druhu, počet je pak dán velikostí okolí (nastavuje posuvník RADIUS) a maximálním tolerovaným podílem sousedů jiného druhu (nastavuje posuvník TOLERANCE).
Přičemž je možné obě varianty kombinovat.

Pokud bychom chtěli od prázdných polí v sousedství odhlížet, je třeba přepracovat architekturu modelu. Pokud má být originální způsob uvažování (Schelling či Willenski) doplněn či pokud má nahradit způsob prezentovaný zde, je třeba přepracovat všechny rozhodovací algoritmy a výpočet spokojenosti. Toto přepracování je tedy první možností, jak rozšířit model. Osobně se mi ale zdálo, že zohlednit prázdná pole je dobrý nápad: vycházel jsem z úvahy, že jestli např. sousedství čítá 20 polí, tolerance je nastavena na 20%, a v tomto sousedství se nachází 1 aktér vlastního a 1 aktér jiného druhu, nepovede těch 5% domů/bytů obsazených aktéry jiného druhu k přílišné nespokojenosti.
Můžeme si klást otázku, jak moc tento jiný způsob výpočtu spokojenosti ovlivní naše výsledky. Není lepší způsob, než Schellingův a Willenského výpočet do prezentovaného modelu doplnit, přeprogramovat i způsob provedení experimentu a testovat citlivost modelu na tento způsob výpočtu spokojenosti.

Jako další rozšíření se nabízí doplnění více etnik, než jsou stávající dvě. Jak to promění výsledky? Opět, není lepší způsob, než model rozšířit a experimentivat s ním.

Třetí rozšíření, které mi napadá, je diverzifikace rozhodovacích algoritmů. Nyní si nastavíme jeden způsob rozhodování pro celou populaci, ale jak se výsledky promění, když se aktéři budou lišit v tom, jaké rozhodovací algoritmy si osvojí? Opět, je třeba model přeprogramovat pro takovou inovaci - bude třeba dohlédnout, aby byly použité algoritmy souměřitelné, např. nemá smysl, aby některý aktér zohledňoval svůj příjem (tj. stěhoval se jen tam, kde mu příjem stačí na nájem) a jiný ne (tj. stěhoval se klidně do drahých domů/bytů, přestože nemá odpovídající příjem); na druhou stranu, je jistě logické a možné, aby někdo trval na standardu svého bydlení (tj. stěhoval se jen do bytů/domů takových cenových kategorií, které odpovídají jeho příjmu, nebo jsou je o málo nižší) a jiný aktér na tom netrval (tj. přestože má např. nejvyšší příjem, nemá problém se přestěhovat do např. bytu/domu té nejnižší kategorie).

Z tohoto rozšíření vyplývá i možnost provázat strategie s etniky - co když se modří budou rozhodovat exklusivně nejakými způsoby a jen některé budou se zelenými sdílet? Je možné experimentovat i s maticí pravděpodobností, která se bude měnit a s různou pravděpodobností přidělovat jednotlivým etnikům jednotlivé rozhodovací strategie.

Podobně lze provázat s etniky i příjmové kategorie, ale i to, zda se budou řídit tolerancí, trváním na dostatečném počtu sousedů ze svého etnika v okolí, nebo zda se budou řídit Schellingovým poměrem.

Také je možné do modelu zapracovat paměť aktérů v tom smyslu, že je k nespokojenosti může přivést krom absolutního momentálního stavu relativní vývoj. Např. okolí uvažujeme jako Moorovo okolí (8 okolních políček) a tolerance je nastavena na 45%, sousedství je na počátku zcela etnicky homogenní, jsou zde 4 prázdná políčka a 4 obsazená stejným etnikem jako je aktér. V prvním kole se přistěhuje do prázdného políčka aktér jiného etnika a ve druhém kole druhý takový. Pokud by náš aktér aproximoval vývoj v tom smyslu, že se počet akterú jiného etnika v sousedství zdvojnásobí (2 * 1 = 2), bude v příštím kole očekávat nastehování dalších dvou sousedů jiného etnika a tedy, že druhé etnikum obsadí v sousedství 50% domů/bytů (2 * 2 = 4; 4 / 8 = 50%), a proto se raději hned odstěhuje. Pokud bude aproximovat vývoj, jako přírůstek o 1 souseda jiného etnika (2 - 1 = 1), bude předpokládat v příštím kole nárůst sousedů jiného etnika na celkem 3, a tudíž se pro stěhování ještě nerozhodne (3 / 8 = 37,5%; 37,5 < 45).

Dále je možné rozšiřovat ekonomický modul např. o dlouhodobé úspory, dluhy atp.

Poslední a dost důležité rozšíření, je rozšíření o výpočet segregace. Nyní model nějak doběhne a uloží obrázek s výsledným rozvrstvením. Jeden obrázek má cca 400kB, je to tedy náročné na volné místo na disku. Bylo by užitečné zapracovat nějaké míry či koeficienty segregace, což by výrazně usnadnilo analýzu, kdyby tyto koeficienty dobře reprezentovaly výsledné rozmístění aktérů.
Willenski používá údaj o průměrném podílu sousedů vlastního etnika mezi všemi sousedy. Možné je i zařadit míru, kolik aktérů má kolem sebe etnicky homogenní von Neumannovo (4 políčka, jedno každé v kolmém směru) nebo Moorovo okolí (8 políček obkružujících aktéra). Případně podíl aktérů s tímto homegenním okolím v celé populaci. Je samozřejmě možné zařadit jakoukoli vhodnou míru segregace.
(Např. mi napadá nejmenší hypotetická velikost okolí při které by pro všechny aktéry byl poměr etnik v tomto hypotetickém okolí stejný jako v celé populaci, případně by v tomto hypotetickém okolí bylo více aktérů z druhého etnika, než jak udává poměr v celé populaci;
čím menší by taková hypotetická velikost byla, tím méně segregovaná by populace měla být;
otázka je jak v takovém výpočtu zacházet s prázdnými políčky… také je otázka, jak zacházet s mimořádnými případy - co když by bylo pro 99% aktérů okolí heterogenní při hypotetickém rádiusu 3 a jen pro 5 aktérů by ta vzdálenost byla 8?;
možná by šlo tento údaj spočítat pro 95%, 99%, 99,9% a 100% aktérů).

Příbuzné modely

Příbuzný rozhodně je Schellingův model segregace, který je v bance základních modelů NetLoga. A samozřejmě ukázkový zjednodušený model pro článek v DaV.

Autorství

(c) 2013
Článek, ve kterém je model publikován, je momentálně v recenzním řízení, není tedy možné autora uvádět.

CODE

breed [zeleni zeleny]
breed [modri  modry]

globals
[
  hodnocena-plocha  
  ;; pocet policek, na kterych bude akter posuzovat pomer etnik a bude se tak rozhodovat, zda bude spokojeny, ci ne
  
  volne-domy        
  ;; sem si bude akter poznamenavat, ktere domy jsou volne, a muze se do nich tudiz prestehovat
  
  spokojeni-modri
  spokojeni-zeleni
  spokojeni-celkem
  ;; tyto tri promenne se nam budou hodit jednak pro prubezny monitoring a jednak pro ukladani vysledku experimentu
  
  soubor
  ;; promenna pro pripadne definovani nazvu nebo cesty souboru
]

turtles-own 
[
  spokojenost  
  ;; 1 = spokojeny, 0 = nespokojeny
  
  prijem       
  ;; budeme mit 9 prijmovych pasem 1-9
]

patches-own
[
  stav  
  ;; dum muze byt ve trech stavech: 0 = neobyvatelny, 1 = obydleny, 2-241 = volny po dobu (stav - 2) mesicu
  
  najem 
  ;; 9 je maximalni cena najmu, tj. mame 9 cenovych hladin najmu 1-9
]


to inicializace
  clear-ticks clear-turtles clear-patches clear-drawing clear-all-plots 
  
  if neobyvatelne-domy = 0 [set neobyvatelne-plochy 0]
  if neobyvatelne-plochy = 0 [set neobyvatelne-domy 0]
  ;; v simulaci lze nastavit, ze nektere plochy jsou neobyvatelne, paramtry jsou dva:
  ;; kolik ma byt celkem neobydlenych domu/bytu a do kolika ploch maji byt rozdeleni
  ;; Pokud je vsak jeden z parametru 0 a druhy je nenulovy, dojde k chybe programu,
  ;; proto je treba nastavit oba parametry na 0, kdyz je jen jeden 0
  
  
  ifelse alternativni-prostredi = false [vykresli-prostredi] [vykresli-alternativni-prostredi]
  ;; vykresli bud prostredi, ktere pripomina Sugarscape, nebo prostredi,
  ;; ktere pripomina zonaci mesta
  
  ask n-of neobyvatelne-plochy patches [set pcolor pink]
  ;; zalozime tolik mist pro neobyvatelne plochy, kolik jsme si nastavili na posuvniku
  
  while [count patches with [pcolor = pink] < neobyvatelne-domy]
  [
    ask one-of patches with [pcolor = pink]
    [
      ask one-of neighbors 
      [
        set pcolor pink
        set stav 0
        set najem 0
      ]
    ]
  ]
  ;; dokud nema neobyvatelna plocha rozsah stanoveny na posuvniku,
  ;; bude stale probihat cyklus, kdy nahodne vybereme jeden neobyvatelny dum/pozemek,
  ;; a pak nahodne vybereme jeden sousedni a ten nastavime take jako neobyvatelny 
    
  ask patches with [stav = 2]
  [
    set stav (2 + random 19)
  ]
  ;; domy, ktere jsou obyvatelne, si nastavi nahodne, jak dlouho jsou volne: 0-18 mesicu
  
  if populace > (5000 - neobyvatelne-domy) [set populace (5000 - neobyvatelne-domy)] 
  ;;  policek je sice 5041, ale potrebujeme alespon tech 41 kvuli stehovani,
  ;;  kdyby byla vsechna pole obsazena, nemaji se nespokojeni kam stehovat
  
  ask n-of populace patches with [pcolor <= 9]
  [
    ifelse (random-float 1) < podil-zelenych-v-populaci 
    [sprout-zeleni 1 [set color green]] 
    [sprout-modri 1 [set color blue]]
  ]
  ;; nahodne vybereme tolik domu, jak velkou jsme stanovili populaci na posuvniku
  ;; kazdy dum pak losuje, dle na posuvniku nastavene pravdepodobnosti,
  ;; zda v nem na pocatku bude bydlet modry nebo zeleny
  ;; dle losu ho pak stvori                                                               
  
  ask turtles 
  [
    ask patch-here [set stav 1]          
    ;; nastavi svuj dum jako obydleny
    
    set size 1.4                         
    ;; nastavi svou velikost, aby byly zretelnejsi
    
    ifelse prijem-dle-prvniho-domu = true
    [set prijem ([najem] of patch-here)]
    [set prijem ((random 9) + 1)]          
    ;; nastavi svuj prijem na 1 - 9,
    ;; bud podle najmu domu, kde se v dobe inicializace nachazi,
    ;; nebo to bude stanoveno nahodne,
    ;; nastaveni dle najmu dava tu vyhodu, ze najem a prijem potom jen omezuji stehovani,
    ;; ale napocatku jejich nesoulad nenuti lidi, aby se stehovali jen kvuli tomu,
    ;; ze jim byl nahodne pridelen prijem, ktery nestaci na najem domu, ktery byl pridelen tez nahodne 
  ]
  
  spocitej-spokojenost
  ;; poprve urcime spokojenost akteru na konci inicializace 
  
  reset-ticks
end


to vykresli-prostredi
  ask patch 50 50 [sprout 1900 [set heading (random-float 360)]]
  ask patch 25 25 [sprout 6000 [set heading (random-float 360)]]
  ask turtles [fd (random 20)]
  ask turtles 
  [
    ask patch-here [set pcolor 8]
    die
  ]
  ;; nejprve nakreslime dva kruhy, a to tak, ze si pripavime na kazdy ze dvou stredu kruhu
  ;; nekolik tisic "zelvicek", ktere rovnomerne nastavi svuj smer po celych 360 stupnu,
  ;; pak kazda zelvicka udela 0-19 kroku kupredu.
  ;; Tim tedy zelvicky pokryji plochu dvou kruhu.
  ;; Kazda zelvicka pak pod sebou obarvi dlazdici na odstin c.8 a zemre, tedy se jiz dale simulace neucastni.
    
  repeat 45 [diffuse pcolor 1]
  ask patches 
  [
    set pcolor ((round pcolor) + 1)
    set najem pcolor
    ;; Odstin dlazdice pak difunduje, vytvori se tedy prechodove zony mezi 0 a 8.
    ;; difundovane odstiny zaokrouhlime na cela cisla a pricteme jednicku,
    ;; dostavame tak pasma najmu 1-9.

    set stav 2
    ;; vsechny domy si nastavi stav 2, tedy volny
  ]
end


to vykresli-alternativni-prostredi
  ask one-of patches [set pcolor 8]
  while [count patches with [pcolor = 8] < 900]
  [
    ask one-of patches with [pcolor = 8]
    [
      if (sum [pcolor] of neighbors) < 64 
      [ask one-of neighbors with [pcolor = black] [set pcolor 8]]
    ]
  ]
  ;; tento cyklus vykresli ctvrt s nejdrazsimi domy/byty
  
  ask n-of 20 patches with [pcolor = black] [set pcolor 4]
  while [count patches with [pcolor = 4] < 2500]
  [
    ask one-of patches with [pcolor = 4]
    [
      if (sum [pcolor] of neighbors) < 32 
      [ask one-of neighbors with [pcolor = black] [set pcolor 4]]
    ]
  ]
  ;; tento cyklus vytvori nekolik oblasti se stredne drahymi domy/byty
  
  ;; nasledujici cast kodu zajisti pomoci prikazu DIFFUSE, ze se cena domu/bytu
  ;; zacne z puvodnich 3 kategorii> 0, 4 a 8 "rozpijet", zacnou vznikat prechody mezi temito
  ;; tremi kategoriemi, az vznikne 9 zon s kategoriemi 0-8
  ;; difundovane odstiny totiz zaokrouhlime na cela cisla a pricteme jednicku,
  ;; dostavame tak pasma najmu 1-9.
  repeat 10 [diffuse pcolor 1]
  ask patches 
  [
    set pcolor (round(pcolor) + 1)
    set najem pcolor
    set stav 2
    ;; vsechny domy si nastavi stav 2, tedy volny
  ]
end

;;
;;
;;
;; samotna simulace, verze pro experiment
;;
;;
;;

to simuluj
  ask turtles with [spokojenost = 0] [prestehuj-se]
  ;; nespokojeni akteri si najdou nove byty
  
  if ekonomika = true [prijmy-najmy]
  ;; pokud je spinac EKONOMIKA zapnuty propocita dobu obsazeni a tridy bydleni
  
  spocitej-spokojenost
  ;; prejde do podprogramu, ktery spocita spokojenost kazdeho aktera
  
  tick
end



;;
;; verze pro samosatne spusteni
;;

to simuluj2
  ask turtles with [spokojenost = 0] [prestehuj-se]
  ;; nespokojeni akteri si najdou nove byty
  
  if ekonomika = true [prijmy-najmy]
  ;; pokud je spinac EKONOMIKA zapnuty propocita dobu obsazeni a tridy bydleni
  
  spocitej-spokojenost
  ;; prejde do podprogramu, ktery spocita spokojenost kazdeho aktera
  
  tick
  
  if (spokojeni-celkem >= (minimalni-podil-spokojenych * populace)) or ticks = 240 [stop]
end



;;
;;
;;
;; podprogramy
;;
;;
;;

to prestehuj-se
  set volne-domy patches with [stav > 1]
  ;; soupis volnych bytu
  
  ask patch-here [set stav 2]
  ;; pred samotnym stehovanim - na algoritmu nezalezi - je treba aktera odhlasit z bytu, 
  ;; i kdyby tu mel na konci kola akter zase skoncit
  
  if algoritmus = 1 
  [
    move-to one-of volne-domy
    ask patch-here [set stav 1]
  ]
    
  if algoritmus = 2
  [
    ;; Po delsim vahani jsem se nakonec rozhodl nedat do tohoto algoritmu automatickou aktivaci modulu
    ;; "EKONOMIKA", protoze muzeme chtit sledovat chovani modelu pri zavedeni podminky cenovych pasem,
    ;; ale bez podminky, ze by ncena neobydlenych domu/bytu degradovala.
    ;; Kdyby byl nekdo jineho mineni, necht smaze ";;" na zacatku nasledujici radky:
    ;;set ekonomika true
    
    
    carefully 
      [ifelse odpovidajici-uroven-bydleni = false 
        [move-to one-of volne-domy with [najem <= [prijem] of myself]]
        [move-to one-of volne-domy with [((najem + 2) >= [prijem] of myself) and (najem <= [prijem] of myself)]]
      ]
      [print "nedostupne bydleni"]
  ]
 
  if algoritmus = 3
  [
    carefully
    ;; muze se stat, ze se zadny vhodny dum nenajde, coz by v programu vyvolalo chybu 
    ;; (neni mozne stehovat aktera do neexistujiciho domu), proto se pouziva CAREFULLY
    ;; pokud program vyvola chybu (zde bude chtit stehovat aktera na neexistujici adresu),
    ;; diky CAREFULLY se program nezastavi, cast programu osetrena CAREFULLY chybu nevyprodukuje,
    ;; a misto toho se provede nahradni blok programu, coz je v nasem pripade
    ;; [print "žádný vhodný dům"]
    [if is-zeleny? self 
      [
        let minimum-zelenych  (hodnocena-plocha * vyzadovany-podil-vlastniho-druhu)
        let maximum-modrych   (hodnocena-plocha * tolerance)
        let vhodne-domy volne-domy
        if odpovidajici-uroven-bydleni = true 
          [set vhodne-domy (volne-domy with [((najem + 2) >= [prijem] of myself)and (najem <= [prijem] of myself)])]
        ;; pro prehlednost a zkraceni podminek si vytvorim tyto tri docasne pomocne promenne
      
        if (pouzit-podil = true)  and (pouzit-toleranci = false)
          [move-to one-of vhodne-domy with [count zeleni in-radius radius-hodnoceneho-okoli > minimum-zelenych]]
        if (pouzit-podil = false)  and (pouzit-toleranci = true)  
          [move-to one-of vhodne-domy with [count modri in-radius radius-hodnoceneho-okoli < maximum-modrych ]]
        if (pouzit-podil = true)  and (pouzit-toleranci = true)  
          [move-to one-of vhodne-domy with [(count zeleni in-radius radius-hodnoceneho-okoli > minimum-zelenych) and (count modri in-radius radius-hodnoceneho-okoli < maximum-modrych)]]
        ;; serie podminek nalezne dle nastavenych kriterii akterovi vhodna mista, tj. domy, ktere splnuji nastavene podminky rasove tolerance,
        ;; akter se presune do jednoho z nich (vybraneho nahodne)  
    ] 

     if is-modry?  self 
      [
        let minimum-modrych  (hodnocena-plocha * vyzadovany-podil-vlastniho-druhu)
        let maximum-zelenych (hodnocena-plocha * tolerance)
        let vhodne-domy volne-domy
        if odpovidajici-uroven-bydleni = true 
          [set vhodne-domy (volne-domy with [((najem + 2) >= [prijem] of myself)and (najem <= [prijem] of myself)])]
        ;; pro prehlednost a zkraceni podminek si vytvorim tyto tri docasne pomocne promenne

        if (pouzit-podil = true)  and (pouzit-toleranci = false)
          [move-to one-of vhodne-domy with [count modri in-radius radius-hodnoceneho-okoli > minimum-modrych ]]
        if (pouzit-podil = false)  and (pouzit-toleranci = true)  
          [move-to one-of vhodne-domy with [count zeleni in-radius radius-hodnoceneho-okoli < maximum-zelenych ]]
        if (pouzit-podil = true)  and (pouzit-toleranci = true)  
          [move-to one-of vhodne-domy with [(count modri in-radius radius-hodnoceneho-okoli > minimum-modrych) and (count zeleni in-radius radius-hodnoceneho-okoli < maximum-zelenych)]]
        ;; serie podminek nalezne dle nastavenych kriterii akterovi vhodna mista, tj. domy, ktere splnuji nastavene podminky rasove tolerance,
        ;; akter se presune do jednoho z nich (vybraneho nahodne)  
      ]
    ]
    [print "žádný vhodný dům"]    
  ]
  
  if algoritmus = 4
  [
    if is-zeleny? self 
    [
      move-to max-one-of volne-domy [(count zeleni in-radius radius-hodnoceneho-okoli)]
    ] 

    if is-modry?  self 
    [
      move-to max-one-of volne-domy [(count modri  in-radius radius-hodnoceneho-okoli)]
    ]    
  ]

  if algoritmus = 5
  [
    set ekonomika true    
    ;; jelikoz "moznym" chapu ekonomickou dostupnost, je nutne zapnout ekonomicky doplnek
    
    if is-zeleny? self 
    [
      carefully
        [ifelse odpovidajici-uroven-bydleni = false 
          [move-to max-one-of volne-domy with [ najem <= [prijem] of myself] 
            [(count zeleni in-radius radius-hodnoceneho-okoli) - (count modri  in-radius radius-hodnoceneho-okoli)]]
          [move-to max-one-of volne-domy with [((najem + 2) >= [prijem] of myself) and najem <= [prijem] of myself] 
            [(count zeleni in-radius radius-hodnoceneho-okoli) - (count modri  in-radius radius-hodnoceneho-okoli)]]
        ]
        [print "nedostupne bydleni"]
    ] 

    if is-modry?  self 
    [
      carefully
        [ifelse odpovidajici-uroven-bydleni = false 
          [move-to max-one-of volne-domy with [ najem <= [prijem] of myself] 
            [(count modri in-radius radius-hodnoceneho-okoli) - (count zeleni in-radius radius-hodnoceneho-okoli)]]
          [move-to max-one-of volne-domy with [((najem + 2) >= [prijem] of myself) and najem <= [prijem] of myself] 
            [(count modri in-radius radius-hodnoceneho-okoli) - (count zeleni  in-radius radius-hodnoceneho-okoli)]]
        ]
        [print "nedostupne bydleni"]
    ]    
  ]
  
  ask patch-here [set stav 1]
  ;; at akter skoncil, kde chtel, je treba nastavit jeho aktualni byt jako obydleny
end 


to prijmy-najmy
  ask patches with [stav > 1]
  [
    set stav (stav + 1)
  ]
  
  ask patches with [najem > 1 and stav > 20]
  [
    set najem (najem - 1)
    set pcolor najem
    set stav (stav - 18)
  ]
end


to spocitej-spokojenost
  ask turtles [set spokojenost 1]
  ;; jelikoz je pro spokojenost v ruznych scenarich ruzne mnozstvi podminek,
  ;; nastavime nejprve kazdeho aktera jako spokojeneho a pak projdeme podminky pro nespokojenost,
  ;; jakmile bude nekdo kvuli necemu nespokojeny, uz nespokojeny zustane
  
  ask patch 35 35 [set hodnocena-plocha ((count patches in-radius radius-hodnoceneho-okoli) - 1)]
  ;; patch 35 35 je zvolena ciste arbitrarne, ale pro pocet policek uvnitr radiusu je nutne
  ;; nejake policko zvolit a od nej vse spocitat
  
  if (pouzit-toleranci or pouzit-podil) = false [set pouzit-podil true]
  ;; je treba, aby bylo zapnute alespon jedno kriterium
  
  ask zeleni 
  [
    if pouzit-toleranci = true 
    [
      if (count modri in-radius radius-hodnoceneho-okoli) / hodnocena-plocha > tolerance 
        [set spokojenost 0]
    ]
    
    if pouzit-podil = true 
    [
      if ((count zeleni in-radius radius-hodnoceneho-okoli) - 1) / hodnocena-plocha < vyzadovany-podil-vlastniho-druhu 
        [set spokojenost 0]
    ]
  ]
  
  ask modri 
  [
    if pouzit-toleranci = true 
    [
      if (count zeleni in-radius radius-hodnoceneho-okoli) / hodnocena-plocha > tolerance 
        [set spokojenost 0]
    ]
    
    if pouzit-podil = true 
    [
      if ((count modri in-radius radius-hodnoceneho-okoli) - 1) / hodnocena-plocha < vyzadovany-podil-vlastniho-druhu 
        [set spokojenost 0]
    ]
  ]
  
  ask turtles 
  [
    if (ekonomika = true) and (prijem < [najem] of patch-here) [set spokojenost 0]                         
    ;; pokud vezmeme v uvahu ekonomiku a akter nema na najem, je nespokojeny
    
    if (odpovidajici-uroven-bydleni = true) and ((prijem - 2) > [najem] of patch-here) [set spokojenost 0] 
    ;; pokud ma nekdo o 3 a vice trid vyssi plat nez je trida jeho bydleni, bude take nespokojeny 
  ] 
  
    
  set spokojeni-modri count modri with [spokojenost = 1 ]
  set spokojeni-zeleni count zeleni with [spokojenost = 1 ]
  set spokojeni-celkem (spokojeni-modri + spokojeni-zeleni)
  ;; pocitame to pro monitoring a pro ulozeni vysledku experimentu
end


to zapis-vysledky
  output-type pocitadlo
  output-type "; "
  output-type (count patches)
  output-type "; "
  output-type neobyvatelne-domy
  output-type "; "
  output-type neobyvatelne-plochy
  output-type "; "
  output-type populace
  output-type "; "
  output-type podil-zelenych-v-populaci
  output-type "; "
  output-type minimalni-podil-spokojenych
  output-type "; "
  output-type pouzit-toleranci
  output-type "; "
  output-type tolerance
  output-type "; "
  output-type pouzit-podil
  output-type "; "
  output-type vyzadovany-podil-vlastniho-druhu
  output-type "; "
  output-type radius-hodnoceneho-okoli
  output-type "; "
  output-type algoritmus
  output-type "; "
  output-type ekonomika
  output-type "; "
  output-type odpovidajici-uroven-bydleni
  output-type "; "
  output-type prijem-dle-prvniho-domu
  output-type "; "
  output-type alternativni-prostredi
  output-type "; "
  output-type ticks
  output-type "; "
  output-type spokojeni-modri
  output-type "; "
  output-type spokojeni-zeleni
  output-type "; "
  output-print spokojeni-celkem
  ;; vypis poslednich polozek do outputu, tech ktere jsou vysledkem a nikoli vstupem
  
  if ukladat-finalni-usporadani = true 
  [
    let nuly ""
    ;; promenna, diky ktere doplnime odpovidajici pocet nul pred poradove cislo obrazku
    
    if pocitadlo < 10000 [set nuly "0"]
    if pocitadlo < 1000 [set nuly "00"]
    if pocitadlo < 100 [set nuly "000"]
    if pocitadlo < 10 [set nuly "0000"]
    ;; spravny pocet nul je pripraven...
    
    export-view (word "SchellingRozsireny" nuly pocitadlo ".png" )
  ]
  ;; Pokud budeme chtit a nastavime si spravny prepinac v interface,
  ;; tak se na disk ulozi obrazek s vyslednym usporadanim,
  ;; muzeme pak posuzovat, jak casto dojde k segregaci.
end


to experimentuj
  clear-all
  set pocitadlo 0
  set-current-directory user-directory
  ;; program se nas zepta, kam chceme ukladat vysledky
   
  let verze 1
  ;set verze user-input "Kolikátou verzi eperimentu spouštíte?" 
  ;; kdyz se odpoznamkuje radek vyse, muzeme zadavat cislo verze simulace,
  ;; a tudiz pozmenime i nazev souboru s vysledky,
  ;; protoze do-file ve STATe je uz pripraven na nazev souboru
  ;; "SchellingExperiment_v1.csv", nastavime verzi na 1
   
  set soubor (word "SchellingRozsireny_v" verze ".csv")
  ;; zadame cislo verze a tim se zkompletuje nazev souboru s vysledky experimentu
    
  ;; 
  ;; nyni zacne vlastni experiment,
  ;; neni zvladnutelne experimentovat se vsim, proto vezmu jen ctyri promenne:
  ;; - algoritmus: "náhodný" vs. "nejlepší"
  ;; - velikost/radius okoli: 1,0 (0,5) 3,0
  ;; - podil-zelenych-v-populaci: 0,10 (0,10) 0,50
  ;; - tolerance: 0,25 (0,10) 0,75
  ;; (tolerance bude prirozene nastavena TRUE, podil pak bude nastaven FALSE)
  set pouzit-toleranci true
  set pouzit-podil false
  
  ;;
  ;; Bylo by jiste mozne vybrat i jine promenne a zafixovat zde i hodnoty tech promennych, ktere jsou celou dobu konstantni,
  ;; ale nakonec jde jen o ukazku. Navic, kdo bude chtit vedet, jak by vysledky vypadaly, kdyby byla nejaka konstanta jinak, necht to zkusi.
  ;; Nebude muset ani programovat, vse si nastavi v interfaceu, pojmenuje nove soubor a muze zkouset... 
  ;;
  
  output-print "id; domy; neobyvatelneDomy; neobyvatelnePlochy; populace; podilZelenych; minimalniSpokojenost; pouzitToleranci; tolerance; pouzitPodil; podil; radius; algoritmus; ekonomika; urovenBydleni; prijemDlePrvnihoDomu; alternativniProstredi; ticks; spokojeniModri; spokojeniZeleni; spokojeniCelkem;" 
  ;; na zacatku experimentu natiskneme prvni radku se jmeny promennych, ty nejen ze pro kontrolu uvidime v okne vystupu,
  ;; ale take nam usnadni nacteni dat z *.csv souboru, kteru nakonec z okna vystupu vytvorime
  
  set algoritmus 1
  set podil-zelenych-v-populaci 0.10
  while [podil-zelenych-v-populaci <= 0.50]
  [
    set tolerance 0.25
    while [tolerance <= 0.75]
    [
      set radius-hodnoceneho-okoli 1
      while [radius-hodnoceneho-okoli <= 3.0]
      [
        repeat opakovani
        [
          set pocitadlo (pocitadlo + 1)
          inicializace
          while [spokojeni-celkem < minimalni-podil-spokojenych * populace and ticks < 240] 
            [simuluj]
          zapis-vysledky
        ]
        set radius-hodnoceneho-okoli precision (radius-hodnoceneho-okoli + 0.5) 1
      ]
      set tolerance precision (tolerance + 0.1) 2
    ]
    set podil-zelenych-v-populaci precision (podil-zelenych-v-populaci + 0.1) 2
  ]
  
  set algoritmus 4
  set podil-zelenych-v-populaci 0.10
  while [podil-zelenych-v-populaci <= 0.50]
  [
    set tolerance 0.25
    while [tolerance <= 0.75]
    [
      set radius-hodnoceneho-okoli 1
      while [radius-hodnoceneho-okoli <= 3.0]
      [
        repeat opakovani
        [
          set pocitadlo (pocitadlo + 1)
          inicializace
          while [spokojeni-celkem < minimalni-podil-spokojenych * populace and ticks < 240] 
            [simuluj]
          zapis-vysledky
        ]
        set radius-hodnoceneho-okoli precision (radius-hodnoceneho-okoli + 0.5) 1
      ]
      set tolerance precision (tolerance + 0.1) 2
    ]
    set podil-zelenych-v-populaci precision (podil-zelenych-v-populaci + 0.1) 2
  ]
     
  export-output soubor
  ;; ulozi vysledky z outputu do souboru, ktery pujde dale zpracovat
end