Лабораторные работы (2008) (Отчёт)

Посмотреть архив целиком

- 15 -

Московский Энергетический Институт

(Технический Университет)












Лабораторная работа №1


По курсу «Теория игр и исследование операций»









Выполнил: ст. гр. А-13-04

Нехай И. В.

Содержание

Содержание 2

Постановка задачи 3

Описание предметной области 3

Описание табличной модели 3

Таблица 1 4

Таблица 2 4

Таблица 3 5

Таблица 4 5

Таблица 5 6

Таблица 6 6

Пример работы 7

Приложение 7


Постановка задачи

Сформировать модель принятия решений в виде совокупности таблиц решений и написать модуль-интерпретатор для данной модели.

В данной работе моделируется поведение зайцев и волков на некотором непрерывном прямоугольном поле.

Описание предметной области

Данная модель имитирует поведение волков и зайцев в условиях замкнутого пространства и ограниченных ресурсов (травы), со следующими правилами:

  • Все животные могут рождаться и умирать.

  • Рождение животных происходит через некоторое время (срок беременности) после встречи двух животных разного пола и одного вида, готовых к размножению.

  • Смерть животных происходит в следующих случаях:

    • от голода

    • от старости

    • в результате съедания зайца волком

  • Изменение готовности к размножению есть периодический процесс. Степень готовности к размножению у отдельно выбранного животного линейно возрастает до момента встречи с животным противоположного пола, после чего она убывает до 0.

  • Смерть от голода происходит при превышении степенью голода конкретного животного определённого порога. Степень голода линейно убывает со временем, может быть повышена в результате поедания пищи (травы для зайца и зайца для волка).

  • Любое животное, испытывающее голод, не готово к размножению, пока не поест.

  • Опасность, исходящая от волка, превышает, с точки зрения зайца, голод и желание к размножению.

  • Волк считается представляющим опасность, если его расстояние до зайца меньше определённого значения.

  • Видимость всех животных больше ширины поля.

  • Заяц движется к единице травы, пока не достигнет её либо пока она не пропадёт с поля

  • Размножение травы – двух видов:

    • С некоторой вероятностью на каждой итерации добавляется единица травы с произвольными координатами

    • Каждая единица травы с некоторой вероятностью порождает ещё одну единицу неподалёку от себя


Одной из основных целей работы было пронаблюдать «популяционные волны»: волнообразное изменение численности на примере зайцев и травы. Волки были внесены в модель с целью проверки изменений при появлении третьего фактора.

Волки вносят сильный дисбаланс в модель. Стабилизировать модель не удалось, поэтому при наличии волков модель неминуемо приходит к всеобщей гибели.


Описание табличной модели

Модель включает 6 таблиц:

№ п/п

Название

Описание

1

Начало работы

Осуществляет управление началом работы модели

2

Проверка на потомство

Проверяет условия на беременность и запускает рождение потомства

3

Классификация зверей

Проверяет условие на смерть (от голода/старости), выбирает тип животного, передаёт управление в таблицу 4 или 6

4

Действия зайца

Действия зайца: убегание от опасности, поиск еды

5

Размножение

Действия волков и зайцев по размножению

6

Действия волка

Поиск и поедание зайцев волком


Все таблицы полны и непротиворечивы.

Таблица 1


Условие 1

Пауза?

Действие 1

Заглушка


Таблица используется для организации цикла ожидания.


Таблица 2


Условие 1

Самка?

Условие 2

Беременна?

Условие 3

Пора рожать?

Действие 1

Родить потомство


Таблица управляет рождением потомства у животных.

Таблица 3


Условие 1

Пора умереть

Условие 2

Заяц?

Условие 3

Волк?

Действие 1

Умереть


Данная таблица выбирает таблицу для дальнейшего выполнения.

Таблица 4


Условие 1

Опасность?

Условие 2

Голоден?

Условие 3

Еда выбрана?

Условие 4

Еду видно?

Условие 5

Еда достигнута?

Действие 1

Идти к еде

Действие 2

Есть

Действие 3

Бродить на месте

Действие 4

Следующий

Действие 5

Убегать


Таблица 5


Условие 1

Готов к размножению?

Условие 2

Пара выбрана?

Условие 3

Пару видно?

Условие 4

Пара также готова?

Условие 5

Пара достигнута?

Действие 1

Идти к паре

Действие 2

Размножаться

Действие 3

Бродить на месте

Действие 4

Сбросить пару

Действие 5

Следующий


Таблица 6


Условие 1

Голоден?

Условие 2

Еду видно?

Условие 3

Еда достигнута?

Действие 1

Идти к еде

Действие 2

Есть

Действие 3

Бродить на месте

Действие 4

Следующий


Пример работы

На экране волки, зайцы и трава обозначаются точками на черном поле. Зайцам соответствуют белые точки, волкам – красные, траве – зелёные. На графике показан процесс роста травы, вызывающий превосходящий рост числа зайцев, в результате которого травы почти не осталось и наступила стабилизация.


Приложение

Общий код модели слишком объемен, поэтому поместим здесь участки, обрабатывающие проверку условий и выполнение действий. Код в достаточной степени самодокументируемый.

Программа написана на Borland C++.

//---------------------------------------------------------------------------


#include


#pragma hdrstop


#include "Hare.h"

#include "Wolf.h"

#include "Model.h"

#include "StartConfig.h"

#include "Condition.h"


//---------------------------------------------------------------------------


#pragma package(smart_init)


CONDITION(Ended, "Пауза?", 0, 0)

{

if(!m) {

return true;

}

return m->paused || m->creatures.size() == 0;

}


//---------------------------------------------------------------------------


CONDITION(Female, "Самка?", 1, 0)

{

return !(m->getCurrentCreature()->maleGender);

}


CONDITION(Pregnant, "Беременна?", 1, 1)

{

return m->getCurrentCreature()->pregnancy > -1;

}


CONDITION(TimeToBear, "Пора рожать?", 1, 2)

{

return m->getCurrentCreature()->pregnancy <= m->iterNum

&& m->getCurrentCreature()->pregnancy > -1;

}


//---------------------------------------------------------------------------


CONDITION(DeathTime, "Пора умирать?", 2, 0)

{

if(m->getCurrentCreature()) {

return (m->iterNum >= m->getCurrentCreature()->deathIter)

|| m->getCurrentCreature()->canDieOfHunger();

}

return false;

}


CONDITION(IsHare, "Заяц?", 2, 1)

{

return m->isHare();

}


CONDITION(IsWolf, "Волк?", 2, 2)

{

return !m->isHare();

}


//---------------------------------------------------------------------------


CONDITION(HareDanger, "Опасность!?", 3, 0)

{

Hare* h = dynamic_cast(m->getCurrentCreature());


Creature* c = NULL;

float dist = 5;

for(vector::iterator it = m->creatures.begin();

it != m->creatures.end();

it++)

{

if(!(*it)->isHare()) {

float newDist = m->distance(h, *it);

if(newDist < dist && newDist < 0.2) {

c = *it;

dist = newDist;

}

}

}

h->setDanger(c);

if(c) {

return true;

}

return false;

}


CONDITION(HareIsHungry, "Голоден?", 3, 1)

{

return m->getCurrentCreature()->isHungry();

}


CONDITION(HareFoodChosen, "Еда выбрана?", 3, 2)

{

Hare* h = dynamic_cast(m->getCurrentCreature());

if(!h->getTargetFood()) {

return false;

}

for(vector::iterator it = m->food.begin();

it != m->food.end();

it++)


{

if(*it == h->getTargetFood()) {

return true;

}

}

h->setTargetFood(NULL);

return false;

}


CONDITION(HareCanSeeFood, "Поиск еды; еду видно?", 3, 3)

{

Hare* h = dynamic_cast(m->getCurrentCreature());

Food* f = NULL;

float dist = 5;

for(vector::iterator it = m->food.begin();

it != m->food.end();

it++)

{

float newDist = m->distance(h, *it);

if(newDist < dist) {

f = *it;

dist = newDist;

}

}

h->setTargetFood(f);

if(f) {

return true;

}

return false;

}


CONDITION(HareFoodReached, "Еда достигнута?", 3, 4)

{

Hare* h = dynamic_cast(m->getCurrentCreature());

if(!h->getTargetFood()) {

return false;

}

if(m->distance(h->getTargetFood(), h) < 0.001) {

return true;

}

return false;

}


//---------------------------------------------------------------------------


CONDITION(ReadyForReproduction, "Готов к размножению?", 4, 0)

{

return m->getCurrentCreature()->isReadyForReproduction();

}


CONDITION(PairChosen, "Пара выбрана?", 4, 1)

{

Creature* c = m->getCurrentCreature();

if(!c->getTargetPair()) {

return false;

}

for(vector::iterator it = m->creatures.begin();

it != m->creatures.end();

it++)

{

if(*it == c->getTargetPair()) {

return true;

}

}

c->setTargetPair(NULL);

return false;

}


CONDITION(CanSeePair, "Поиск пары; пару видно?", 4, 2)

{

Creature* h = m->getCurrentCreature();

Creature* p = NULL;

float dist = 5;

for(vector::iterator it = m->creatures.begin();

it != m->creatures.end();

it++)

{

float newDist = m->distance(h, *it);

if(newDist < dist

&& (*it)->maleGender != h->maleGender

&& (*it)->isHare() == h->isHare()

&& (*it)->isReadyForReproduction()

&& (((*it)->getTargetPair() == NULL)

|| ((*it)->getTargetPair() == h))) {

p = *it;

dist = newDist;

}

}

h->setTargetPair(p);

if(p) {

p->setTargetPair(h);

return true;

}

return false;

}


CONDITION(PairOK, "Пара ОК?", 4, 3)

{

Creature* h = m->getCurrentCreature();

if(!h->getTargetPair()) {

return false;

}

if(h->getTargetPair()->getTargetPair() != h) {

return false;

}

if(!h->getTargetPair()->isReadyForReproduction()) {

return false;

}

return true;

}


CONDITION(HarePairReached, "Пара достигнута?", 4, 4)

{

Creature* h = m->getCurrentCreature();

if(!h->getTargetPair()) {

return false;

}

if(m->distance(h->getTargetPair(), h) < 0.001) {

return true;

}

return false;

}


//---------------------------------------------------------------------------


CONDITION(WolfIsHungry, "Голоден?", 5, 0)

{

return m->getCurrentCreature()->isHungry();

}


CONDITION(WolfCanSeeFood, "Еду видно?", 5, 1)

{

Wolf* w = dynamic_cast(m->getCurrentCreature());

Creature* c = NULL;

float dist = 5;

for(vector::iterator it = m->creatures.begin();

it != m->creatures.end();

it++)

{

if((*it)->isHare()) {

float newDist = m->distance(w, *it);

if(newDist < dist) {

c = *it;

dist = newDist;

}

}

}

w->setTargetFood(c);


if(c) {

return true;

}

return false;

}


CONDITION(WolfFoodReached, "Еда достигнута?", 5, 2)

{

Wolf* w = dynamic_cast(m->getCurrentCreature());

if(!w->getTargetFood()) {

return false;

}

if(m->distance(w->getTargetFood(), w) < StartConfig::instance()->hareSpeed) {

return true;

}

return false;

}


//---------------------------------------------------------------------------


#pragma hdrstop


#include "Hare.h"

#include "Wolf.h"

#include "Model.h"

#include "TMainForm.h"

#include "SysAction.h"


//---------------------------------------------------------------------------


#pragma package(smart_init)


SYSACTION(DoNothing, "Заглушка", 0, 0)

{

}


//---------------------------------------------------------------------------


SYSACTION(GiveBirth, "Рожать", 1, 0)

{

m->getCurrentCreature()->giveBirth(m);

m->getCurrentCreature()->pregnancy = -1;

}


//---------------------------------------------------------------------------


SYSACTION(HareDie, "Умереть", 2, 0)

{

m->killCurrent();

}


//---------------------------------------------------------------------------


SYSACTION(HareGoToFood, "Идти к еде", 3, 0)

{

Hare* h = dynamic_cast(m->getCurrentCreature());

if(h->getTargetFood()) {

h->runTo(h->getTargetFood()->x, h->getTargetFood()->y);

}

}


SYSACTION(HareEat, "Есть", 3, 1) {

Hare* h = dynamic_cast(m->getCurrentCreature());

for(vector::iterator it = m->food.begin();

it != m->food.end();

it++) {

if(*it == h->getTargetFood()) {

m->food.erase(it);

h->eat();

h->setTargetFood(NULL);

break;

}

}

}


SYSACTION(HareWanderByTable2, "Бродить вокруг", 3, 2)

{


}


SYSACTION(NextCreatureTable2, "Следующий", 3, 3)

{

m->nextCreature();

}


SYSACTION(HareRunAway, "Убегать!", 3, 4)


{

Hare* h = dynamic_cast(m->getCurrentCreature());

if(h->getDanger()) {

float toX = h->x - h->getDanger()->x;

float toY = h->y - h->getDanger()->y;

float l = sqrt(toX*toX + toY*toY);

if(l > 0) {

toX = toX/l * h->speed;

toY = toY/l * h->speed;

toX += h->x;

toY += h->y;

}


if(toX >= 1) toX = 0.9;

if(toY >= 1) toY = 0.9;

if(toX <= 0) toX = 0.1;

if(toY <= 0) toY = 0.1;

h->runTo(toX, toY);

h->setTargetFood(NULL);

h->setTargetPair(NULL);

}

}


//---------------------------------------------------------------------------


SYSACTION(GoToPair, "Идти к паре", 4, 0)

{

Creature* h = m->getCurrentCreature();

if(h->getTargetPair()) {

h->runTo(h->getTargetPair()->x, h->getTargetPair()->y);

}


}


SYSACTION(Reproduce, "Размножаться", 4, 1)

{

Creature* h = m->getCurrentCreature();

if(h->getTargetPair()) {

Creature* p = h->getTargetPair();

h->copulate(m);

p->copulate(m);

}

else {

h->setTargetPair(NULL);

}

}


SYSACTION(WanderByTable3, "Бродить вокруг", 4, 2)

{


}


SYSACTION(DropPair, "Сбросить пару", 4, 3)

{

Creature* h = m->getCurrentCreature();

h->setTargetPair(NULL);

}


SYSACTION(CreatureTable3, "Следующий", 4, 4)

{

m->nextCreature();

}


//---------------------------------------------------------------------------



SYSACTION(WolfGoToFood, "Идти к еде", 5, 0)

{

Wolf* w = dynamic_cast(m->getCurrentCreature());

if(w->getTargetFood()) {

w->runTo(w->getTargetFood()->x, w->getTargetFood()->y);

}

}


SYSACTION(WolfEat, "Есть", 5, 1) {

Wolf* w = dynamic_cast(m->getCurrentCreature());

for(vector::iterator it = m->creatures.begin();

it != m->creatures.end();

it++) {

if(*it == w->getTargetFood()) {

m->creatures.erase(it);

w->eat();

break;

}

}

w->setTargetFood(NULL);

}


SYSACTION(WolfWanderByTable5, "Бродить вокруг", 5, 2)

{


}


SYSACTION(NextCreatureTable5, "Следующий", 5, 3)

{

m->nextCreature();

}


- 15 -


Случайные файлы

Файл
30306-1.rtf
153263.rtf
4774.rtf
24848-1.rtf
26342.rtf