Тема: Аксиоматические модели клеточных популяций
Задание: Построить алгоритм роста клеточной структуры, которая имеет следующие свойства:
- Исходная структура – 4 клетки в точках поля, с координатами, выбранными случайным образов.
- Клетка может развиваться и давать потомство в соседние клетки по следующему правилу: пустое поле заполняется, если количество соседних клеток по вертикали и горизонтали равно количеству соседних клеток по диагоналям.
- Клетка гибнет с вероятностью 0,8 спустя 10 тактов.
Написать программу на Си Шарп и вывести на экран состояние для нескольких поколений клеток. Исследовать рост структуры в зависимости от количества соседей, при котором клетка гибнет.
Теоретические сведения
Любая клетка может иметь три состояния:
M – клетка родилась
G – клетка ростет и ожидает деления
Z – клетка взрослая. Деление невозможно.
Клетка гибнет с вероятностью 0,8 через 10 тактов, а через 13 тактов с вероятностью 1.
Для каждой клетки необходимо хранить:
- Время рождения
- Текущее состояние
- Условные вероятности ( если они разные для каждой клетки )
- Если или нету клетки (0 – нет, 1 – есть )
Текст программы на C#:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing; //Доступ к методам GDI+
using System.Drawing.Drawing2D;//Добавить для расширения доступа к GDI+
using System.Threading;
namespace KSSLR6
{
public struct kletka
{
public int t_jizni; // время жизни
public int sost; // состояние M, G, Z
public int status; // 0 - клетки нет, 1 - клетка есть
}
public partial class Form1 : Form
{
int n = 50; // размер массива
int m = 100; // размер цикла клеток
kletka[,] mas = new kletka[50, 50];
Random rand = new Random();
int sum = 0; // переменная для определение свободного места для деления
int[,] masiv = new int[4, 2]; // массив для записи свободных позиций для деления клетки
int[] masiv2 = new int[4]; // массив для определения свободных позиций для деления клетки
int vibor = 0; // переменная для выбора деления
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) // метод деления клеток
{
Random rand = new Random();
double temp;
int x, y;
for (int p = 0; p < 4; p++)
{
x = rand.Next(n);
y = rand.Next(n);
mas[x, y].status = 1;
mas[x, y].sost = 1;
mas[x, y].t_jizni = 0;
}
for (int p = 0; p < m; p++)
{
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
if (mas[i, j].status == 1)
{
if (mas[i, j].sost == 1)
{
mas[i, j].t_jizni++;
if (mas[i, j].t_jizni >= 2) mas[i, j].sost = 2;
}
else if (mas[i, j].sost == 2)
{
Delenie(i, j); // вызов метода деления клетки
mas[i, j].t_jizni++;
if (mas[i, j].t_jizni >= 6) mas[i, j].sost = 3;
}
else if (mas[i, j].sost == 3)
{
mas[i, j].t_jizni++;
if (mas[i, j].t_jizni >= 10 && mas[i, j].t_jizni != 13)
{
temp = Convert.ToDouble(rand.Next(100)) / 100;
if (temp <= 0.8)
{
mas[i, j].t_jizni = 0;
mas[i, j].sost = 0;
mas[i, j].status = 0;
}
}
else if (mas[i, j].t_jizni == 13)
{
mas[i, j].t_jizni = 0;
mas[i, j].sost = 0;
mas[i, j].status = 0;
}
}
}
}
Print(); // вызов метода печати на экран
}
}
private void Print() // вывод в форму массив клеток прямоугольниками
{ // зеленый - это состояние M; желтый - это состояние G; красный - это состояние Z
Graphics GDIp = CreateGraphics();
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
if (mas[i, j].status == 1)
{
if (mas[i, j].sost == 1)
{
GDIp.DrawRectangle(new Pen(Color.Green, 5), ((j+1)*10), ((i+1)*10), 10, 10);
}
else if (mas[i, j].sost == 2)
{
GDIp.DrawRectangle(new Pen(Color.Yellow, 5), ((j + 1) * 10), ((i + 1) * 10), 10, 10);
}
else if (mas[i, j].sost == 3)
{
GDIp.DrawRectangle(new Pen(Color.Red, 5), ((j + 1) * 10), ((i + 1) * 10), 10, 10);
}
}
}
Thread.Sleep(100); // задержка на 100 миллисекунд
}
private void Delenie(int i, int j)
{
sum = 0; // для суммы свободных ячеек для размножения клеток
int k1;
int sum2 = 0; // переменная для выбора деления клетки
for (k1 = 0; k1 < 4; k1++) masiv2[k1] = 0;
if (i - 1 >= 0) if (mas[i - 1, j].status == 0) { sum++; masiv2[0] = 1; masiv[0, 0] = i-1; masiv[0, 1] = j; } // сверху
if (i + 1 < n) if (mas[i + 1, j].status == 0) { sum++; masiv2[1] = 1; masiv[1, 0] = i+1; masiv[1, 1] = j; } // снизу
if (j - 1 >= 0) if (mas[i, j - 1].status == 0) { sum++; masiv2[2] = 1; masiv[2, 0] = i; masiv[2, 1] = j-1; } // слева
if (j + 1 < n) if (mas[i, j + 1].status == 0) { sum++; masiv2[3] = 1; masiv[3, 0] = i; masiv[3, 1] = j+1; } // справа
if (sum > 0) // если есть свободное место для деления клетки
{
vibor = rand.Next(1, sum + 1); // получение случайного местя для деления
for (k1 = 0; k1 < 4; k1++)
{
if (masiv2[k1] == 1)
sum2++;
if (sum2 == vibor) // условие для деления клетки по случайному числу vibor
{
mas[masiv[k1, 0], masiv[k1, 1]].status = 1;
mas[masiv[k1, 0], masiv[k1, 1]].t_jizni = 0;
mas[masiv[k1, 0], masiv[k1, 1]].sost = 1;
mas[i, j].status = 1;
mas[i, j].t_jizni = 0;
mas[i, j].sost = 1;
}
}
}
}
}
}
Результат работы программы:
Скачать готовый проект можно здесь )))