Skip to content

Commit 2bff161

Browse files
committed
final version (20230208)
1 parent 1d375a0 commit 2bff161

22 files changed

Lines changed: 913 additions & 0 deletions

docs/protokol.pdf

863 KB
Binary file not shown.

source/DECISION.m

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
function new_position_people = DECISION(position_to_be_updated,position_people,levels,walls,exit)
2+
%INPUT ... %position_to_be_updated ... náhodně vybraný index buňky, jejíž okolí budeme
3+
%aktualizovat v celé mřížce position_people...... NESMI TO BYT ZADNA Z
4+
%BUNEK NA OKRAJI
5+
%position_people ... tabulka 0 a 1 vyjadřující polohy lidí na
6+
%mřížce
7+
%levels ... tabulka potenciálů
8+
%walls ... tabulka stěn a sloupů
9+
%exit ... zvlast vypichnute souradnice vychodu
10+
%OUTPUT ... new_position ... aktualizovaná mřížka position_people
11+
12+
new_position_people = position_people; %inicializace
13+
14+
%v patem sloupci promenne neighborhood jsou hodnoty potenciálů, případně
15+
%NAN pro stěny, nebo sloupce
16+
neighborhood = GET_OKOLI(position_to_be_updated,position_people,levels,walls);
17+
18+
if position_people(position_to_be_updated(1),position_to_be_updated(2)) == 1 %%%%%%nejdriv resim, pokud je ta vybrana bunka plna
19+
min_pot = min(neighborhood(:,5));
20+
21+
%nalezeni radku s minimální hodnotou potencialu
22+
indeces_of_min_pot = find(neighborhood(:,5)==min_pot);
23+
%pocet radku s tim minimalnim potencialem
24+
[n_min_pots,~] = size(indeces_of_min_pot);
25+
%nejriv je snažíme tlacit na pole s minimalnim potencialem
26+
is_there_a_man = 0;
27+
is_there_a_wall = 0;
28+
for ind = 1:n_min_pots
29+
is_there_a_man(ind) = neighborhood(indeces_of_min_pot(ind),4);
30+
is_there_a_wall(ind) = neighborhood(indeces_of_min_pot(ind),3);
31+
end
32+
if sum(is_there_a_man) < n_min_pots && sum(is_there_a_wall) < n_min_pots %pokud bude mozny vubec nejaky pohyb do vrstvy s nizsim potencialem
33+
%pocet volnych bunek s nejnizsim potencialem
34+
free_spots = n_min_pots - sum(is_there_a_man);
35+
%nahodne vybere jednu v dostupnych volnych pozic
36+
r = randi(free_spots);
37+
%ted vyselektuju, kterou volnou pozici jsme vlastne vybrali
38+
free_spot_position = find(is_there_a_man == 0);
39+
selected_free_spot = free_spot_position(r);
40+
selected_neigh_row = neighborhood(indeces_of_min_pot(selected_free_spot),:);
41+
42+
new_position_people(position_to_be_updated(1),position_to_be_updated(2)) = 0;
43+
new_position_people(selected_neigh_row(1),selected_neigh_row(2)) = 1;
44+
45+
46+
elseif sum(is_there_a_man) == n_min_pots || sum(is_there_a_wall) == n_min_pots %pokud se nelze pohnout z duvodu preplnenosti nebo sten do vrstvy s nejnizsim potencialem
47+
sec_min_pot = min(neighborhood(:,5))+1;
48+
%nalezeni radku s druhou minimální hodnotou potencialu
49+
indeces_of_sec_min_pot = find(neighborhood(:,5)==sec_min_pot);
50+
%pocet radku s timto potencialem
51+
[n_sec_min_pots,~] = size(indeces_of_sec_min_pot);
52+
%nejdriv je snažíme tlacit na pole s minimalnim potencialem
53+
is_there_a_man = 0;
54+
is_there_a_wall = 0;
55+
for ind = 1:n_sec_min_pots
56+
is_there_a_man(ind) = neighborhood(indeces_of_sec_min_pot(ind),4);
57+
is_there_a_wall(ind) = neighborhood(indeces_of_sec_min_pot(ind),3);
58+
end
59+
if sum(is_there_a_man) < n_sec_min_pots && sum(is_there_a_wall) < n_sec_min_pots %pokud bude mozny vubec nejaky pohyb
60+
%pocet volnych bunek s nejnizsim potencialem
61+
free_spots = n_sec_min_pots - sum(is_there_a_man);
62+
%nahodne vybere jednu v dostupnych volnych pozic
63+
r = randi(free_spots);
64+
%ted vyselektuju, kterou volnou pozici jsme vlastne vybrali
65+
free_spot_position = find(is_there_a_man == 0);
66+
selected_free_spot = free_spot_position(r);
67+
selected_neigh_row = neighborhood(indeces_of_sec_min_pot(selected_free_spot),:);
68+
69+
new_position_people(position_to_be_updated(1),position_to_be_updated(2)) = 0;
70+
new_position_people(selected_neigh_row(1),selected_neigh_row(2)) = 1;
71+
end
72+
73+
end
74+
else %aktualizace prazdne bunky je zalozena na tom, ze se tam prednostne tlaci spis lidi s vetsim potencialem a az potom ti na stejne urovni
75+
if isnan(neighborhood(5,5)) %5. radek pole neighborhood odpovida bodu, ktery prave aktualizujeme, 5. sloupec pokud ma hodnotu NAN znamena, ze je tam zed/sloup
76+
;
77+
else
78+
max_pot = max(neighborhood(:,5));
79+
%nalezeni radku s maximalni hodnotou potencialu
80+
indeces_of_max_pot = find(neighborhood(:,5)==max_pot);
81+
%pocet radku s tim maximalnim potencialem
82+
[n_max_pots,~] = size(indeces_of_max_pot);
83+
is_there_a_man = 0;
84+
for ind = 1:n_max_pots
85+
is_there_a_man(ind) = neighborhood(indeces_of_max_pot(ind),4);
86+
end
87+
if sum(is_there_a_man) > 0 %pokud bude mozny vubec nejaky pohyb do vrstvy s nizsim potencialem
88+
%pocet plnych bunek s nejvyssim potencialem
89+
full_spots = sum(is_there_a_man);
90+
%nahodne vybere jednu z dostupnych plnych pozic
91+
r = randi(full_spots);
92+
%ted vyselektuju, kterou plnou pozici jsme vlastne vybrali
93+
full_spot_position = find(is_there_a_man == 1);
94+
selected_full_spot = full_spot_position(r);
95+
selected_neigh_row = neighborhood(indeces_of_max_pot(selected_full_spot),:);
96+
97+
new_position_people(position_to_be_updated(1),position_to_be_updated(2)) = 1;
98+
new_position_people(selected_neigh_row(1),selected_neigh_row(2)) = 0;
99+
elseif sum(is_there_a_man) == 0 %z vrstvy s nejvyssim potencialem nema kdo sejit niz
100+
sec_max_pot = max(neighborhood(:,5))-1;
101+
%nalezeni radku s druhou nejvyssi hodnotou potencialu
102+
indeces_of_sec_max_pot = find(neighborhood(:,5)==sec_max_pot);
103+
%pocet radku s timto potencialem
104+
[n_sec_max_pots,~] = size(indeces_of_sec_max_pot);
105+
%nejdriv je snažíme tlacit na pole s minimalnim potencialem
106+
is_there_a_man = 0;
107+
for ind = 1:n_sec_max_pots
108+
is_there_a_man(ind) = neighborhood(indeces_of_sec_max_pot(ind),4);
109+
end
110+
if sum(is_there_a_man) > 0 %pokud bude mozny vubec nejaky pohyb
111+
%pocet plnych bunek s nejvyssim potencialem
112+
full_spots = sum(is_there_a_man);
113+
%nahodne vybere jednu z dostupnych plnych pozic
114+
r = randi(full_spots);
115+
%ted vyselektuju, kterou plnou pozici jsme vlastne vybrali
116+
full_spot_position = find(is_there_a_man == 1);
117+
selected_full_spot = full_spot_position(r);
118+
selected_neigh_row = neighborhood(indeces_of_sec_max_pot(selected_full_spot),:);
119+
120+
new_position_people(position_to_be_updated(1),position_to_be_updated(2)) = 1;
121+
new_position_people(selected_neigh_row(1),selected_neigh_row(2)) = 0;
122+
elseif sum(is_there_a_man) == 0 %pokud ani z druheho nejvyssiho potencialu neni mozne sejit niz
123+
thrd_max_pot = max(neighborhood(:,5))-2;
124+
if thrd_max_pot >= neighborhood(5,5) %vezmu jeste treti mozny potencial, nesmi ale byt nizsi nez ten, ktery prislusi prazdne bunce, kterou se snazim aktualizovat
125+
%nalezeni radku s treti nejvyssi hodnotou potencialu
126+
indeces_of_thrd_max_pot = find(neighborhood(:,5)==thrd_max_pot);
127+
%pocet radku s timto potencialem
128+
[n_thrd_max_pots,~] = size(indeces_of_thrd_max_pot);
129+
%nejdriv je snažíme tlacit na pole s minimalnim potencialem
130+
is_there_a_man = 0;
131+
for ind = 1:n_thrd_max_pots
132+
is_there_a_man(ind) = neighborhood(indeces_of_thrd_max_pot(ind),4);
133+
end
134+
if sum(is_there_a_man) > 0 %pokud bude mozny vubec nejaky pohyb
135+
%pocet plnych bunek s nejvyssim potencialem
136+
full_spots = sum(is_there_a_man);
137+
%nahodne vybere jednu z dostupnych plnych pozic
138+
r = randi(full_spots);
139+
%ted vyselektuju, kterou plnou pozici jsme vlastne vybrali
140+
full_spot_position = find(is_there_a_man == 1);
141+
selected_full_spot = full_spot_position(r);
142+
selected_neigh_row = neighborhood(indeces_of_thrd_max_pot(selected_full_spot),:);
143+
144+
new_position_people(position_to_be_updated(1),position_to_be_updated(2)) = 1;
145+
new_position_people(selected_neigh_row(1),selected_neigh_row(2)) = 0;
146+
end
147+
end
148+
end
149+
end
150+
151+
152+
153+
end
154+
155+
end
156+
%pokud bude plna bunka se souradnicemi "exit", pred vykreslenim ji vzdy
157+
%vyprazdnim
158+
159+
if new_position_people(exit(1),exit(2)) == 1
160+
new_position_people(exit(1),exit(2)) = 0;
161+
end
162+
163+
end

source/Floor_field_model.m

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
%% FLOOR FIELD MODEL - spousteci skript
2+
3+
%% uklid
4+
close all
5+
clear variables
6+
7+
%% Nastaveni konstant (pomoci fce 'params.m')
8+
% lze vytvorit nekolik ruznych sad pocatecnich parametru, treba fce
9+
% 'params1.m', 'params2.m' atd)
10+
11+
params = parameters(4);
12+
P = params.P;
13+
Q = params.Q;
14+
loc_of_exit = params.exit;
15+
mtx_loc_of_pillars = params.pillars;
16+
num_of_peds = params.pedestrians;
17+
18+
%[num_of_peds, P, Q, mtx_loc_of_pillars, loc_of_exit, animation_show] = params();
19+
%[num_of_peds, P, Q, mtx_loc_of_pillars, loc_of_exit, animation_show] = params_big_room_full(); % pozor: Dijkstra bezi cca 4min na tak velke mape
20+
%[num_of_peds, P, Q, mtx_loc_of_pillars, loc_of_exit, animation_show] = params_big_room_empty(); % pozor: Dijkstra bezi cca 4min na tak velke mape
21+
22+
animation_show = true;
23+
%% Nastaveni mapy, rozmisteni sloupu a sten
24+
walls = double(isnan(get_map (P, Q, loc_of_exit, mtx_loc_of_pillars))); % AG: melo by to vratit mapu, kde na vsech "nevkrocitelnych" polich je 1, a na volnych 0
25+
% nevim, kde presne se to pouzije, ale jestli je potreba, tak tu je.
26+
27+
%% -------------------------- simulace FFM
28+
n_simulations = 30; % počet simulácií
29+
iterations = ones(n_simulations, 1); % počet krokov do úplnej evakuácie miestnosti
30+
rho = []; % prázdne pole pre ukladanie hustôt
31+
32+
rng(1) % pevný seed
33+
34+
for i = 1:n_simulations
35+
%% Vypocet potencialu na mape (fce 'get_grad_field.m' od AG)
36+
tStart = tic;
37+
levels = get_grad_field(P, Q, loc_of_exit, mtx_loc_of_pillars); % Dijkstra runs inside
38+
tEnd = toc(tStart)
39+
'log: get_grad_field.m successfully done'
40+
41+
%% Umisteni chodcu do mistnosti (fce 'get_pedestrians.m' od SM)
42+
position_people = get_pedestrians(P, Q, mtx_loc_of_pillars, num_of_peds);
43+
'log: get_pedestrians.m successfully done'
44+
45+
%% Pomocna matice pro vykresleni polohy exitu zelenou barvou
46+
exit_matrix = 0*position_people; %stejne rozmery jako matice position people
47+
exit_matrix(loc_of_exit(1),loc_of_exit(2)) = 1;
48+
49+
while (sum(sum(position_people)) ~= 0)
50+
[row_num,col_num] = size(position_people);
51+
%budu se snazit generovat cisla pouze z te zaplnene casti, abych to
52+
%urychlila
53+
first_nonempty_col = 1;
54+
while sum(position_people(:,first_nonempty_col)) == 0 && (first_nonempty_col + 1) <= (col_num - 1)
55+
first_nonempty_col = first_nonempty_col + 1;
56+
end
57+
58+
%ind_row a ind_col budou indexy bunky, kterou prave aktualizuju, nesmi
59+
%to byt nic z okraju pole
60+
ind_row = randi([2,row_num-1]);
61+
ind_col = randi([first_nonempty_col,col_num-1]);
62+
63+
position_people = DECISION([ind_row,ind_col],position_people,levels,walls,loc_of_exit);
64+
R = 255 * (-position_people+1) - 255*exit_matrix;
65+
G = 255 * (-position_people+1)-255*walls;
66+
B = 255 * (-position_people+1)-255*walls - 255*exit_matrix;
67+
res = cat(3,R,G,B);
68+
69+
% %plot result
70+
% if animation_show == true
71+
% imshow(res,'InitialMagnification',20000)
72+
% pause(0.07);
73+
% end
74+
75+
% Hustota chodcov v miestnosti v danej iterácii
76+
rho = [rho; stats(P, Q, mtx_loc_of_pillars, position_people)];
77+
78+
iterations(i) = iterations(i)+1;
79+
end
80+
end
81+
82+
% Stredný počet krokov potrebný pre evakuáciu miestnosti
83+
[mu, delta] = expectation(iterations, n_simulations);
84+
histogram(iterations)
85+
xlabel("number of steps",'interpreter','latex')
86+
ylabel("frequency",'interpreter','latex')
87+
set(gca,'TickLabelInterpreter','latex')
88+
89+
'Done.'
90+
91+
92+
93+
94+
95+
96+
97+
98+
99+
100+
101+
102+
103+
104+

source/GET_OKOLI.m

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
function okoli = GET_OKOLI(ped,pozice_lidi,urovne,zdi)
2+
%ped jsou souradnice bunky, kterou jsem se rozhodla aktualizovat, nesmi to
3+
%byt z kraje mrizky, tam jsou proste steny
4+
okoli = nan(9,5);
5+
okoli(1,1) = ped(1)-1;
6+
okoli(1,2) = ped(2)-1;
7+
okoli(1,3) = zdi(okoli(1,1),okoli(1,2));
8+
okoli(1,4) = pozice_lidi(okoli(1,1),okoli(1,2));
9+
okoli(1,5) = urovne(okoli(1,1),okoli(1,2));
10+
11+
12+
okoli(2,1) = ped(1)-1;
13+
okoli(2,2) = ped(2);
14+
okoli(2,3) = zdi(okoli(2,1),okoli(2,2));
15+
okoli(2,4) = pozice_lidi(okoli(2,1),okoli(2,2));
16+
okoli(2,5) = urovne(okoli(2,1),okoli(2,2));
17+
18+
19+
okoli(3,1) = ped(1)-1;
20+
okoli(3,2) = ped(2)+1;
21+
okoli(3,3) = zdi(okoli(3,1),okoli(3,2));
22+
okoli(3,4) = pozice_lidi(okoli(3,1),okoli(3,2));
23+
okoli(3,5) = urovne(okoli(3,1),okoli(3,2));
24+
25+
26+
okoli(4,1) = ped(1);
27+
okoli(4,2) = ped(2)-1;
28+
okoli(4,3) = zdi(okoli(4,1),okoli(4,2));
29+
okoli(4,4) = pozice_lidi(okoli(4,1),okoli(4,2));
30+
okoli(4,5) = urovne(okoli(4,1),okoli(4,2));
31+
32+
33+
okoli(5,1) = ped(1);
34+
okoli(5,2) = ped(2);
35+
okoli(5,3) = zdi(okoli(5,1),okoli(5,2));
36+
okoli(5,4) = pozice_lidi(okoli(5,1),okoli(5,2));
37+
okoli(5,5) = urovne(okoli(5,1),okoli(5,2));
38+
39+
40+
okoli(6,1) = ped(1);
41+
okoli(6,2) = ped(2)+1;
42+
okoli(6,3) = zdi(okoli(6,1),okoli(6,2));
43+
okoli(6,4) = pozice_lidi(okoli(6,1),okoli(6,2));
44+
okoli(6,5) = urovne(okoli(6,1),okoli(6,2));
45+
46+
47+
okoli(7,1) = ped(1)+1;
48+
okoli(7,2) = ped(2)-1;
49+
okoli(7,3) = zdi(okoli(7,1),okoli(7,2));
50+
okoli(7,4) = pozice_lidi(okoli(7,1),okoli(7,2));
51+
okoli(7,5) = urovne(okoli(7,1),okoli(7,2));
52+
53+
54+
okoli(8,1) = ped(1)+1;
55+
okoli(8,2) = ped(2);
56+
okoli(8,3) = zdi(okoli(8,1),okoli(8,2));
57+
okoli(8,4) = pozice_lidi(okoli(8,1),okoli(8,2));
58+
okoli(8,5) = urovne(okoli(8,1),okoli(8,2));
59+
60+
61+
okoli(9,1) = ped(1)+1;
62+
okoli(9,2) = ped(2)+1;
63+
okoli(9,3) = zdi(okoli(9,1),okoli(9,2));
64+
okoli(9,4) = pozice_lidi(okoli(9,1),okoli(9,2));
65+
okoli(9,5) = urovne(okoli(9,1),okoli(9,2));
66+
67+
end
68+

0 commit comments

Comments
 (0)