If you're seeing this message, it means we're having trouble loading external resources on our website.

Ако си зад уеб филтър, моля, увери се, че домейните *. kastatic.org и *. kasandbox.org са разрешени.

Основно съдържание

Случайни раходки

Преди да се захванем със сложната материя на векторите и на движението, основано на физиката, да помислим какво означава това нещо да се движи по екрана. Да започнем с добра позната и проста симулация на движение – случайна походка.
Представи си, че стоиш в средата на балансираща греда. На всеки 10 секунди хвърляш монета. Ако се падне ези, пристъпваш напред. Ако се падне тура – отстъпваш назад. Това е случайна походка – път, дефиниран от случайни стъпки. Ако стъпиш извън гредата, някъде по пода, можеш да изпълниш случайната походка в две измерения, като хвърляш монетата по 2 пъти със следните резултати:
Хвърляне 1Хвърляне 2Резултат
ЕзиЕзиСтъпка напред.
ЕзиТураСтъпка надясно.
ТураЕзиСтъпка наляво.
ТураТураСтъпка назад.
Да, това може да ти изглежда като недодялан алгоритъм. Въпреки това случайната походка може да се използва за моделиране на събития, които се проявяват в реалния свят – от движението на молекули в газ до поведението на играч, който прекарва деня си в казино. Що се отнася до нас, ние започваме тази тема, като изучаваме случайната походка с 3 цели наум.

Обектът Random Walker

Нека първо да разгледаме малко от обектно-ориентираното програмиране (ООП), като създадем обекта Walker. Това ще бъде само бегъл преглед. Ако не си много наясно с ООП, по-добре мини през секцията за Обектно-ориентиран JavaScript.
Обектът в JavaScript е тип данни, който има свойства и функционалност, които са прикрепени към него чрез неговия прототип. Ние искаме да създадем обект Walker, който следи своите данни (къде съществува на екрана) и има умението да изпълнява определени действия (например да нарисува себе си или да нарави стъпка).
За да създадем инстанции на обекта Walker, трябва да дефинираме обект Walker. Ще използваме този обект като форма за курабийки като всяка нова инстанция на Walker са курабийките.
Да започнем, като дефинираме типа на обекта Walker. Обектът Walker се нуждае само от две порции данни – число за неговата позиция х и друго за позицията y. Ще ги зададем в конструктора, като поставим обекта в центъра на платното.
var Walker = function() {
    this.x = width/2;
    this.y = height/2;
};
Освен да следи за позициите си х и y, нашият обект Walker ще има и методи, които можем да извикваме. Първият ще бъде метод, който позволява на обекта да се визуализира като черна точка. Запомни, че, когато добавяме методи към обект в JavaScript, ги прикрепяме към прототипа prototype на обекта,
Walker.prototype.display = function() {
    stroke(0, 0, 0);
    point(this.x, this.y);
};
Вторият метод насочва обекта Walker да направи стъпка. И тук нещата стават малко по-интересни. Спомняш ли си онзи под, върху който правим случайни стъпки? Добре, сега можем да използваме нашето платно по същия начин. Има четири възможни стъпки. Стъпка надясно може да бъде симулирана с увеличаване на x (x++); наляво – с намаляване на x (x--); напред – намаляме с един пиксел (y++); и назад – увеличаваме с един пиксел (y--). Как избираме между тези четири избора? По-рано казахме, че можем да хвърляме две монети. В ProcessingJS, обаче, когато искаме да изберем случайна стойност от списък с възможности, можем да изберем случайно число, като използваме random().
Walker.prototype.walk = function() {
    var choice = floor(random(4));
};
Горният ред взима случайно число с плаваща запетая между 0 и 4 и го превръща в цяло число, като използва floor(), а резултатът е 0, 1, 2 или 3. Технически, най-голямото число никога няма да е 4,0, а по-скоро 3,999999999 (с толкова цифри 9, колкото са позициите след десетичната запетая); тъй като floor() връща най-близкото цяло число, което е по-малко или равно, най-високият резултат, който можем да получим, ще бъде 3.. След това правим съответната стъпка (наляво, надясно, нагоре или надолу) според това кое случайно число сме избрали.
Walker.prototype.walk = function() {
    var choice = floor(random(4));
    if (choice === 0) {
        this.x++;
    } else if (choice === 1) {
        this.x--;
    } else if (choice === 2) {
        this.y++;
    } else {
        this.y--;
    } 
};
След като написахме класа е време да направим действителен обект Walker в нашата програма. Да речем, че искаме да моделираме само една случайна походка в нашата програма, декларираме и инициализираме една глобална променлива от типа Walker, като извикваме функцията конструктор с оператора new.
var w = new Walker();
За да накараме нашия обект действително да прави нещо, дефинираме функцията draw() и казваме на обекта да прави стъпка и да се рисува всеки път, когато е извикан:
draw = function() {
    w.walk();
    w.display();
};
Тъй като не извикваме background() във функцията за рисуване, можем да видим следата от случайната походка по платното:

Подобрение на случайната походка

Има няколко подобрения, които можем да приложим към обекта със случайна походка. За начало изборът на стъпки за обекта е ограничен до четири възможности – нагоре, надолу, наляво и надясно. Но всеки пиксел на прозореца има осем възможни съседа, а деветата възможност е да остане на същото място.
Фигура I.1
За да имплементираме обект Walker, който може да стъпи върху всеки съседен пиксел (или да остане на мястото си), можем да избираме число между 0 и 8 (девет възможни избора). По-ефективен начин да напишем този код ще бъде просто да избираме от три възможни стъпки по оста х (-1, 0 или 1) и три възможни стъпки по оста y.
Walker.prototype.walk = function() {
  var stepx = floor(random(3))-1;
  var stepy = floor(random(3))-1;
  this.x += stepx;
  this.y += stepy;
};
Ако продължим по този начин, можем да използваме десетично число за x и y и да се движим по случайно зададена стойност между -1 и 1 – ако нашата среда може да покаже разликата между "2,2" и "2,4":
Walker.prototype.walk = function() {
  var stepx = random(-1, 1);
  var stepy = random(-1, 1);
  this.x += stepx;
  this.y += stepy;
};
Всички тези вариации на "традиционната" случайна походка имат едно общо нещо: във всеки един момент вероятността обектът Walker да направи стъпка в дадена посока (или въобще да не се движи) е равна на вероятността обектът Walker да направи стъпка във всяка посока. С други думи, ако има четири възможни стъпки, има шанс 1 на 4 (25%) обектът Walker да направи всяка стъпка. С девет възможни стъпки, шансът е 1 на 9 (или 11,1%).
За наше удобство функцията random() работи точно така. Нейният генератор на случайни числа произвежда това, което е известно като "равномерно" разпределение на числа. Можем да проверим това разпределение с програма, която отчита всеки път, когато се избере дадено число, и го показва графично като височина на правоъгълник:
Дали правоъгълниците са с еднаква височина след няколко минути на изпълнение? Вероятно не. Нашият прост размер (т.е. броят на случайните числа, които избираме) е доста малък и се случва да има несъответствия, в които определени числа се избират по-често. С времето и с добър генератор на случайни числа, това ще се изглади.
Случайните числа, които получаваме от фунцията random(), не са наистина случайни; затова те са известни като псевдо-случайни. Те са резултат от математическа функция, която симулира случайност. С времето тази функция ще покаже шаблон, но този период от време е толкова дълъг за нас, че може да се приеме за числа случайност!
В следващия раздел ще говорим за различните начини, по които можем да създаваме обекти, които имат "тенденцията" да се движат в определени посоки. Преди да се потопиш в това, има предизвикателство, което те очаква!
Курсът "Компютърни симулации на физични явления" е производeн на "Природата на кода" от Даниел Шифман, използвана от Creative Commons Attribution-NonCommercial 3,0 Unported License.

Искаш ли да се присъединиш към разговора?

  • Аватар leafers seedling style за потребителя Петко  Попов
    Този Дан Шифман ме преследва (навсякъде в youtube_то е ) наскоро от него учих ГИТ системата :)
    (2 гласа)
    Аватар Default Khan Academy avatar за потребителя
Разбираш ли английски? Натисни тук, за да видиш още дискусии в английския сайт на Кан Академия.