Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Моделирование Виртуальной Вычислительной Системы.


Информационный Канал Subscribe.Ru


Моделирование Виртуальной Вычислительной Системы.
 
Выпуск №8
home URL
автор рассылки: noonv (noonv@narod.ru)

"Он повернулся, пнул дверь и вышел на крыльцо. Дождь словно только и ждал этого.
Только что он лениво моросил, а тут вдруг хлынул настоящим ливнем."
Аркадий и Борис Стругацкие. Гадкие лебеди.

Здравствуйте, уважаемые читатели!
Вот оно какое- лето! Жарко, зной словно выбелил небо...стоит только выглянуть на солнце и просто чувствуешь, как на тебя обрушиваются потоки оглушающей и вязкой теплоты, вот оно всемирное потепление :)
Но "вернёмся к нашим баранам", сегодня рассмотрим одно из применений клеточных автоматов: модель просачивания жидкости через слой какого-то материала.
Просачивания - ага, сейчас только об этом и разговаривать :)
Сразу оговорюсь: модель эта достаточно грубая. Нус приступим:
модель я построил просто подредактировав исходный код игры Жизнь, который был приведён в прошлом выпуске. Главная(и единственная) характеристика вещества в данной задаче - коеффициент просачивания:
const double p_LeakCoef=0.013;
изменяя это число вы можете посмотреть как будет меняться картина просачивания.
Размер поля я оставил прежний: 20x60, одна клетка может находиться в двух состояниях - она либо мокрая(wet), либо сухая(dry), причём если клетка мокрая, то она в этом состоянии и остаётся, то есть обратных процессов нет. Таким образом происходит обработка только сухих клеток. Переход ячейки из сухого состояния в противоположное, происходит так:
подсчитывается число влажных соседей данной клетки в окрестности Мура,
генерируется псевдослучайное число функцией rand(), оно делится на RAND_MAX для того, чтобы получить число в пределах от 0 до 1.
и, наконец, происходит сравнение псевдослучайного числа с произведением коеффициента просачивания на число мокрых соседних клеток. Если произведение окажется больше псевдослучайного числа, то мочим клетку :)

Note: Генерация псевдослучайных чисел.
#include<stdlib.h>
int rand(void);
void srand(unsigned seed);

rand() возвращает последовательность псевдослучайных чисел в диапазоне от 0 до RAND_MAX.
srand(seed) позволяет задать посредством аргумента seed новое начало для последовательности псевдослучайных чисел, которые будут генерироваться последующими вызовами rand(). Если srand потом будет вызвана с тем же аргументом, последовательнось генерирумых чисел поворится. Отсутствие вызова srand перед вызовами rand эквивалентна начальному вызову srand с аргументом 1.
// М.И.Беляков Мобильная операционная система М.:Радио и связь,1991

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

А вот и исходник.

//////////////////////////////////////////////////////////////////////
//
// 8.cpp
// for model of leakage 
//                       aka pampers =)
// issue N8
// Started: 16.07.03 9:10:12
//
//                                                    XIII
//////////////////////////////////////////////////////////////////////
// * - is wet cell 
// a - will wet
#ifndef _8_CPP_
#define _8_CPP_ 1

#include<fstream.h>
#include<stdio.h> // for getchar()
#include<stdlib.h> // for rand()
char *prog_name="pampers v0.02";
// size of massive
#define P_SIZE 20
#define P_SIZEY 60
const double p_LeakCoef=0.013; // coefficient of leakage 
          // try to change it
typedef unsigned int uint;
// variables
char *file_name="pampers.txt";
fstream fs; // for manipulations with file
char p_mas[P_SIZE+2][P_SIZEY+2]; //massive
int p_i,p_j; // counter's
uint p_time=0; // age of model
uint p_coef=0; // coefficient for check cell
// functions
int in_file(char*); // get data from file and set massive
void calculate(uint,uint); // calculate one cell 
int main()
{
 // print Hello :)
 cout<<"+---------------+\n";
 cout<<"|  Pampers :)   |\n";
 cout<<"|               |\n";
 cout<<"|          XIII |\n";
 cout<<"+---------------+"<<endl;
 cout<<"press Enter for next step; for Exit press q"<<endl;
 // set border
 for(p_i=0;p_i<P_SIZEY+2;p_i++)
  p_mas[0][p_i]=p_mas[P_SIZE+1][p_i]='-';
 for(p_j=0;p_j<P_SIZE+2;p_j++)
  p_mas[p_j][0]=p_mas[p_j][P_SIZEY+1]='|';
 p_mas[P_SIZE+1][0]=p_mas[0][P_SIZEY+1]='+';
 p_mas[0][0]=p_mas[P_SIZE+1][P_SIZEY+1]='+';
 // set elements of p_mas zero
 for(p_i=1;p_i<P_SIZE+1;p_i++)
 {
  for(p_j=1;p_j<P_SIZEY+1;p_j++)
   p_mas[p_i][p_j]='0';
 }
 // get data
 if(in_file(file_name))
  return 1; // error open file
 while(getchar()!='q')
 {
  cout<<"Time: "<<p_time++<<endl;
  // print massive
  for(p_i=0;p_i<P_SIZE+2;p_i++)
  {
   for(p_j=0;p_j<P_SIZEY+2;p_j++)
   {
    if(p_mas[p_i][p_j]=='a')
     p_mas[p_i][p_j]='*'; // wet
    if(p_mas[p_i][p_j]=='0')
     cout<<" ";
    else
     cout<<p_mas[p_i][p_j];
   }
   cout<<endl;
  }
  // calculate next step
  for(p_i=1;p_i<P_SIZE+1;p_i++)
  {
   for(p_j=1;p_j<P_SIZEY+1;p_j++)
    calculate(p_i,p_j);
  }
 }
 ////////////
 return 0;
}
int in_file(char*file)
{// get data from file and set life-massive
 fs.open(file,ios::in);
 if(!fs)
 {// can't open file
  cout<<"Error open file!\t"<<file_name<<endl;
  return 1;
 }
 // get data
 for(p_i=1;p_i<P_SIZE+1;p_i++)
 {
  for(p_j=1;p_j<P_SIZEY+1;p_j++)
   fs>>p_mas[p_i][p_j];
 }
 fs.close();
 return 0;
}
void calculate(uint x,uint y)
{// calculate one cell with x,y
 switch(p_mas[x][y])
 {
 case 'a':
 case '+':
 case '|':
 case '-':
 case '*':
 break;
 case '0':// only for dry cell
  //-------------------------------------//
  p_coef=0;
  if(p_mas[x][y-1]=='*') // west
   p_coef++;
  if(p_mas[x-1][y-1]=='*')// north-west
   p_coef++;
  if(p_mas[x-1][y]=='*')// north
   p_coef++;
  if(p_mas[x-1][y+1]=='*')// north-east
   p_coef++;
  if(p_mas[x][y+1]=='*')// east
   p_coef++;
  if(p_mas[x+1][y+1]=='*')// south-east
   p_coef++;
  if(p_mas[x+1][y]=='*')// south
   p_coef++;
  if(p_mas[x+1][y-1]=='*')// south-west
   p_coef++;
  //
  // take pseudorandom number in the range 0 to 1.
  // yes here very simple case; in reality,  
  // here must be equation with exp() ; i think so =)
  //
  if((double)rand()/RAND_MAX<p_LeakCoef*p_coef)
    p_mas[x][y]='a';
  //-------------------------------------//
  break;
 default:
  break;
 }
}
#endif

Теперь файл с данными называется pampers.txt. Вот пример каким он может быть:
000000000000000000**********************00000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000

или можете всю первую строчку сделать влажной :) экспериментируйте.
Сразу почему-то вспоминаются эти дурацкие рекламные ролики про памперсы и прокладки ! :-)

Можно сказать, что модель у нас стохастическая, т.е. в ней присутствует элемент случайности.

Пока!

[noonv@volodia noonv]$ logout

XIII

Рейтинг@Mail.ru

http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное