Симуляция агрессивный, пассивный, альтруист — различия между версиями
Материал из Department of Theoretical and Applied Mechanics
Nathan (обсуждение | вклад) |
Nathan (обсуждение | вклад) (→Инструкция по использованию) |
||
(не показана 1 промежуточная версия этого же участника) | |||
Строка 3: | Строка 3: | ||
# Вся система состоит из неограниченного числа итераций длинной несколько секунд. | # Вся система состоит из неограниченного числа итераций длинной несколько секунд. | ||
# В начале итерации на квадратном поле случайным образом расположено одинаковое число пищи. | # В начале итерации на квадратном поле случайным образом расположено одинаковое число пищи. | ||
− | # Черепахе любой модели поведения необходимо употребить 1 пищу, чтобы выжить и продолжить существовать в следующей итерации, 2 пищи, чтобы выжить и дать потомство в количестве одной черепахи, чья модель поведения совпадает с моделью родителя, но может измениться с какой-то вероятностью(вероятность мутации) на одну из двух других моделей, больше | + | # Черепахе любой модели поведения необходимо употребить 1 пищу, чтобы выжить и продолжить существовать в следующей итерации, 2 пищи, чтобы выжить и дать потомство в количестве одной черепахи, чья модель поведения совпадает с моделью родителя, но может измениться с какой-то вероятностью(вероятность мутации) на одну из двух других моделей, больше 2 употребить невозможно. Если же не было употреблено пищи совсем, то на следующей итерации черепаха исчезает. |
# Модель поведения "пассивный" заключается в случайном блуждании по полю в поиске пищи. | # Модель поведения "пассивный" заключается в случайном блуждании по полю в поиске пищи. | ||
# Модель поведения "агрессивный" заключается в преимущественном случайном блуждании по полю в поиске пищи, однако при недостатке пищи для выживания черепаха будет пытаться отобрать еду у ближайшей сытой черепахи любой модели поведения. | # Модель поведения "агрессивный" заключается в преимущественном случайном блуждании по полю в поиске пищи, однако при недостатке пищи для выживания черепаха будет пытаться отобрать еду у ближайшей сытой черепахи любой модели поведения. | ||
− | # Модель поведения "альтруист" заключается в преимущественном случайном блуждании по полю в поиске пищи, однако если будет употреблено 2 пищи то черепаха будет | + | # Модель поведения "альтруист" заключается в преимущественном случайном блуждании по полю в поиске пищи, однако если будет употреблено 2 пищи то черепаха будет стремиться отдать 1 пищу ближайшей голодной черепахе любой модели поведения. |
== Основные допущения и ограничения == | == Основные допущения и ограничения == | ||
Строка 17: | Строка 17: | ||
* Чтобы ускорить симуляцию изменяйте значение параметра "simulation speed". | * Чтобы ускорить симуляцию изменяйте значение параметра "simulation speed". | ||
* Чтобы начать симуляцию нажмите кнопку "start simulation", а чтобы закончить - "end simulation". | * Чтобы начать симуляцию нажмите кнопку "start simulation", а чтобы закончить - "end simulation". | ||
− | * Симуляцию можно приостановить нажав кнопку "stop". | + | * Симуляцию можно приостановить, нажав кнопку "stop". |
* Можно разрешить черепахам мутировать только в определённые модели поведения, поставив возле соответствующего поля галочку. | * Можно разрешить черепахам мутировать только в определённые модели поведения, поставив возле соответствующего поля галочку. | ||
В симуляции агрессивные черепахи раскрашены рыжим цветом, пассивные - болотным, альтруисты - зелёным. На графиках это отображается красным, жёлтым и зелёным соответственно. | В симуляции агрессивные черепахи раскрашены рыжим цветом, пассивные - болотным, альтруисты - зелёным. На графиках это отображается красным, жёлтым и зелёным соответственно. | ||
+ | |||
== Симуляция == | == Симуляция == | ||
{{#widget:Iframe | url=http://tm.spbstu.ru/htmlets/js2020/Simulation%20agr%20pas%20alt/Simulation.html| width=1200 | height=1400 | border=0}} | {{#widget:Iframe | url=http://tm.spbstu.ru/htmlets/js2020/Simulation%20agr%20pas%20alt/Simulation.html| width=1200 | height=1400 | border=0}} |
Текущая версия на 12:32, 1 июня 2020
Содержание
Формулировка задачи[править]
Дана абстрактная система, в начальный момент состоящая из пищи и какого-то количества существ(черепах) каждой модели поведения из трёх возможных - агрессивный, пассивный, альтруист. Необходимо построить симуляцию данной системы. Её условия таковы:
- Вся система состоит из неограниченного числа итераций длинной несколько секунд.
- В начале итерации на квадратном поле случайным образом расположено одинаковое число пищи.
- Черепахе любой модели поведения необходимо употребить 1 пищу, чтобы выжить и продолжить существовать в следующей итерации, 2 пищи, чтобы выжить и дать потомство в количестве одной черепахи, чья модель поведения совпадает с моделью родителя, но может измениться с какой-то вероятностью(вероятность мутации) на одну из двух других моделей, больше 2 употребить невозможно. Если же не было употреблено пищи совсем, то на следующей итерации черепаха исчезает.
- Модель поведения "пассивный" заключается в случайном блуждании по полю в поиске пищи.
- Модель поведения "агрессивный" заключается в преимущественном случайном блуждании по полю в поиске пищи, однако при недостатке пищи для выживания черепаха будет пытаться отобрать еду у ближайшей сытой черепахи любой модели поведения.
- Модель поведения "альтруист" заключается в преимущественном случайном блуждании по полю в поиске пищи, однако если будет употреблено 2 пищи то черепаха будет стремиться отдать 1 пищу ближайшей голодной черепахе любой модели поведения.
Основные допущения и ограничения[править]
- Начальное число черепах каждой модели поведения ограничено 20 .
- Число пищи ограничено 60.
- Длительность одной итерации ограничена 30 секундами.
Инструкция по использованию[править]
- Чтобы изменить какой-то параметр введите в строку число не превышающее установленных границ. Разрешены только символы цифр 0-9.
- Чтобы ускорить симуляцию изменяйте значение параметра "simulation speed".
- Чтобы начать симуляцию нажмите кнопку "start simulation", а чтобы закончить - "end simulation".
- Симуляцию можно приостановить, нажав кнопку "stop".
- Можно разрешить черепахам мутировать только в определённые модели поведения, поставив возле соответствующего поля галочку.
В симуляции агрессивные черепахи раскрашены рыжим цветом, пассивные - болотным, альтруисты - зелёным. На графиках это отображается красным, жёлтым и зелёным соответственно.
Симуляция[править]
Текст программы на языке JavaScript (разработчики Фурманов Натан и Курмакаева Алсу):
Файл "Main script.js"
1 window.addEventListener('load', main, false);
2
3 function main() {
4
5 ctx = main_canvas.getContext('2d');
6 w = main_canvas.width;
7 h = main_canvas.height;
8 ctxp = population_canvas.getContext('2d');
9 wp = population_canvas.width;
10 hp = population_canvas.height;
11 ctxm = mean_canvas.getContext('2d');
12 wm = mean_canvas.width;
13 hm = mean_canvas.height;
14 var end = true;
15 var image = document.getElementById('source');
16
17
18 function food(x=0, y=0){
19 this.x = x;
20 this.y = y;
21
22 this.info = function(){
23 return [this.x, this.y];
24 }
25
26 this.draw= function(){
27 ctx.drawImage(image, this.x-10, this.y-10, 20, 20);
28 }
29 }
30
31
32 Run_button.onclick = function(){
33
34 if (!end) {
35 end = true;
36 Stop_button.value = 'stop';
37 return
38 }
39
40 console.log('|___________________NEW SIMULATION___________________|')
41 ctxp.clearRect(0,0,wp,hp);
42 ctxm.clearRect(0,0,wp,hp);
43
44 Run_button.value = 'end simulation';
45 Stop_button.disabled = false;
46 Population_pas_input.disabled = true;
47 Population_agr_input.disabled = true;
48 Population_alt_input.disabled = true;
49 Food_supply_input.disabled = true;
50 Durability_input.disabled = true;
51 Mutation_input.disabled = true;
52 passive_mutation_allowed.disabled = true;
53 aggressive_mutation_allowed.disabled = true;
54 altruistic_mutation_allowed.disabled = true;
55 end = false;
56
57 fps = 100;
58 dt = 1/fps;
59 iteration_durability = Durability_input.value;
60 var iteration = 0;
61 var simulation_speed = Simulation_speed_input.value;;
62
63 var Start_population = parseInt(Population_pas_input.value)+parseInt(Population_agr_input.value)+parseInt(Population_alt_input.value);
64 var Alt_population = [parseInt(Population_alt_input.value)];
65 var Pas_population = [parseInt(Population_pas_input.value)];
66 var Agr_population = [parseInt(Population_agr_input.value)];
67 var Population = [Start_population];
68
69 var Turtles = [];
70 var velocity = 100;
71 var size = 15;
72 var viewing_radius = 150;
73
74 var Mutation_probability = Mutation_input.value/100;
75
76 var Food_quantity = Food_supply_input.value;
77 var Current_food_quantity = Food_quantity;
78
79 for (var i=0; i<Population_pas_input.value; i++){
80 Turtles.push(new Turtle((w-2*size)*Math.random()+size, h-(h-2*size)*Math.random()-size,
81 velocity, size, viewing_radius,'passive'));
82 }
83 for (var i=0; i<Population_agr_input.value; i++){
84 Turtles.push(new Turtle((w-2*size)*Math.random()+size, h-(h-2*size)*Math.random()-size,
85 velocity, size, viewing_radius,'aggressive'));
86 }
87 for (var i=0; i<Population_alt_input.value; i++){
88 Turtles.push(new Turtle((w-2*size)*Math.random()+size, h-(h-2*size)*Math.random()-size,
89 velocity, size, viewing_radius,'altruistic'));
90 }
91
92
93 console.log('Population: '+Population[iteration]);
94 console.log('Altruistic population: '+Alt_population[iteration]);
95 console.log('Passive population: '+Pas_population[iteration]);
96 console.log('Aggressive population: '+Agr_population[iteration]);
97
98
99 var Food_supply = [];
100 for (var i=0; i<Current_food_quantity; i++){
101 Food_supply.push(new food(w*Math.random(), h*Math.random()));
102 }
103
104
105
106
107
108 function move(){
109 var turn_propobility = 0.05;
110
111 for (var i=0; i<Population[iteration]; i++){
112 var best_food_distance = viewing_radius;
113 var best_turtle_distance = viewing_radius;
114 var target_name = 'food';
115
116 if ((Turtles[i].satiety < 2)||(Turtles[i].gender == 'altruistic')){
117 for (var j=0; j<Current_food_quantity; j++){
118 var distance = Math.sqrt(Math.pow(Food_supply[j].x-Turtles[i].x,2)+
119 Math.pow(Food_supply[j].y-Turtles[i].y,2));
120
121 if ((distance < best_food_distance)&&(Turtles[i].satiety < 2)){
122 Turtles[i].target = j;
123 best_food_distance = distance;
124 target_name = 'food';
125 }
126 }
127 if ((Turtles[i].gender == 'aggressive')&&(Turtles[i].target == -1)&&(Turtles[i].satiety==0)){
128 for (var j=0; j<Population[iteration]; j++){
129 var distance = Math.sqrt(Math.pow(Turtles[j].x-Turtles[i].x,2)+
130 Math.pow(Turtles[j].y-Turtles[i].y,2));
131
132 if ((distance < best_turtle_distance)&&(i!=j)&&(Turtles[j].satiety == 2)){
133 Turtles[i].target = j;
134 best_turtle_distance = distance;
135 target_name = 'turtle';
136 }
137 }
138 }
139 if ((Turtles[i].gender == 'altruistic')&&(Turtles[i].target == -1)&&(Turtles[i].satiety==2)){
140 for (var j=0; j<Population[iteration]; j++){
141 var distance = Math.sqrt(Math.pow(Turtles[j].x-Turtles[i].x,2)+
142 Math.pow(Turtles[j].y-Turtles[i].y,2));
143
144 if ((distance < best_turtle_distance)&&(i!=j)&&(Turtles[j].satiety == 0)){
145 Turtles[i].target = j;
146 best_turtle_distance = distance;
147 target_name = 'turtle';
148 }
149 }
150 }
151
152 if (Turtles[i].target != -1){
153 var target = Turtles[i].target;
154
155 if (target_name == 'food'){
156 Turtles[i].moveTo(Food_supply[target].x, Food_supply[target].y);
157 var best_food_distance = viewing_radius;
158
159 var distance = Math.sqrt(Math.pow(Food_supply[target].x-Turtles[i].x,2)+
160 Math.pow(Food_supply[target].y-Turtles[i].y,2));
161 if (distance <= 1.5*Turtles[i].size){
162 Turtles[i].satiety++;
163 Food_supply.splice(target,1);
164 Current_food_quantity--;
165 }
166 } else if (target_name == 'turtle'){
167 Turtles[i].moveTo(Turtles[target].x, Turtles[target].y);
168 //if (Turtles[i].gender == 'aggressive'){
169 //Turtles[i].moveTo(Turtles[target].x, Turtles[target].y);
170 //}
171
172 var distance = Math.sqrt(Math.pow(Turtles[target].x-Turtles[i].x,2)+
173 Math.pow(Turtles[target].y-Turtles[i].y,2));
174 if (distance <= 1.5*Turtles[i].size){
175 if (Turtles[i].gender == 'aggressive'){
176 Turtles[i].satiety++;
177 Turtles[target].satiety--;
178 } else if (Turtles[i].gender == 'altruistic'){
179 Turtles[i].satiety--;
180 Turtles[target].satiety++;
181 }
182 }
183 }
184
185 Turtles[i].target = -1;
186 } else{
187 Turtles[i].wander(turn_propobility);
188 }
189
190 } else{
191 Turtles[i].wander(turn_propobility);
192 }
193 }
194 }
195
196 function draw(){
197 ctx.clearRect(0,0,w,h);
198 for (var i=0; i<Population[iteration]; i++){
199 Turtles[i].draw();
200 }
201 for (var i=0; i<Current_food_quantity; i++){
202 Food_supply[i].draw();
203 }
204 ctx.fillStyle = "black";
205 ctx.font = "italic 10pt Arial";
206 ctx.textAlign = "left";
207 ctx.fillText('Iteration '+iteration, 10, 20);
208 ctx.fillText('Time '+Math.round((performance.now() - time - stop_time)/100)/10, 10, 40);
209 }
210
211 function control(){
212 if (Population[iteration] != 0){
213 if (Turtles[0].energy < 0){
214 console.log('|___________end of iteration '+iteration+'__________|');
215 console.log('Time: '+(performance.now()-time - stop_time)/1000);
216 time = performance.now();
217 stop_time = 0;
218
219 var N = Population[iteration];
220 var New_population = Population[iteration];
221 for (var i=0; i<N; i++){
222 if (Turtles[i].satiety == 0){
223 Turtles.splice(i,1);;
224 N--;
225 New_population--;
226 i--;
227 } else if (Turtles[i].satiety == 1){
228 Turtles[i].energy = 100;
229 Turtles[i].satiety = 0;
230 } else{
231 var gender = Turtles[i].gender;
232 if (Math.random() <= Mutation_probability){
233 if (gender == 'aggressive'){
234 if (((Math.random() <= 0.5)||(!altruistic_mutation_allowed.checked))&&(passive_mutation_allowed.checked)){
235 gender = 'passive';
236 } else if (altruistic_mutation_allowed.checked){
237 gender = 'altruistic';
238 }
239 } else if (gender == 'altruistic'){
240 if (((Math.random() <= 0.5)||(!aggressive_mutation_allowed.checked))&&(passive_mutation_allowed.checked)){
241 gender = 'passive';
242 } else if (aggressive_mutation_allowed.checked){
243 gender = 'aggressive';
244 }
245 } else if (gender == 'passive'){
246 if (((Math.random() <= 0.5)||(!altruistic_mutation_allowed.checked))&&(aggressive_mutation_allowed.checked)){
247 gender = 'aggressive';
248 } else if (altruistic_mutation_allowed.checked){
249 gender = 'altruistic';
250 }
251 }
252 }
253 Turtles.push(new Turtle(Turtles[i].x+5*size*(2*Math.random()-1),
254 Turtles[i].y+5*size*(2*Math.random()-1),
255 velocity, size, viewing_radius, gender));
256 New_population++;
257 Turtles[i].energy = 100;
258 Turtles[i].satiety = 0;
259 }
260 }
261 iteration++;
262
263 Population.push(New_population);
264
265 var new_passive = 0;
266 var new_aggressive = 0;
267 var new_altruistic = 0;
268 for (var i=0; i<Population[iteration]; i++){
269 if (Turtles[i].gender == 'passive'){
270 new_passive++;
271 } else if (Turtles[i].gender == 'aggressive'){
272 new_aggressive++;
273 } else if (Turtles[i].gender == 'altruistic'){
274 new_altruistic++;
275 }
276 }
277 Alt_population.push(new_altruistic);
278 Agr_population.push(new_aggressive);
279 Pas_population.push(new_passive);
280
281 console.log('Population: '+Population[iteration]);
282 console.log('Altruistic population: '+Alt_population[iteration]);
283 console.log('Passive population: '+Pas_population[iteration]);
284 console.log('Aggressive population: '+Agr_population[iteration]);
285 Population_graph(Alt_population, Pas_population, Agr_population, Population);
286
287 Current_food_quantity = Food_quantity;
288 Food_supply = [];
289 for (var i=0; i<Food_quantity; i++){
290 Food_supply.push(new food(w*Math.random(), h*Math.random()));
291 }
292
293 }else{
294 draw();
295 for (var x=0; x<simulation_speed; x++){
296 move();
297 }
298 }
299 }
300 }
301
302
303
304
305 var stop = false;
306 Stop_button.onclick = function(){
307 if (stop) {
308 stop = false;
309 stop_time = performance.now() - stop_time;
310 Stop_button.value = 'stop';
311 } else {
312 stop = true;
313 stop_time = performance.now() - stop_time;
314 Stop_button.value = 'continue';
315 }
316 }
317
318 simulation = function(){
319 if (!stop){
320 control();
321 }
322 if ((Population[iteration] == 0)||(end)) {
323 console.log('|_____________end of simulation____________|');
324 Run_button.value = 'start simulation';
325 Stop_button.disabled = true;
326 Population_pas_input.disabled = false;
327 Population_agr_input.disabled = false;
328 Population_alt_input.disabled = false;
329 Food_supply_input.disabled = false;
330 Durability_input.disabled = false;
331 Mutation_input.disabled = false;
332 passive_mutation_allowed.disabled = false;
333 aggressive_mutation_allowed.disabled = false;
334 altruistic_mutation_allowed.disabled = false;
335 end = true;
336
337 ctx.clearRect(0,0,w,h);
338 clearInterval(timerId);
339 }
340 }
341
342 Simulation_speed_input.oninput = function() {
343 simulation_speed = Simulation_speed_input.value;
344 Result_speed.value = Simulation_speed_input.value;
345 }
346
347 var time = performance.now();
348 var stop_time = 0;
349 var timerId = setInterval(simulation, 1000/fps);
350
351 }
352 }