.
Моделирование систем. Урок 2. Система "Хищник, жертва, растения".
Автор megabax   
23.08.2012 г.
New Page 2

Моделирование систем. Урок 2. Система "Хищник, жертва, растения".

Первая задача моделирования которую мы рассмотрим, это простейшая модель экологической системы. Пусть у нас существует три вида популяций: Predator (Хищник), Herbivore (Травоядное животное), Plant (Растение). Все они живут на определенной ограниченной площади - Area. На каждом квадратном метре площади может произрастать определенное количество Plant. За единицу времени каждый из Herbivore  съедает определенное количество Plant. Если Plant не хватает, то те животные, которым не хватило, вымирают. Каждый Predator  так же потребляет определенное количество Herbivore за единицу времени. Если им пищи не хватает - то те хищники, которые остались голодными, так же умирают. Если хищникам либо травоядным животным хватает пищи, то они размножаются с определенной скоростью. И еще одно допущение модели: Plant растет независимо от наличия Plant. Допустим, Herbivore  съели весь Plant, но пока они его съедали, семена успели разлететься и из них вырос новый Plant. Что касается Herbivore   и Predator  то они растут только при наличии онных, каждую единицу времени прирост на определенный процент. Тоесть Herbivore  и Predator  растут в геометрической прогрессии, Plant  в арифметической.

И так, давайте начнем писать программу. Сначала объявим базовый класса (мы же еще и библиотеку попутно пишем):

    public abstract class BaseClass

    {

        private BaseClass _owner;

 

        public BaseClass owner

        {

            get

            {

                return _owner;

            }

            set

            {

                _owner = value;

            }

        }

 

        public abstract string GetClassCaption();

    }

Теперь напишем класс для реализации растений (Plant):

    public class Plant : BaseClass

    {

        public override string GetClassCaption()

        {

            return "Растение";

        }

 

        private double _countOnAreaUnit;

 

        /// <summary>

        /// Количество растений на квадратный метр

        /// </summary>

        public double countOnAreaUnit

        {

            get

            {

                return _countOnAreaUnit;

            }

            set

            {

                _countOnAreaUnit = value;

            }

        }

 

        private double _growthSpeed;

 

 

        /// <summary>

        /// Скорость роста, кол во в единицу времени.

        /// </summary>

        public double growthSpeed

        {

            get

            {

                return _growthSpeed;

            }

            set

            {

                _growthSpeed = value;

            }

        }

 

        private double _count;

 

        /// <summary>

        /// Общее количество растений

        /// </summary>

        public double count

        {

            get

            {

                return _count;

            }

            set

            {

                _count = value;

            }

        }

 

        /// <summary>

        /// Моделирование роста растений

        /// </summary>

        /// <param name="availabalArea">Доступная площадь</param>

        public void grow(double availabalArea)

        {

            double totalCount = _count + _growthSpeed;

            double totalArea = totalCount / _countOnAreaUnit;

            if (totalArea > availabalArea) totalArea = availabalArea;

            _count = totalArea*_countOnAreaUnit;

        }

    }

Аналогично Herbivore:

    public class Herbivore

    {

        public virtual string GetClassCaption()

        {

            return "Травоядное животное";

        }

 

        private double _foodNeed;

 

        /// <summary>

        /// Сколько одному животному нужно еды на единицу времени

        /// </summary>

        public double foodNeed

        {

            get

            {

                return _foodNeed;

            }

            set

            {

                _foodNeed = value;

            }

        }

 

        private double _growthSpeed;

 

 

        /// <summary>

        /// Скорость размножения, относительный прирост за единицу времени.

        /// </summary>

        public double growthSpeed

        {

            get

            {

                return _growthSpeed;

            }

            set

            {

                _growthSpeed = value;

            }

        }

 

        private int _count;

 

        /// <summary>

        /// Количество животных

        /// </summary>

        public int count

        {

            get

            {

                return _count;

            }

            set

            {

                _count = value;

            }

        }

 

        /// <summary>

        /// Жизненный цикл

        /// </summary>

        /// <param name="plant">Доступная пища</param>

        public void liveLoop(Plant plant)

        {

            double availabalFood = plant.count;

            double needFood = _count * _foodNeed;

 

            //проверим, хватает ли еды

            if (needFood > availabalFood)

            {

                //если еды не хватает,

                //то некоторые живтоные умирают

                int animalIsFull = Convert.ToInt32(availabalFood / _foodNeed); // скольки животным хватит еды

                _count = animalIsFull; //выживает только те, кто успел "пообедать"

 

                //все растения съедены

                plant.count = 0;

            }

            else

            {

                //еды хватило всем, животные размножаються

                _count = Convert.ToInt32(_count * (1 + _growthSpeed));

 

                //животные съели растения, отразим этот факт - уменьшим кол-во растений

                plant.count = plant.count - needFood;

            }

           

        }

    }

И Predator:

    public class Predator

    {

        public virtual string GetClassCaption()

        {

            return "Хищник";

        }

 

        private int _foodNeed;

 

        /// <summary>

        /// Сколько одному хищнику нужно еды на единицу времени

        /// </summary>

        public int foodNeed

        {

            get

            {

                return _foodNeed;

            }

            set

            {

                _foodNeed = value;

            }

        }

       private double _growthSpeed;

       

        /// <summary>

        /// Скорость размножения, относительный прирост за единицу времени.

        /// </summary>

        public double growthSpeed

        {

            get

            {

                return _growthSpeed;

            }

            set

            {

                _growthSpeed = value;

            }

        }

 

        private int _count;

 

        /// <summary>

        /// Количество хищников

        /// </summary>

        public int count

        {

            get

            {

                return _count;

            }

            set

            {

                _count = value;

            }

        }

 

        /// <summary>

        /// Жизненный цикл

        /// </summary>

        /// <param name="herbivore">Доступная пища</param>

        public void liveLoop(Herbivore herbivore)

        {

            int availabalFood = herbivore.count;

            int needFood = _count * _foodNeed;

 

            //проверим, хватает ли еды

            if (needFood > availabalFood)

            {

                //если еды не хватает,

                //то некоторые хищники умирают

                int animalIsFull = Convert.ToInt32(availabalFood / _foodNeed); // скольки животным хватит еды

                _count = animalIsFull; //выживает только те, кто успел "пообедать"

 

                //все жертвы съедены

                herbivore.count = 0;

            }

            else

            {

                //еды хватило всем, хищники размножаются

                _count = Convert.ToInt32(_count * (1 + _growthSpeed));

 

                //хищники съели травоядных, отразим этот факт - уменьшим кол-во растений

                herbivore.count = herbivore.count - needFood;

            }

           

        }

    }

Что бы моделировать взаимодействие всех этих объектов, создадим класс Area:

    public class Area : BaseClass

    {

        private Plant _plant;

 

        public override string GetClassCaption()

        {

            return "Площадка";

        }

       

        /// <summary>

        /// Растения

        /// </summary>

        public Plant plant

        {

            get

            {

                return _plant;

            }

            set

            {

                _plant = value;

            }

        }

 

        private Herbivore _herbivore;

 

        /// <summary>

        /// Травоядные

        /// </summary>

        public Herbivore herbivore

        {

            get

            {

                return _herbivore;

            }

            set

            {

                _herbivore = value;

            }

        }

 

        private Predator _predator;

 

        /// <summary>

        /// Хищники

        /// </summary>

        public Predator predator

        {

            get

            {

                return _predator;

            }

            set

            {

                _predator = value;

            }

        }

 

        private double _availabalArea;

 

        /// <summary>

        /// Доступная площадь

        /// </summary>

        public double availabalArea

        {

            get

            {

                return _availabalArea;

            }

            set

            {

                _availabalArea=value;

            }

        }

 

        /// <summary>

        /// Жизненный цикл

        /// </summary>

        public void liveLoop()

        {

            _plant.grow(_availabalArea);

            _herbivore.liveLoop(_plant);

            _predator.liveLoop(_herbivore);

        }

    }

Теперь накидаем на форму меток и кнопочку:

Моделирование систем. Урок 2. Система "Хищник, жертва, растения".

Вместе с конструктором и обработчиком нажатия на кнопочку, программа выглядит примерно так (у вас могут быть другие начальные данные и название объектов):

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

 

namespace WindowsFormsApplication1

{

    public partial class Form1 : Form

    {

        private Area _area;

 

        public Form1()

        {

            InitializeComponent();

            _area = new Area();

            _area.availabalArea = 10000;

            _area.herbivore = new Herbivore();

            _area.herbivore.count = 200;

            _area.herbivore.foodNeed = 2;

            _area.herbivore.growthSpeed = 0.1;

 

            _area.plant = new Plant();

            _area.plant.count = 2000;

            _area.plant.countOnAreaUnit = 10;

            _area.plant.growthSpeed = 500;

 

            _area.predator = new Predator();

            _area.predator.count = 10;

            _area.predator.foodNeed = 1;

            _area.predator.growthSpeed = 0.1;

 

            showData();

        }

 

        private void showData()

        {

            lbHerbirove.Text = _area.herbivore.count.ToString();

            lbPlants.Text = _area.plant.count.ToString();

            lbPredators.Text = _area.predator.count.ToString();

        }

 

        private void btnNext_Click(object sender, EventArgs e)

        {

            _area.liveLoop();

            showData();

        }

    }

}

И так, запускаем программу и наблюдаем результат:

Моделирование систем. Урок 2. Система "Хищник, жертва, растения".

Вообще, скажу сразу, какие бы исходные данные вы не завели, кончиться все одинаково: хищники съедать всех травоядных и вымрут сами. Попробуйте поэкспериментировать. Почему так происходит? Ответ прост и очевиден: количество хищников растет неограниченно, а количество травоядных ограничено количество подножного корма - когда трава заполнить всю доступную площадь, прирост травоядных прекратится. А хищники будут плодиться и размножаться, пока не съедят всех травоядных.

Ну что-ж, подведем итоги. Мы запрограммировали простейшую модель экосистемы, которая, как оказалось, неустойчивая и в конце концов приходит к коллапсу. В следующих уроках мы придумаем другие, более устойчивые системы и будем их моделировать.


Скриншоты, приведенные в данной статье, являются цитатами и иллюстрациями   программного продукта "Microsoft Visual Studio 2010", авторское право на который принадлежит Microsoft


 

 

Последнее обновление ( 23.08.2012 г. )