1. вычисление производных и интегралов

advertisement
Майер Р.В. Задачи,
алгоритмы, программы
[Электронный ресурс]. -Глазов: ГГПИ, 2010.
(Web-site http://maierrv.glazov.net"Найти задачу - не меньшая радость, чем
отыскать ее решение".
Томас де Куинси
О ЧЕМ ЭТА КНИГА
Вот уже около 10 лет я занимаюсь преподаванием ряда информационных дисциплин
("Информатика" (1 курс), "Компьютерное моделирование" (3 курс), "Теоретические
основы информатики" (5 курс)) на физическом факультете Глазовского государственного
педагогического института. Вместе с этим руковожу выполнением курсовых работ по
физике и информатике.
Развитие компьютерной техники привело к повсеместному распространению
информационно--коммуникационных технологий, что не могло не сказаться на формах и
методах обучения. Доступность ПЭВМ позволяет решать различные задачи, связанные с
написанием
программ,
созданием
компьютерных
моделей,
проведением
вычислительного эксперимента. На практических занятиях и лабораторных работах,
проводимых в компьютерных классах, студенты, осваивая основы программирования,
создают нескложные компьютерные программы, что способствует развитию их
творческих способностей, дает возможность проявить себя. Преподаватель формулируя
задачу может предложить студентам программу, являющуюся решением аналогичной
задачи, чтобы студент на ее основе создал свою, а не писал программу "с нуля". При
выполнении курсовых и дипломных проектов также возможно создание и исследование
компьютерных моделей изучаемых явлений, решение уравнений и их систем,
математическая обработка результатов измерений.
В книге "Задачи, алгоритмы, программы" проанализированы некоторые наиболее
интересные с точки зрения автора задачи по программированию, компьютерному
моделированию и информатике. Некоторые компьютерные модели физических или
биологических явлений могут быть использованы для проведения учебного
вычислительного эксперимента, под которым автор предлагает понимать упрощенные
варианты научного вычислительного эксперимента, адаптированные к условиям
обучения. В процессе выполнения учебного вычислительного эксперимента учащиеся
изменяют параметры исследуемых систем, характер и силу внешних воздействий,
начальные условия и "наблюдают", как при этом меняется отклик системы, характер
исследуемых процессов. Все это позволяет изучить динамику изменения различных
величин, характеризующих данное явление, сформировать его наглядный образ.
1
Учебный вычислительный эксперимент следует рассматривать как дополнение к
учебной теории и учебному натурному эксперименту.
В книге рассмотрены компьютерные модели некоторых автоматов, в частности, модели
машины Поста и машины Тьюринга, а также различных нейросетей и персептронов.
Предложенные задачи позволяют студентам и учащимся понять соответствующие
вопросы теоретической информатики.
Почти все задачи решены на языке Borland Pascal 7.0, большая часть решений имеет
пояснения и рисунки. Многие из представленных программ использовались на занятиях
со студентами. Автор выражает благодарность преподавателям физического факультета,
в той или иной степени способствовавшим выполнению этой работы.
1. ВЫЧИСЛЕНИЕ ПРОИЗВОДНЫХ И ИНТЕГРАЛОВ
Задача 1.1.
Исследуемый физический процесс описывается уравнением x(t)=3t3-3t2+4.
Определите первую и вторую производные функции x=x(t) момент времени 2
с. Найдите интеграл данной функции в интервале от 1 до 3 с методом
трапеций. Решите задачу аналитически и сравните результаты.
Алгоритм решения этой задачи АЛ - 1.1 представлен ниже. При уменьшении
шага h получающиеся значения производной и интеграла стремятся к
некоторым предельным значениям, которые совпадают с аналитически
найденными значениями производной y' и интеграла I функции (табл. 1).
Алгоритм АЛ - 1.1
ЗАДАТЬ ФУНКЦИЮ Funct:=t*t*t-t*t+3;
---------------------НАЧАЛО ПРОГРАММЫ
t:=3; h:=0.001;
y1:=Funct(t-h); y2:=Funct(t); y3:=Funct(t+h);
ПЕЧАТЬ "Первая производная ", (y2-y1)/h
ПЕЧАТЬ "Вторая производная ", (y1-2*y2+y3)/(h*h)
a:=1; b:=3; t:=a; S:=0;
ПОВТОРЯТЬ{S:=S+0.5*(Funct(t)+Funct(t+h))*h; t:=t+h;}
ПОКА НЕ t>b;
ПЕЧАТЬ "Интеграл ", S
КОНЕЦ ПРОГРАММЫ
Решением задачи является программа ПР - 1.1. При уменьшении шага точность
вычислений обычно возрастает. Если же шаг очень мал, то для нахождения
интеграла приходится суммировать слишком большое число слагаемых, что
приводит к снижению точности. Точные значения первых двух производных и
интеграла приведены в нижней строчке табл. 1.1.
2
uses crt;
var x,y1,y2,y3,a,b,h,S : real;
{ ПР 1.1 }
Function Funct(x:real):real;
begin
Funct:=3*x*x*x-3*x*x+4;
end;
BEGIN clrscr; x:=2; h:=0.001;
y1:=Funct(x-h); y2:=Funct(x); y3:=Funct(x+h);
Writeln('Первая производная ', (y2-y1)/h:3:3);
Writeln('Вторая производная ', (y12*y2+y3)/(h*h):3:3);
a:=1; b:=3; x:=a; S:=0;
Repeat
S:=S+0.5*(Funct(x)+Funct(x+h))*h; x:=x+h;
until x>b;
Writeln('Интеграл ',S:3:3);
Repeat until KeyPressed;
END.
Таблица 1. Результаты вычислений.
Шаг Δx=h
x'
x''
I
0,2
21,120
30,000
42,200
0,1
22,530
30,000
48,177
0,01
23,850
30,000
42,584
0,001
23,985
30,000
42,000
0,0001
23,998
30,006
42,000
0,00001
24,000
30,268
42,001
Точн. знач.
24
30
42
Задача 1.2.
Точка движется по закону: x=3cos(t), y=2cos(3,7t+2). Вычислите координаты
x, y, проекции и модули скорости vx, vy, v и ускорения ax, ay, a, нормальное
aн и тангенциальное aтускорения в моменты времени t=iΔt, i=1, 2, ...
3
dt = .2: FOR t = 0 TO 10 STEP dt
{
ПР - 1.2 }
x0 = x: y0 = y: vx0 = vx: vy0 = vy
'QBASIC
x = 3 * COS(t): y = 2 * COS(3.7 * t + 2)
vx = (x - x0) / dt: vy = (y - y0) / dt
ax = (vx - vx0) / dt: ay = (vy - vy0) / dt
vv = SQR(vx * vx + vy * vy): aa = SQR(ax * ax + ay *
ay)
cosa = (ax * vx + ay * vy) / (aa * vv): at = aa *
cosa:
IF at < aa THEN an = SQR(aa * aa - (at * at))
PRINT t; x; y; vv; aa; at; an
NEXT
Задача 1.3.
Имеется неоднородная пластина, ограниченная функцией y=x1/2, осью
абсцисс, прямой x=2, плотность которой равна ρ(x,y)=2+0,4y+0,2x 2. Найдите
момент инерции пластины относительно оси Ox.
Рис. 1.3. К нахождению момента инерции пластины.
Вычисление момента инерции тела сводится к интегрированию по объему и
нахождению суммы элементарных моментов инерции. Разобъем тело (рис. 1.3)
на элементарные объемы dV=h·dx·dy массами dm=ρdV, имеющими моменты
инерции относительно оси Ox dI=y2dm. Для нахождения суммы всех
элементарных моментов инерции dI организуют два вложенных цикла, в
которых перебираются и суммируются все dI (программа ПР - 1.3).
4
dx = .05: dy = .05: h = .02
- 1.3 }
FOR x = 0 TO 2 STEP dy
'QBASIC
WHILE y < SQR(x)
y = y + dy: rho = 2 + .4 * y + .2 * x * x
dV = dx * dy * h: I = I + rho * dV * y * y
WEND: NEXT: PRINT I:
END
{ ПР
Задача 1.4.
Решите дифференциальное уравнение первого порядка y'x-f(x,y)=0 (например,
y'x-sin(x)=0) методом Эйлера. Получите семество решений, соответствующих
различным начальным условиям y0=y(0).
Запишем уравнение в конечных разностях:
dy/dx=f(x,y), (yi+1-yi)/h=f(x,y),
где h=Δ x --- шаг сетки по x. Отсюда следует:
yi+1=yi+f(x,y)h.
Чтобы численно решить уравнение, необходимо переменной y присвоить
значение y_0=y(0), а затем в цикле рассчитать последующие значения yi при
i=1, 2, ... в соответствии с приведенной выше формулой. В программе ПР - 1
(алгоритм АЛ - 1.4) решается уравнение y'x-sin(x)=0 при трех различных
начальных условиях y(0)=0, 0.5, 1. Получается семейство из трех функций
отличающихся на постоянную величину.
ДЛЯ j:=0 ДО 3 ДЕЛАТЬ {АЛ - 1.4
dx:=0.01: y:=.5*j
ДЛЯ i:=1 ДО 1000 ДЕЛАТЬ {-FNN:=sin(x); x:=i*dx; y:=y+FNN*dx;
ПОСТАВИТЬ ТОЧКУ С КООРДИНАТАМИ (x, y) --} -}
Используемая программа ПР - 1.4 представлена ниже.
SCREEN 12
LINE (0, 400)-(640, 400)
LINE (20, 0)-(20, 480)
'DEF FNN (x, y) = -y + 3
'DEF FNN (x, y) = -y - .5 * x + 4
DEF FNN (x, y) = SIN(x)
FOR j = 0 TO 3
dx = .01: y = .5 * j
FOR i = 1 TO 1000
x = i * dx: y = y + FNN(x, y) * dx
{ ПР - 1.4 }
'Qbasic
5
CIRCLE (20 + 50 * x, 400 - 100 * y), 2
NEXT: NEXT
Рис. 1.4. Решение дифференциального уравнения.
Задача 1.5.
Тело ограничено поверхностями z1=f(x,y), z2=f(x,y). Зависимость плотности от
координат ρ=ρ(x,y,z) известно. Методом Монте-Карло определите объем,
массу и положение центра масс тела.
Рис. 1.5. К вычислению массы, объема и координат центра масс тела.
6
Пусть тело ограничено поверхностями z1=1-1,3x2-y2, z2=x2-1. Плотность тела
задается соотношением: если x>-0,1, то ρ=3y+5z+10, иначе ρ=20. Опишем
вокруг тела куб, стороны которого перпендикулярны осям координат и
пересекают их в точках 1 и -1. Случайным образом наполним куб большим
количеством точек (106) с координатами x, y, z. Подсчитаем количество точек
nt, попавших внутрь тела, тогда объем тела во столько раз меньше объема куба
(который равен 4 м3), во сколько раз число nt меньше общего числа точек N.
Для того, чтобы определить массу и координаты центра масс, учтем, что на
каждую точку приходится элементарный объем dV=4/N. Поэтому будем
умножать dV на плотность ρ в данной точке, получающиеся элементарные
массы складывать. Так мы найдем массу тела msum. Для нахождения
координат центра масс
xsum:=xsum+rho*dV*x; ysum:=ysum+rho*dV*y;
zsum:=zsum+rho*dV*z; msum:=msum+rho*dV; end;
xc:=xsum/msum; yc:=ysum/msum; zc:=zsum/msum;
Решением задачи является программа ПР - 1.5.
{$N+}
uses dos, crt;
{ ПР - 1.5 }
var x,y,z,z1,z2,xc,yc,zc,rho,dV,V,
msum,xsum,ysum,zsum: single;
nt,N: longint;
BEGIN clrscr; Randomize;
nt:=0; N:=0; dV:=8/1000000;
Repeat
inc(N);
x:=random(200)/100-1;
y:=random(200)/100-1;
z:=random(200)/100-1;
If x>-0.3 then rho:=10+5*z+3*y else rho:=20;
z1:=1-1.3*x*x-y*y; z2:=x*x-1;
If (zz2) then begin inc(nt);
xsum:=xsum+rho*dV*x; ysum:=ysum+rho*dV*y;
zsum:=zsum+rho*dV*z; msum:=msum+rho*dV; end;
until N>1000000; V:=nt*dV;
xc:=xsum/msum; yc:=ysum/msum; zc:=zsum/msum;
writeln(xc:3:5,' ',yc:3:5,' ',zc:3:5);
writeln(msum:3:5,' | ',V:3:5); ReadKey;
END.
7
Задача 1.6.
Решите дифференциальное уравнение второго порядка y''x-f(x,y,y'_x)=0
(например, y''x+y'x+1,2y-5sin(x)=0) методом Эйлера. Начальные условия yx(0),
y'x(0).
Дифференциальное уравнение второго порядка представимо в виде системы
двух диффуравнений первого порядка:
В программе ПР - 2 создан цикл по i в котором пересчитываются значения yi,
y'i и решается уравнение y''x+y'x+1,2y-5sin(x)=0 (алгоритм АЛ - 1.6).
y = 20: dx = 0.01
АЛ - 1.6
ДЛЯ i = 1 ДО 5000 ДЕЛАТЬ {x = x + dx
pr2y = 5 * SIN(x) - .1 * pr1y - 1.2 * y
pr1y = pr1y + pr2y * dx; y = y + pr1y * dx
ПОСТАВИТЬ ТОЧКУ С КООРДИНАТАМИ (x, y)
-}
SCREEN 12
{ ПР - 1.6 }
LINE (0, 240)-(640, 240)
'Qbasic
LINE (20, 0)-(20, 480)
y = 20: dx = .01
FOR i = 1 TO 5000
x = x + dx
pr2y = 5 * SIN(x) - .1 * pr1y - 1.2 * y
pr1y = pr1y + pr2y * dx
y = y + pr1y * dx
CIRCLE (20 + 12 * x, 240 - 5 * y), 2
NEXT
END
8
Рис. 1.6. Решение дифференциального уравнения.
Задача 1.7.
Решите дифференциальное уравнение первого порядка вида y' x-f(x,y)=0
методом Рунге--Кутта четвертого порядка.
Сущность метода Рунге--Кутта четвертого порядка выражается следующими
формулами:
Организуем цикл по i, в котором вычисляются значения функции y(x) по этой
схеме. Например, для решения уравнения y'x-2sin(x)+0.5/y=0 используется
алгоритм АЛ--11.
АЛ - 1.7
ЗАДАТЬ ФУНКЦИЮ FNN (x, y) = 2 * SIN(x) + .5 / y
-------------------------------y = 1: dx = .01
ДЛЯ i = 1 ДО 1500 ДЕЛАТЬ {x = i * dx; k1 = FNN(x, y);
k2 = FNN(x + dx / 2, y + dx * k1 / 2)
k3 = FNN(x + dx / 2, y + dx * k1 / 2)
k4 = FNN(x + dx, y + k3)
y = y + dx / 6 * (k1 + 2 * k2 + 2 * k3 + k4)
ПОСТАВИТЬ ТОЧКУ С КООРДИНАТАМИ (x, y)
-}
Этот алгоритм реализован в программе ПР - 1.7.
9
SCREEN 12
LINE (0, 400)-(640, 400)
LINE (20, 0)-(20, 480)
DEF FNN (x, y) = 2 * SIN(x) +
'DEF FNN (x, y) = -y * y + .2
y = 1: dx = .01
FOR i = 1 TO 1500
x = i * dx: k1 = FNN(x, y)
k2 = FNN(x + dx / 2, y + dx *
k3 = FNN(x + dx / 2, y + dx *
k4 = FNN(x + dx, y + k3)
y = y + dx / 6 * (k1 + 2 * k2
CIRCLE (20 + 40 * x, 400 - 50
NEXT: END
{ ПР - 1.7 }
'Qbasic
.5 / y
* x
k1 / 2)
k1 / 2)
+ 2 * k3 + k4)
* y), 2
Рис. 1.7. Решение диффуравнения методом Рунге-Кутта.
Задача 1.8.
Решите дифференциальное уравнение второго порядка y''x-f(x,y,y'x)=0
методом Рунге--Кутта четвертого порядка. Начальные условия yx(0), y'x(0).
Записывают данное уравнение в виде системы двух диффуравнений первого
порядка и используют рассмотренную выше схему Рунге--Кутта. Используется
алгоритм АЛ - 1.8.
ЗАДАТЬ ФУНКЦИЮ FNN1 (x, y, pr1) = SIN(x) .25 * pr1 - .9 * SIN(y)
-------------------------------y = 2: v = 0: dx = .01
ДЛЯ i = 1 ДО 8000 ДЕЛАТЬ {10
x = i * dx: k1 = FNN1(x, y, pr1)
k2 = FNN1(x + dx / 2, y, pr1 + dx * k1 / 2)
k3 = FNN1(x + dx / 2, y, pr1 + dx * k2 / 2)
k4 = FNN1(x + dx, y, pr1 + k3)
pr1 = pr1 + dx / 6 * (k1 + 2 * k2 + 2 * k3 + k4)
y = y + pr1 * dx
ПОСТАВИТЬ ТОЧКУ С КООРДИНАТАМИ (x, y)
-}
Программа Пр - 1.8 позволяет решить уравнение y''x+0,25y'x + 0,9sin(y)=sin(x).
SCREEN 12
{ ПР - 1.8 }
LINE (0, 240)-(640, 240)
'QBasic
LINE (20, 0)-(20, 480)
DEF FNN1 (x, y, pr1) = SIN(x) - .25 * pr1 - .9 *
SIN(y)
y = 2: v = 0: dx = .01
FOR i = 1 TO 8000
x = i * dx: k1 = FNN1(x, y, pr1)
k2 = FNN1(x + dx / 2, y, pr1 + dx * k1 / 2)
k3 = FNN1(x + dx / 2, y, pr1 + dx * k2 / 2)
k4 = FNN1(x + dx, y, pr1 + k3)
pr1 = pr1 + dx / 6 * (k1 + 2 * k2 + 2 * k3 + k4)
y = y + pr1 * dx
CIRCLE (20 + 8 * x, 240 - 50 * y), 1
NEXT: END
Рис. 1.8. Решение диффуравнения методом Рунге-Кутта.
Задача 1.9.
Определите силу гравитационного притяжения, действующую со стороны
шарообразного тела радиуса R на материальную точку массой m,
находящуюся на расстоянии z' от центра. Плотность шара ρ(r)=100/r, где r -расстояние от его центра.
11
Рис. 1.9. К расчету взаимодействия шара и точки.
Распределение плотности шарообразного тела, а значит и его гравитационное
поле обладают центральной симметрией, поэтому задачу следует решать в
сферической системе координат. Результирующая сила может быть найдена по
формулам;
где i= 1, 2, ... , n, n -- число элементарных масс Δmi, li=z'-r cosθi. Программа ПР 1.9 для расчета искомой силы F содержит вложенные друг в друга цикл по r, по
φ и по θ, позволяющие перебрать все элементарные массы тела, рассчитать и
просуммировать проекции сил ΔF на ось Oz.
CLS: dr = .1: dtheta = .1: dfi = .2
ПР - 1.9 }
m = 1: rho1 = 100: z1 = 20
'QBASIC
FOR r = 0 TO 3 STEP dr
FOR theta = 0 TO 3.14 STEP dtheta
FOR fi = 0 TO 6.28 STEP dfi
IF r < 1 THEN rho = 100 ELSE rho = 100 / r
z = r * COS(theta): y = r * SIN(theta) * SIN(fi)
x = r * SIN(theta) * COS(fi)
dm = rho * r * r * dtheta * dfi * dr
rast = SQR(x * x + y * y + (z1 - z) * (z1 - z))
l = z1 - r * COS(theta)
F = F + m * dm * l / (rast * rast * rast)
NEXT: NEXT: PRINT F, r
{
12
NEXT
Задача 1.10.
Определите силу гравитационного притяжения, действующую между
неоднородным диском радиусом R, толщиной h и однородным стержнем
массой m1, концы которого имеют координаты a и b>R. Зависимость
плотности диска от координаты: ρ(r)=100/r, где r -- расстояние от его центра
O.
Рис. 1.10. К расчету взаимодействия диска и стержня.
Распределение массы обладает осевой симметрией, будем использовать
полярную и декартовую системы координат (рис. 1.10). Разобъем диск на n
элементарных объемов ΔV=rh ΔφΔr с координатами xi=r cos(φ), yi=r sin(φ) и
массами Δm=ρ(r)ΔV=ρ(r) rhΔφΔr. Стержень рассмотрим как k элементарных
масс Δm1=m1/k с координатами x1j=a+jΔx, где j=1, 2, ... , k. Расстояние между
Δmi и Δm1j равно dij=[(xi - x1j)2 + yi2]0,5. Проекция силы ΔFij на ось Oz равна:
В используемой программе ПР -- 1.10 перебираются все элементарные массы
Δmi и Δm1i обоих тел, определяются и суммируются проекции сил притяжения
на ось Oz.
13
CLS: dr = .1: dfi = .05: rho1 = 100
{ ПР
- 1.10 }
dx1 = .1: dm1 = .2 * dx1: h = .1
FOR x1 = 5 TO 6 STEP dx1
'QBASIC
FOR r = 0 TO 3 STEP dr
FOR fi = 0 TO 6.28 STEP dfi
IF r < 1 THEN rho = 100 ELSE rho = 100 / r
x = r * COS(fi): y = r * SIN(fi): dm = rho * h * r *
dr * dfi
rast = SQR((x - x1) * (x - x1) + y * y): l = x1 - r *
COS(fi)
F = F + dm1 * dm * l / (rast * rast * rast)
NEXT: NEXT: PRINT F, r, x1: NEXT
2. МЕХАНИКА ТОЧКИ
Задача 2.1.
Промоделируйте скольжение материальной точки по циклоидальной горке в
поле тяжести. Убедитесь в том, что циклоида явлется таутохроной, то есть
время скольжения к основанию горки не зависит от точки запуска.
Рис. 2.1. К доказательству таутохронных свойств циклоиды.
14
Исследуем скольжение точки по циклоидальной горке и вычислим время
движения при различных начальных положениях точки (рис. 2.1). Запишем
уравнения циклоиды и выразим параметр α:
Чтобы определить угол β, найдем координаты двух близко расположенных
точек, соответствующих значениям параметра α1, α2 и выразим угол β между
касательной к траектории и осью Oy равен:
Для расчета тангенциального ускорения точки, скорости и координат
используются формулы:
Таким образом, программа ПР - 2.1, моделирующая скольжение тела по
циклоидальной горке, должна содержать цикл по времени , в котором будут
пересчитываться координаты и скорости частицы, осуществляться построения
ее изображения на экране, вычисляться время движения, которое также
выводится на экран. Изменяя начальное значение α, можно запускать точку с
различных положений. При отсутствии трения (rs=0) время скольжения не
зависит от точки запуска (в пределах погрешности вычислений).
uses dos, crt, graph;
{ПР - 2.1}
const r=100; g=10; rs=0.00; dx=0.001;
dt=0.0005; da=0.001; pi=3.1415926;
var c,s,a,b,x1,x2,y1,y2,at,v,vx,vy,x,y,t: real;
Gd,Gm,n : integer; tt : string;
BEGIN Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
15
a:=1.3; x:=r*(a-sin(a)); y:=r*(1-cos(a));
Repeat
c:=1-y/r; s:=sqrt(1-c*c);
If y<=r then a:=arctan(s/c) else a:=piarctan(abs(s/c));
x1:=r*(a-sin(a)); y1:=r*(1-cos(a)); a:=a+da;
x2:=r*(a-sin(a)); y2:=r*(1-cos(a));
b:=pi/2-arctan((y2-y1)/(x2-x1)); at:=g*cos(b)rs*v; v:=v+at*dt;
x:=x+v*sin(b)*dt; y:=y+v*cos(b)*dt;
If n mod 100=0 then begin
Circle(120+round(x),240+round(y),1); end;
Circle(120,240,2); t:=t+dt; inc(n);
until (KeyPressed)or(a>pi);
Str(round(t*1000),tt); OutTextXY(10,10,tt); Readkey;
END.
Задача 2.2.
С помощью вычислительного эксперимента убедитесь в том, что циклоида
является брахистохроной -- кривой наибыстрейшего спуска.
Рассмотрим скольжение частицы массой m по циклоидальной горке в
однородном поле тяжести. Исходя из параметра α, можно вычислить
координаты частицы x1 и y1. Если параметру α дать малое приращение Δα и
рассчитать соответствующие координаты x2, y2, то элементарное перемещение
ΔS можно найти по формуле:
Скорость v вычисляется из закона сохранения механической энергии:
v=(2gy)1/2. Это позволяет определить промежуток времени Δt=ΔS/v, в течение
которого частица, двигаясь со скоростью v, прошла расстояние ΔS. Суммируя
элементарные промежутки времени Δt можно получить общее время
скольжения частицы по кривой из точки O(0,0) до точки A(πR, 2R). Допустим,
необходимо сравнить время скольжения частицы по циклоиде с аналогичным
временем движения по другой кривой, достаточно близкой к циклоиде и
проходящей через точки O(0,0) и A(πR, 2R). Эти кривые могут быть заданы
уравнениями:
где k -- некоторый параметр. Видно, что независимо от значения k при кривые
соединяют точки O(0,0) и A(πR, 2R). При k=1 получается циклоидальная
траектория. В программе можно создать цикл, в котором с некоторым шагом
16
будет изменяться параметр k и вычисляться время движения материальной
точки по соответствующей кривой. При k=1 время должно быть минимально.
Текст используемой программы ПР - 2 приводится ниже. При ее запуске на
экране рисуются траектории, соответствующие различным значениям (рис.
2.2), и рассчитывается время движения частицы и выводится на экран. Из
результатов вычислительного эксперимента следует, что минимальным
является время движения по циклоиде (k=1).
uses dos, crt, graph;
{ПР - 2}
const r=150; dx=0.001; dt=0.001; da=0.0005;
pi=3.1415926;
var k,a,x1,x2,y1,y2,ds,at,v,vx,vy,t : real;
Gd,Gm,n,i : integer; tt,kk : string;
BEGIN
Gd:=Detect; InitGraph(Gd,Gm,'c:\bp\bgi');
For i:=1 to 8 do
begin k:=0.4+0.2*i; a:=0; t:=0;
Repeat
a:=a+da; x1:=r/k*(k*a-sin(a)); y1:=r*(1cos(a));
a:=a+da; x2:=r/k*(k*a-sin(a)); y2:=r*(1cos(a));
ds:=sqrt(sqr(x1-x2)+sqr(y1-y2));
v:=sqrt(20*y1); t:=t+ds/v;
Putpixel(110+round(x1),150+round(y1),15);
until (KeyPressed)or(a>pi);
Str(round(t*1000),tt); OutTextXY(550,10*i,tt);
Str(round(k*10),kk); OutTextXY(500,10*i,kk);
end; Readkey;
END.
17
Рис. 2.2. К доказательству брахистохронных свойств циклоиды.
Задача 2.3.
Промоделируйте скольжение частицы по сферической поверхности и ее
движение после отрыва. Найдите точку отрыва.
Допустим, шайба скользит по шероховатой сферической поверхности и
отрывается от нее на некоторой высоте h. Необходимо рассчитать траекторию
шайбы и время движения. Из второго закона Ньютона можно вычислить
ускорение, скорость и координаты точки в последовательные моменты
времени:
В момент отрыва шайба движется с ускорением g, при этом ее нормальное
ускорение равно:
18
После отрыва от сферической поверхности шайба движется под действием
силы тяжести:
Используется программа ПР - 2.3, в ней определяется высота h отрыва шайбы и
общее время движения, которое выводится на экран. Результат моделирования
приведен на рис. 2.3.
uses dos, crt, graph;
{ПР - 2.3}
const r=200; m=1; mu=0.1; g=10; dt=0.001;
pi=3.1415926;
var a,at,v,vx,vy,x,y,t : real; Gd, Gm,n : integer;
tt : string;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
Line(20,400,600,400); Circle(120,400,199);
a:=0.3; x:=r*sin(a); y:=r*cos(a);
Repeat
inc(n); t:=t+dt;
If v<sqrt(g*r*cos(a)) then
begin
a:=arctan(x/y); at:=g*(sin(a)-mu*cos(a));
v:=v+at*dt; x:=x+v*cos(a)*dt;
y:=y-v*sin(a)*dt; vx:=v*cos(a); vy:=v*sin(a);
end
else begin
vx:=v*cos(a); vy:=vy-g*dt;
x:=x+vx*dt; y:=y+vy*dt;
Circle(250,400-round(y),1);
end;
Circle(120,400,2);
If n mod 300=0 then Circle(120+round(x),400round(y),3);
until (KeyPressed)or(y<-1);
Str(round(t*1000),tt); OutTextXY(10,10,tt); Readkey;
END.
19
Рис. 2.3. Скольжение частице по сферической поверхности.
Задача 2.4.
Изучите движение лыжника, скатывающегося с горы и прыгающего с
трамплина на склон. Профили горки и склона заданы.
Пусть профиль горки и склона, на который прыгает лыжник, задаются
уравнениями:
Для расчета движения лыжника используются уравнения:
20
Программа ПР - 2.4 содержит цикл по времени, в котором пересчитываются
координаты и скорость лыжника в последовательные моменты времени, а
результаты выводятся на экран (рис. 2).
uses dos, crt, graph;
{
ПР - 2.4 }
const r=200; m=1; mu=0.2; g=10; dt=0.001; dx=0.1;
pi=3.1415926;
var a,b,x1,x2,y1,y2,at,v,vx,vy,x,y,t : real;
Gd, Gm,n : integer; tt : string;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
b:=0.015; x:=-160; y:=b*x*x;
Repeat
inc(n); t:=t+dt; delay(1);
If x<30 then
begin x1:=x; y1:=b*x1*x1; x2:=x+dx; y2:=b*x2*x2;
a:=arctan((y1-y2)/(x2-x1));
at:=g*(sin(a)-mu*cos(a));
v:=v+at*dt; x:=x+v*cos(a)*dt;
y:=y-v*sin(a)*dt; vx:=v*cos(a);
vy:=-v*sin(a);
end else
begin vy:=vy-g*dt;
x:=x+vx*dt; y:=y+vy*dt;
end;
If x<30 then Circle(120+round(0.5*x),280round(0.5*y),1);
If n mod 300=0 then
Circle(120+round(0.5*x),280-round(0.5*y),3);
until (KeyPressed)or((y<0)and(y<-sqrt(50*x-3000)));
x:=60;
Repeat
x:=x+1; y:=-sqrt(50*x-3000);
Circle(120+round(0.5*x),280-round(0.5*y),1);
until x>1000;
Str(round(t*1000),tt); OutTextXY(40,330,tt);
21
Readkey;
END.
Рис. 2.4. Движение лыжника.
Задача 2.5.
Из пушки вылетает снаряд с известной скоростью. Определить угол под
которым необходимо произвести выстрел для того, чтобы снаряд попал в
цель. Сила сопротивления, действующая на снаряд, пропорциональна его
скорости.
При движении снаряда на него со стороны воздуха действует сила вязкого
трения. Запишем второй закон Ньютона в конечных разностях:
Для решения задачи используется метод стрельбы: в программе ПР - 2.5
определяется траектория движения снаряда при заданной начальной скорости и
произвольном угле α между стволом орудия и горизонталью. Если снаряд не
поразил цель, то угол α увеличивают на некоторый шаг Δα и повторяют расчет,
22
затем еще раз и еще раз до тех пор, пока снаряд не попадет в цель. Искомое
значение угла в радианах выводится на экран компьютера. Задача имеет два
решения. На рис. 2.5 показан метод нахождения одного из них.
uses crt, graph; {Метод стрельбы}
{ ПР 2.5 }
var x,y,vx,vy,ax,ay,v,Fx,Fy,alfa : real;
Gd, Gm, i: integer; ugol: string; Label metka;
const m=100; dt=0.005; r=1.5; xc=490; yc=30;
BEGIN Gd:= Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
Line(10,0,10,450); Line(0,450,640,450);
Circle(xc+10,450-yc,2); v:=10;
For i:=1 to 40 do
begin
x:=0; y:=0;
alfa:=0.6+0.02*i; str(alfa,ugol);
vx:=v*cos(alfa); vy:=v*sin(alfa);
Repeat
Fy:=-3; Fx:=0;
ax:=(Fx-r*vx)/m; ay:=(Fy-r*vy)/m;
vx:=vx+ax*dt; vy:=vy+ay*dt;
x:=x+vx*dt; y:=y+vy*dt;
Circle(round(x)+10,450-round(y),1);
If sqr(x-xc)+sqr(y-yc)<16 then goto metka;
until (y<0)or(KeyPressed);
end;
metka: OutTextXY(10,10,ugol);
Repeat until KeyPressed; CloseGraph;
END.
Рис. 2.5. Определение направления ствола методом стрельбы.
23
Задача 2.6.
Ракета движется вокруг Земли по круговой орбите радиуса r. При
однократном включении двигателя в течение заданного интервала времени
скорость ракеты увеличивается в k раз. Промоделируйте переход спутника на
круговую орбиту с большим радиусом R.
Свяжем с центром Земли инерциальную систему отсчета. На спутник действует
сила гравитационного притяжения, проекции его ускорения, скорости, а также
его координаты в последовательные моменты времени вычисляются по
формулам:
В программе ПР - 2.6 моделируется переход спутника с одной круговой орбиты
на другую более высокую орбиту. Для этого в моменты времени t=20000 и
t=40000 следует на небольшое время включить двигатели так, чтобы скорость
спутника возрасла в k раз. Результат расчета траектории движения спутника
представлен на рис. 2.6.
uses crt, graph;
{ ПР - 2.6 }
var v, B, q, F, Fx, Fy : real;
r, x, y, vx,vy,ax,ay,t : real; Gd, Gm, i: integer;
const M=1500; mm=200; dt=0.005; k1=1.2; k2=1.22;
BEGIN Gd:= Detect;
InitGraph(Gd, Gm, 'c:\bp\bgi');
If GraphResult <> grOk then Halt(1);
Line(320,240,640,240); Line(320,240,320,0);
Circle(320,240,5);
x:=0; y:=80; vx:=4.1; vy:=0;
Repeat begin
t:=t+1; r:=sqrt(x*x+y*y); F:=M*mm/(r*r);
Fx:=-F*x/r; Fy:=-F*y/r; ax:=Fx/mm; ay:=Fy/mm;
If t=20000 then
begin
vx:=k1*vx; vy:=k1*vy;
Circle(round(x)+320,240-round(y),3);
end;
If t=40000 then
begin
24
vx:=k2*vx; vy:=k2*vy;
Circle(round(x)+320,240-round(y),3);
end;
vx:=vx+ax*dt; vy:=vy+ay*dt;
x:=x+vx*dt; y:=y+vy*dt;
Circle(round(x)+320,240-round(y),1); end;
until KeyPressed; CloseGraph;
END.
Рис. 2.6. Переход спутника на более высокую орбиту.
3. МЕХАНИКА СИСТЕМЫ МАТЕРИАЛЬНЫХ ТОЧЕК
Задача 3.1.
На тележке установлен резервуар с вязкой жидкостью, в котором
расположена горизонтальная направляющая с массивным грузом. Тележка
разгоняется до некоторой скорости и ударяется об упругое препятствие.
Масса тележки и груза, жесткость пружины, коэффициент вязкого трения
известны, начальные скорости заданы. Рассчитайте скорость тележки и груза
после удара, промоделируйте их движение на экране монитора.
25
Рис. 3.1. Движение тележки с грузом при ударе (вязкое трение).
При взаимодействии тележки с пружиной на тележку действует сила упругости
пружины, груз начинает скользить и со стороны него на тележку действует
сила вязкого трения. Из второго закона Ньютона можно определить ускорения
тележки и груза, а затем вычислить их скорости и координаты:
Для моделирования этого явления используется программа ПР - 3.1,
содержащая цикл по времени, в котором вычисляются скорости и координаты
тележки и груза. На экране появляется изображение движущихся тележки и
груза до и после взаимодействия с пружиной.
uses crt, graph;
{ ПР - 3.1 }
var F,Ftr,x1,x2,v1,v2,a1,a2,xx1,xx2,t: real;
Gd, Gm, i: integer;
const m1=1; m2=1.2; dt=0.005; k=0.1; r=0.1;
BEGIN
Gd:= Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
line(220,0,220,480);
x1:=250; v1:=-5; x2:=250; v2:=-5;
Repeat
If x1<0 then F:=-k*x1 else F:=0;
Ftr:=r*abs(v2-v1);
a1:=(F-Ftr)/m1; v1:=v1+a1*dt; x1:=x1+v1*dt;
a2:=Ftr/m2; v2:=v2+a2*dt; x2:=x2+v2*dt;
setcolor(8);
Rectangle(round(xx1)+220,240,round(xx1)+300,250);
26
Circle(round(xx2)+290,230,3); setcolor(15);
Rectangle(round(x1)+220,240,round(x1)+300,250);
Circle(round(x2)+290,230,3); delay(5);
xx1:=x1; xx2:=x2;
until KeyPressed; CloseGraph;
END.
Задача 3.2.
На тележке лежит груз, между ними действует сила трения. Тележка
разгоняется до некоторой скорости и ударяется об упругое препятствие.
Масса тележки и груза, другие параметры системы, а также их начальные
скорости известны. Рассчитайте скорость тележки после удара. Получите на
экране монитора изображения тележки и груза при взаимодействии с
пружиной.
Рис. 3.2. Движение тележки с грузом при ударе (сухое трение).
Решение подобно решению задачи 3.1 с той лишь разницей, что вместо силы
вязкого трения следует учесть силу сухого трения покоя и скольжения.
Программа ПР - 3.2 вычисляет ускорения, скорости и координаты тележки и
тела в последовательные моменты времени и на экране строит их изображения.
uses crt, graph;
{ ПР - 3.2
}
var F,Ftr,x1,x2,xx1,xx2,v1,v2,a1,a2,t: real;
Gd,Gm,i: integer;
const m1=1; m2=1; dt=0.005; k=0.1; g=10; mu=0.03;
BEGIN
Gd:= Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
line(220,0,220,480);
x1:=250; v1:=-7; x2:=250; v2:=-7;
Repeat
If x1<0 then F:=-k*x1 else F:=0;
If (v1=v2) then
If (abs(a2)+abs(a1)<=mu*g) then
27
Ftr:=m2*(abs(a2)+abs(a1))
else Ftr:=-m2*(abs(a2)+abs(a1));
If v1<>v2 then
begin
If (v1>0)and(v2<0) then Ftr:=mu*m2*g;
If (v1<0)and(v2>0) then Ftr:=-mu*m2*g;
If (v1>0)and(v2>0)and(abs(v2)>abs(v1))
then Ftr:=-mu*m2*g;
If (v1>0)and(v2>0)and(abs(v2)<abs(v1))
then Ftr:=mu*m2*g;
end;
a1:=(F-Ftr)/m1; v1:=v1+a1*dt; x1:=x1+v1*dt;
a2:=Ftr/m2; v2:=v2+a2*dt; x2:=x2+v2*dt;
setcolor(8);
Rectangle(round(xx1)+220,240,round(xx1)+400,248);
Circle(round(xx2)+400,230,3);
setcolor(15);
Rectangle(round(x1)+220,240,round(x1)+400,248);
Circle(round(x2)+400,230,3); delay(5);
xx1:=x1; xx2:=x2;
until KeyPressed; CloseGraph;
END.
Задача 3.3.
Тележка с телом движется с некоторой скоростью. В тело попадает пуля и
застревает в нем (или проходит сквозь него). Как изменяются скорости
тележки и пули в процессе взаимодействия?
28
Рис. 3.3.1. Движение тела после попадания пули.
Запишем формулы, позволяющие рассчитать ускорение пули и тела, их
скорости и координаты в следующий момент времени t+1:
Программа ПР - 3.3 содержит цикл по времени, в котором вычисляются сила
взаимодействия пули и тела, их ускорения, скорости и координаты.
Получающиеся графики зависимости скоростей пули и тела от времени
представлены на рис. 3.3.2: слева -- пуля и тело двигались навстречу друг
другу, пуля прошла на вылет; справа -- пуля догнала тело и застряла в нем.
29
uses crt, graph;
{ ПР - 3.3
}
var Ftr,x1,x2,v1,v2,a1,a2,xx1,xx2,t: real;
Gd,Gm,i: integer;
const m1=4; m2=1; dt=0.005; r=0.1;
BEGIN
Gd:= Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
line(220,0,220,40); line(0,350,640,350);
x1:=250; v1:=-4; x2:=0; v2:=10;
Repeat
If abs(x2-x1)<40 then Ftr:=r*abs(v2-v1) else
Ftr:=0;
a1:=Ftr/m1; v1:=v1+a1*dt; x1:=x1+v1*dt; t:=t+dt;
a2:=-Ftr/m2; v2:=v2+a2*dt; x2:=x2+v2*dt;
setcolor(8);
Rectangle(round(xx1)+22040,10,round(xx1)+260,30);
Circle(round(xx2)+220,20,3);
setcolor(15);
Rectangle(round(x1)+220-40,10,round(x1)+260,30);
Circle(round(x2)+220,20,3);
delay(10); xx1:=x1; xx2:=x2;
Circle(round(t*10),350-round(15*v1),1);
Circle(round(t*10),350-round(15*v2),1);
until KeyPressed; CloseGraph;
END.
Рис. 3.3.2. Графики зависимостей скрости пули и тележки от времени.
30
Задача 3.4.
Создайте двумерную модель газа, рассматривая молекулы как частицы, между
которыми действуют силы отталкивания.
Рассмотрим систему материальных точек, движущихся по плоскости, на
которые действуют внешние силы Fi (например, сила тяжести) и внутренние
силы F'i. Из второго закона Ньютона следует:
Программа, моделирующее движение молекул, должна содержать цикл по
времени t, а также цикл, в котором перебираются все молекулы, вычисляются
проекции действующих на сил, определяются ускорение, скорость и
координата в следующий момент времени:
Используется программа ПР - 3.4.
{$N+}
{ ПР 3.4 }
uses dos, crt, graph;
const N=200; dt=0.0002; m=0.1;
var Fx,Fy,x,y,vx,vy: array[1..N] of single;
t,Gd,Gm,i,j: integer; k,ax,ay,F,l : single;
hh: string;
Procedure Sila; label Metka;
begin
For i:=1 to N do begin Fx[i]:=0; Fy[i]:=0; end;
For i:=1 to N do For j:=1 to N do begin
If j=i then goto Metka;
l:=sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j]));
If (l>0)and(l<10) then F:=40000/l else F:=0;
Fx[i]:=Fx[i]+F*(x[i]-x[j])/(l+0.0001);
31
Fy[i]:=Fy[i]+F*(y[i]-y[j])/(l+0.0001);
Metka: end;
end;
Procedure Nach_uslov;
begin Randomize;
For i:=1 to N do begin
x[i]:=10+random(390); y[i]:=10+random(390);
vy[i]:=random(400)/10-20; vx[i]:=random(400)/1020; end; end;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
Nach_uslov;
Repeat Sila;
For i:=1 to N do begin
vx[i]:=vx[i]+Fx[i]/m*dt;
vy[i]:=vy[i]+Fy[i]/m*dt;
x[i]:=x[i]+vx[i]*dt;
y[i]:=y[i]+vy[i]*dt;
If y[i]>400 then y[i]:=10;
If y[i]<10 then y[i]:=400;
If x[i]<10 then x[i]:=400;
If x[i]>400 then x[i]:=10;
end;
If t mod 20=0 then
begin
cleardevice;
For i:=1 to N do
circle(round(x[i]),round(y[i]),2);
end;
t:=t+1; str(t,hh); OuttextXY(550,150,hh);
until KeyPressed;
Repeat until keypressed; CloseGraph;
END.
Задача 3.5.
Рассматривая вязкую жидкость как совокупность твердых шарообразных
частиц, между которыми действуют силы притяжения и отталкивания,
промоделируйте падение жидкого цилиндра на выступ.
Будем моделировать жидкость как совокупность частиц (шариков), между
которыми действуют силы притяжения (при удалении) и отталкивания (при
сближении). Движение каждого шарика подчиняется второму закону Ньютона
и рассчитывается как в задаче 3.4. На систему частиц действует сила тяжести,
она как единое целое падает на выступ или горизонтальную поверхность.
Используется программа ПР - 3.5, результат моделирования представлен на
рис. 3.5.
32
{$N+}
{ ПР - 3.5
}
uses dos, crt, graph;
const N=250; dt=0.003; m=1;
var Fx,Fy,x,y,vx,vy,xx,yy: array[1..N] of single;
t,Gd,Gm,i,j: integer; k,ax,ay,F,l : single;
hh: string;
Procedure Sila; label Metka;
begin
For i:=1 to N do begin Fx[i]:=0; Fy[i]:=0; end;
For i:=1 to N do For j:=1 to N do begin
If j=i then goto Metka;
l:=sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j]));
If (l>9)and(l<30) then F:=-40000/l/l else F:=0;
If l<8 then F:=4000000/l/l/l;
Fx[i]:=Fx[i]+F*(x[i]-x[j])/(l+0.001);
Fy[i]:=Fy[i]+F*(y[i]-y[j])/(l+0.001)+m*10;
Metka: end;
end;
Procedure Nach_uslov;
begin Randomize;
For j:=0 to 24 do For i:=1 to 10 do begin
x[i+10*j]:=8*i+170; y[i+10*j]:=8*j+150;
vy[i]:=0; vx[i]:=0; end;
end;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
Nach_uslov;
Repeat Sila;
For i:=1 to N do
begin k:=0.9;
xx[i]:=x[i];
yy[i]:=y[i];
ax:=Fx[i]/m;
ay:=Fy[i]/m;
vx[i]:=k*vx[i]+ax*dt; vy[i]:=k*vy[i]+ay*dt;
x[i]:=x[i]+vx[i]*dt;
y[i]:=y[i]+vy[i]*dt;
If (x[i]<220)and(y[i]>352) then
begin vx[i]:=-k*vx[i]; x[i]:=221; end;
If (x[i]<220)and(y[i]>350) then
begin vy[i]:=-k*vy[i]; y[i]:=349;
end;
If (y[i]>400) then
begin vy[i]:=-k*vy[i]; y[i]:=399;
end;
end;
cleardevice; setcolor(15);
line(0,402,640,402); rectangle(0,402,318,353);
For i:=1 to N do
33
begin
Circle(100+round(x[i]),round(y[i]),3);
Circle(100+round(x[i]),round(y[i]),1);
end;
t:=t+1; str(t,hh); OuttextXY(150,150,hh);
until KeyPressed;
Repeat until keypressed; CloseGraph;
END.
Рис. 3.5. Падение столба жидкости на выступ.
Задача 3.6.
Используя решение предыдущей задачи создайте компьютерную модель
диффузии двух газов. Считайте молекулы газов твердыми шарами, между
которыми действуют силы отталкивания.
Для решения задачи следует промоделировать движение нескольких десятков
молекул двух сортов внутри прямоугольного сосуда. Чтобы учесть отражение
молекул от стенок в результате абсолютно упругого удара будем использовать
операторы:
If (x[i]>500)or(x[i]<100) then vx[i]:=-vx[i];
If (y[i]>200)or(y[i]<100) then vy[i]:=-vy[i];
Результат работы программы ПР - 3.6, моделирующей диффузию, представлен
на рис. 3.6.
34
{$N+}
{ ПР - 3.6 }
uses dos, crt, graph;
const N=100; dt=0.00005; m=0.01;
var Fx,Fy,x,y,vx,vy: array[1..N] of single;
t,Gd,Gm,i,j: integer; k,ax,ay,F,l : single;
hh: string;
Procedure Sila;
label Metka;
begin
For i:=1 to N do begin Fx[i]:=0; Fy[i]:=0; end;
For i:=1 to N do For j:=1 to N do begin
If j=i then goto Metka;
l:=sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j]));
If (l>0)and(l<10) then F:=40000/l else F:=0;
Fx[i]:=Fx[i]+F*(x[i]-x[j])/(l+0.0001);
Fy[i]:=Fy[i]+F*(y[i]-y[j])/(l+0.0001);
Metka: end; end;
Procedure Nach_uslov;
begin Randomize;
For i:=1 to N do begin y[i]:=102+random(98);
If i<N/2 then x[i]:=102+random(200) else
x[i]:=302+random(198);
vx[i]:=random(800)/10-40; vy[i]:=random(800)/10-40;
end; end;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
Nach_uslov;
Repeat
Sila; inc(t);
For i:=1 to N do
begin
vx[i]:=vx[i]+Fx[i]/m*dt;
vy[i]:=vy[i]+Fy[i]/m*dt;
x[i]:=x[i]+vx[i]*dt;
y[i]:=y[i]+vy[i]*dt;
If (x[i]>500)or(x[i]<100) then vx[i]:=-vx[i];
If (y[i]>200)or(y[i]<100) then vy[i]:=-vy[i];
end;
If t mod 10=0 then
begin cleardevice; setbkcolor(white);
setcolor(8); rectangle(98,98,502,202);
For i:=1 to N do If i<N/2 then begin
setcolor(9);
circle(round(x[i]),round(y[i]),2);
end else begin setcolor(2);
circle(round(x[i]),round(y[i]),4); end;
end;
35
until KeyPressed;
Repeat until keypressed; CloseGraph;
END.
Рис. 3.6. Моделирование диффузии двух газов.
Задача 3.7.
Промоделируйте обтекание пластины газом (сжимаемой жидкостью). Газ
следует представлять в виде совокупности частиц-маркеров, между которыми
действуют силы притяжения и отталкивания.
Рассмотрим двумерную модель газа, представляющую собой совокупность
частиц-маркеров, каждый из которых соответствует элементарному объему.
При удалении маркеров между ними действуют силы притяжения, а при
сближении - силы отталкивания. Пусть на частицы-маркеры действует сила
тяжести, в результате чего они движутся вниз. Поставим на пути их движения
36
препятствие, от которого частицы будут отталкиваться. Используемая
программа ПР - 3.7 позволяет получить результат, изображенный на рис. 3.7.
{$N+}
{ ПР - 3.7 }
uses dos, crt, graph;
const N=250; dt=0.01;
var Fx,Fy,x,y,vx,vy : array[1..N] of real;
m,t,Gd,Gm,i,j : integer; k,F,l : real;
Procedure Sila;
begin
For i:=1 to N do begin Fx[i]:=0; Fy[i]:=0; end;
For i:=1 to N do For j:=1 to N do begin
l:=sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j]));
If (l>0)and(l<100) then F:=-700/(l) else F:=0;
If (l>0)and(l<10) then F:=25000/l;
Fx[i]:=Fx[i]+F*(x[i]-x[j])/(l+0.001);
Fy[i]:=Fy[i]+F*(y[i]-y[j])/(l+0.001)+m*20;
end; end;
Procedure Nach_uslov;
begin Randomize; m:=1;
For j:=0 to 24 do For i:=1 to 10 do begin
x[i+10*j]:=10*i+155; y[i+10*j]:=10*j+120;
end; end;
BEGIN Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
setbkcolor(15); Nach_uslov;
Repeat Sila;
For i:=1 to N do
begin k:=0.2;
vx[i]:=k*vx[i]+Fx[i]/m*dt;
vy[i]:=k*vy[i]+Fy[i]/m*dt;
x[i]:=x[i]+vx[i]*dt;
y[i]:=y[i]+vy[i]*dt;
If (x[i]<160) then begin vx[i]:=-vx[i];
x[i]:=161; end;
If (x[i]>260) then begin vx[i]:=-vx[i];
x[i]:=259; end;
If
(x[i]>180)and(x[i]<240)and(y[i]>320)and(y[i]<324)
then begin vy[i]:=-vy[i];
y[i]:=319; end;
If (y[i]>410) then begin vy[i]:=1; y[i]:=240;
x[i]:=random(90)+165; end;
end; delay(50);
If t mod 2=0 then begin cleardevice; setcolor(12);
For i:=1 to N do begin
circle(round(2*x[i]),round(2*y[i])-400,3); end;
setcolor(8);
37
rectangle(2*180,2*320-400,2*240,2*324-400);
line(2*160,0,2*160,480); line(2*260,0,2*260,480);
end; inc(t);
until KeyPressed; Repeat until keypressed;
CloseGraph;
END.
Рис. 3.7. Обтекание пластины газом.
Задача 3.8.
Промоделируйте конвекцию газа в прямоугольном сосуде с помощью частицмаркеров, между которыми действуют силы отталкивания.
Допустим, квадратный сосуд заполнен двумерным газом, который
моделируется совокупностью частиц-маркеров. Эти частицы соответствуют
элементарным объемам газа, они имеют равные массы, координаты x[i] и y[i],
скорости vx[i] и vy[i], и температуры t[i]. Между частицами-маркерами
действуют силы отталкивания, вычисляемые в процедуре Sila. Левая часть
сосуда нагревается, температура частиц с x[i]<50 равна t[i]:=1, на них действует
сила, направленная вверх. Правая часть сосуда охлаждается, температура
частиц с x[i]>150 составляет t[i]:=-1, на них действует сила, направленная вниз.
Для того, чтобы промоделировать конвекцию газа, необходимо учесть, что
давление в точках, лежащих на одной горизонтали, примерно одинаково. То
38
есть молекулы (а значит и частицы-маркеры), поднимающиеся вблизи левой
стенки вверх, не должны скапливаться в левом верхнем углу сосуда. Для учета
этого фактора сосуд разбивается на 16 квадратов. В процедуре Davlenie
рассчитывается число частиц-маркеров в каждом квадрате, считается, что оно
пропорционально давлению газа. Если в левом квадрате давление меньше чем в
данном, то на частицы данного квадрата действует сила, направленная влево.
Если в правом квадрате давление меньше, то на частицы действует сила,
направленная вправо. Это учитывается в процедуре Sila. Используется
программа PR-1. На рис. 3.8 показаны траектории частиц-маркеров за
небольшой промежуток времени. Левый рисунок соответсвует ситуации, когда
частицы движутся хаотично, конвекция отсутствует.
{$N+}
{ ПР - 3.8 }
uses dos, crt, graph;
const N=80; dt=0.0005; k=0.95; m=0.1;
var Fx,Fy,x,y,vx,vy,xx,yy : array[1..N] of single;
t: array[1..N]of single; p: array[1..10,1..10] of
integer;
FFy,FFx,Gd,Gm,i,j,kk,v,w,v1,w1,time: integer; r,F,l:
single;
Procedure Sila;
begin
For i:=1 to N do begin Fx[i]:=0; Fy[i]:=0; end;
For i:=1 to N do For j:=1 to N do begin
l:=sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j]));
If (l>0)and(l<30) then F:=300000/l else F:=0;
v1:=round(x[i]/50); w1:=round(y[i]/50); FFx:=0;
If ((p[v1,w1]>p[v1-1,w1])and(v1>2)) then
FFx:=70;
If ((p[v1,w1]>p[v1+1,w1])and(v1<3)) then FFx:=70;
Fx[i]:=Fx[i]+F*(x[i]-x[j])/(l+0.001)+FFx;
Fy[i]:=Fy[i]+F*(y[i]-y[j])/(l+0.001)-100*t[i];
end; end;
Procedure Davlenie;
begin
For v:=1 to 4 do For w:=1 to 4 do p[v,w]:=0;
For i:=1 to N do begin For v:=1 to 4 do For w:=1
to 4 do
If (50*(v-1)<x[i])and(x[i]<50*v)and(50*(w1)<y[i])and(y[i]<50*w)
then inc(p[v,w]); end;
end;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
For i:=1 to N do begin
x[i]:=random(198); y[i]:=random(198); end;
Repeat Davlenie; Sila;
39
For i:=1 to N do begin
vx[i]:=k*vx[i]+Fx[i]/m*dt;
vy[i]:=k*vy[i]+Fy[i]/m*dt;
x[i]:=x[i]+vx[i]*dt;
y[i]:=y[i]+vy[i]*dt;
t[i]:=0.8*t[i];
If x[i]>150 then t[i]:=-1;
If x[i]<50 then t[i]:=1;
If x[i]<0 then begin x[i]:=1; vx[i]:=-vx[i];
end;
If x[i]>200 then begin x[i]:=199; vx[i]:=-vx[i];
end;
If y[i]<0 then begin y[i]:=1; vy[i]:=-vy[i];
end;
If y[i]>200 then begin y[i]:=199; vy[i]:=-vy[i];
end;
end; delay(10); inc(time);
rectangle(198,198,402,402);
If time mod 500=0 then cleardevice;
If time mod 20<>0 then
For i:=1 to N do
circle(200+round(x[i]),200+round(y[i]),1);
until KeyPressed; Repeat until keypressed;
CloseGraph;
END.
Рис. 3.8. Конвекция двумерного газа.
Задача 3.9.
Рост некоторых природных объектов (кораллов, снежных хлопьев)
происходит в результате случайного присоединения частей. Этот процесс
называется агрегацией с ограничением диффузии. Возникает фрактал,
имеющий древовидную структуру и называющийся дендритом. Напишите
программу, моделирующую рост дендрита.
40
Промоделируем хаотическое движение молекул некоторого вещества в
растворе. Все молекулы находятся в состоянии 0. Когда какая-нибудь молекула
достигнет ячейки с заравочной частицей, она перейдет в состояние 1,
остановится и изменит свой цвет. Если другая частица приблизится к молекуле,
находящейся в состоянии 1, она как бы осядет, присоединится к ней, тоже
перейдя в состояние 1. Частицы, находящиеся в состоянии 0, продолжают
хаотически двигаться и оседать на частицах, находящихся в состоянии 1. В
результате растет фрактал, имеющий древовидную структуру. Частицы,
обуславливающие его рост, не могут проникнуть в глубь образующегося
дендрита, они оседают на его периферии. Используется программа ПР - 3.9,
результат ее работы представлен на рис. 3.9.2. В ней используются
периодические граничные условия: когда частица выходит через левую
границу квадратной ячейки, она входит в нее через правую границу; когда
частица выходит через нижнюю границу квадратной ячейки, она входит в нее
через верхнюю границу и т.д.
{$N+}
uses dos, crt, graph;
{ ПР - 3.9 }
const N=400;
var Fx,Fy,x,y,vx,vy: array[1..N] of Longint;
h: array[1..N] of boolean;
r,t,Gd,Gm,i,j: integer; k,ax,ay,F,l: single;
hh: string; v: real; label m0;
Procedure Raschet;
label m1;
begin For i:=1 to N do For j:=1 to N do
If h[i]=false then begin
l:=sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j]));
If (h[j]=true)and(l<6) then h[i]:=true;
end; end;
Procedure Nach_uslov;
begin For i:=1 to N do begin
x[i]:=100+round(random(300));
y[i]:=100+round(random(300));
end; end;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
Nach_uslov; Randomize; setbkcolor(15);
Repeat Raschet;
For i:=1 to N do
begin
If h[i]=true then goto m0;
x[i]:=x[i]+round(random(600)/100)-3;
y[i]:=y[i]+round(random(600)/100)-3;
If x[i]<100 then x[i]:=400;
If x[i]>400 then x[i]:=100;
If y[i]>400 then y[i]:=100;
If y[i]<100 then y[i]:=400;
41
If (abs(x[i]-250)<4)and(abs(y[i]-250)<4)then
h[i]:=true;
m0:
end;
If t mod 20=0 then
begin
cleardevice;
For i:=1 to N do
begin
If h[i]=true then setcolor(blue) else
setcolor(red);
circle(round(x[i]),round(y[i]),2);
circle(round(x[i]),round(y[i]),1);
end;
end; inc(t);
until KeyPressed; Repeat until keypressed;
CloseGraph;
END.
Рис. 3.9.1. Рост дендрита.
42
Рис. 3.9.2. Дендрит имеет фрактальную структуру.
4. МЕХАНИКА ТВЕРДОГО ТЕЛА
Задача 4.1.
Стержень устанавливают на горизонтальную поверхность так, чтобы он
образовывал некоторый угол с вертикалью и отпускают. Необходимо
рассчитать координаты его концов при падении в последовательные моменты
времени.
43
Рис. 4.1.1. Падение стержня на горизонтальную поверхность.
Рассмотрим систему, состоящую из двух материальных точек m1 и m2,
связанных между собой невесомым упругим стержнем. Длина стержня в
недеформированном состоянии равна l0, при его сжатии возникают силы
упругости F1 и F2. Будем считать, что нижний конец стержня A скользит по
горизонтальной поверхности, не отрываясь от нее (y1=0). При этом на него
действует сила вязкого трения FТР, пропорциональная скорости и направленная
в сторону противоположную движению. Проекции сил, действующих на
материальные точки m1 и m2 вычисляются из формул:
В программе ПР - 4.1 в последовательные моменты времени пересчитывают
силы, действующие на материальные точки, их ускорения, скорости и
координаты. Результаты моделирования падения стержня при различных
значениях коэффициента сопротивления r представлены на рис. 4.1.2. При
необходимости можно рассчитать траекторию движения центра масс стержня,
зависимость его угла наклона от времени и т.д.
44
uses dos, crt, graph;
{ ПР
- 4.1 }
const m1=1; m2=2; k=100; r=0.02; l0=300; dt=0.001;
var l,x1,x2,y1,y2,vx1,vy1,vx2,vy2,F,Fx1,Fy1,Fx2,Fy2
: real;
Gd, Gm, n : integer;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
x1:=200; y1:=0; x2:=201; y2:=300;
line(0,452,640,452);
Repeat
l:=sqrt(sqr(x1-x2)+sqr(y1-y2)); F:=k*(l0-l);
Fx1:=-F*(x2-x1)/l-r*vx1;
Fx2:=F*(x2-x1)/l; Fy2:=F*(y2-y1)/l-9.8*m2;
vx1:=vx1+Fx1/m1*dt; vy1:=vy1+Fy1/m1*dt;
vx2:=vx2+Fx2/m2*dt; vy2:=vy2+Fy2/m2*dt;
x1:=x1+vx1*dt;
x2:=x2+vx2*dt; y2:=y2+vy2*dt;
if y2<1 then begin vx2:=0; vy2:=0; end;
if n mod 500=0 then begin
line(20+round(x1),450round(y1),20+round(x2),450-round(y2));
line(21+round(x1),451round(y1),21+round(x2),451-round(y2));
circle(20+round(x2),450-round(y2),3); end;
n:=n+1;
until KeyPressed;
END.
Рис. 4.1.2. Результаты моделирования падения стержня.
45
Задача 4.2.
Лестницу прислоняют к стене и отпускают. Напишите программу,
моделирующую падение лестницы, если известно, что ее концы с трением
скользят по поверхностям стены и пола, не отрываясь от них.
Рис. 4.2. Падение стержня на горизонтальную поверхность.
Вместо лестницы рассмотрим систему двух материальных точек массами m1 и
m2, соединенных невесомым упругим стержнем жесткостью k и длиной l 0. Эти
точки как бы скользят по вертикальной и горизонтальной направляющим, при
этом на них действует сила вязкого трения, прямо пропорциональная скорости
и направленная в противоположную сторону. Найдем действующие на точки
силы:
Программа ПР - 4.2 содержит цикл по времени в котором вычисляются силы,
действующие на материальные точки, определяются их ускорения, скорости и
46
координаты, а также координаты центра масс. На экране монитора
изображается положение лестницы в последовательные моменты времени.
uses dos, crt, graph;
{ ПР
- 4.2 }
const m1=3; m2=1; k=1000; r=0.1; dt=0.0004;
var
x1,x2,y1,y2,xc,yc,vx1,vy1,vx2,vy2,l,l0,F,Fx1,Fy1,Fx2,
Fy2 : real;
Gd, Gm, n : integer;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
x1:=100; y1:=300; x2:=150; y2:=0;
l0:=sqrt(sqr(x1-x2)+sqr(y1-y2));
rectangle(100,450,500,100);
Repeat
l:=sqrt(sqr(x1-x2)+sqr(y1-y2)); F:=k*(l0-l);
Fy1:=F*(y1-y2)/l-9.8*m1-r*vy1;
Fx2:=F*(x2-x1)/l-r*vx2;
vy1:=vy1+Fy1/m1*dt; vx2:=vx2+Fx2/m2*dt;
x2:=x2+vx2*dt; y1:=y1+vy1*dt;
xc:=(m1*x1+m2*x2)/(m1+m2); yc:=m1*y1/(m1+m2);
if y1<1 then begin vx1:=0; vy1:=0; end;
delay(10);
if n mod 2000=0 then begin
setcolor(15);
line(round(x1),450-round(y1),round(x2),450round(y2));
line(round(x1+1),451-round(y1),round(x2+1),451round(y2));
setcolor(12);
circle(round(x1),450-round(y1),2);
circle(round(x2),450-round(y2),2);
circle(round(xc),450-round(yc),3);
circle(round(xc),450-round(yc),4);
end; n:=n+1;
until KeyPressed;
END.
47
Рис. 4.2. Падение стержня на горизонтальную поверхность.
Задача 4.3.
Промоделируйте плоское движение тела в поле тяжести, при котором его
центр масс движется по кривой, а само тело вращается вокруг центра масс.
Используйте модель состоящую из двух материальных точек, связанных
упругим стержнем.
Рис. 4.3.1. К вычислению массы, объема и координат центра масс тела.
Рассмотрим систему из двух материальных точек, соединенных упругим
стержнем. Проекции сил, действующих на точки, могут быть вычислены по
формулам:
48
<="" p="">
Программа ПР - 4.3 содержит цикл по времени, в котором вычисляются
действующие силы, ускорения, скорости и координаты точек. На экране
строятся положения стержня в последовательные моменты времени.
Программа позволяет промоделировать: 1) отскок стержня от стены и пола; 2)
движение системы в случае, когда массы точек сильно отличаются; 3)
движение системы при не очень большой жесткости стержня.
uses dos, crt, graph;
{ ПР 4.3 }
const m1=0.2; m2=0.1; k=1000; r=0.005;
b=0.6; l0=40; dt=0.001;
var l,x1,x2,y1,y2,vx1,vy1,vx2,vy2,F,Fx1,Fy1,Fx2,Fy2
: real;
Gd, Gm, n : integer;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
x1:=0; y1:=300; x2:=0; y2:=260; vx1:=50; vy1:=20;
rectangle(2,2,572,442);
Repeat
l:=sqrt(sqr(x1-x2)+sqr(y1-y2)); F:=k*(l-l0);
Fx1:=F*(x2-x1)/l-r*vx1; Fy1:=F*(y2-y1)/l-r*vy10.98*m1;
Fx2:=-F*(x2-x1)/l-r*vx2; Fy2:=-F*(y2-y1)/lr*vy2-0.98*m2;
vx1:=vx1+Fx1/m1*dt; vy1:=vy1+Fy1/m1*dt;
vx2:=vx2+Fx2/m2*dt; vy2:=vy2+Fy2/m2*dt;
x1:=x1+vx1*dt; y1:=y1+vy1*dt;
x2:=x2+vx2*dt; y2:=y2+vy2*dt;
If x1>550 then vx1:=-b*vx1; If x2>550 then
vx2:=-b*vx2;
If y1<-0 then vy1:=-b*vy1; If y2<-0 then vy2:=b*vy2;
circle(20+round(x2),440-round(y2),1);
If n mod 1000=0 then begin
line(20+round(x1),440round(y1),20+round(x2),440-round(y2));
circle(20+round(x1),440-round(y1),3);
49
end; inc(n);
until KeyPressed;
END.
Рис. 4.3.2. Движение палки в поле тяжести.
Задача 4.4.
На тележке массой m1 подвешен маятник, состоящий из тела массой m2 и нити
длиной l. Маятник выводят из положения равновесия и отпускают. В
подшипниках тележки действует сила вязкого трения. Напишите программу,
моделирующую затухающие колебания системы.
Рис. 4.4.1. Движение тележки с маятником.
Заменим систему "маятник-тележка" системой, состоящей из двух
материальных точек m1 и m2, связанных упругим стержнем жесткостью k и
длиной l0. Материальная точка m1 способна скользить по горизонтальной
линии так, что ее координата y2остается постоянной. При этом на нее действует
сила вязкого трения, направленная противоположно скорости и
50
пропорциональная ее величине. Проекции сил, действующих на точки системы,
вычисляются по формулам:
В предлагаемой программе ПР - 4.4 осуществляется расчет действующих на
точки сил, а также проекций их ускорений, скоростей и координат в
последовательные моменты времени. Результаты моделирования представлены
на рис. 4.4.
uses dos, crt, graph;
{ ПР
- 4.4 }
const m1=0.1; m2=0.2; k=100; r=0.01; dt=0.001;
var
l0,l,x1,x2,y1,y2,vx1,vy1,vx2,vy2,F,Fx1,Fy1,Fx2,Fy2 :
real;
Gd, Gm : integer; n: longint;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
x1:=0; y1:=0; x2:=300; y2:=-150;
l0:=sqrt(sqr(x1-x2)+sqr(y1-y2));
Repeat
l:=sqrt(sqr(x1-x2)+sqr(y1-y2)); F:=k*(l-l0);
Fx1:=F*(x2-x1)/l-r*vx1;
Fx2:=-F*(x2-x1)/l;
Fy2:=-F*(y2-y1)/l-0.5*m2;
vx1:=vx1+Fx1/m1*dt;
vx2:=vx2+Fx2/m2*dt;
vy2:=vy2+Fy2/m2*dt;
x1:=x1+vx1*dt;
x2:=x2+vx2*dt;
y2:=y2+vy2*dt;
circle(250+round(x2),50-round(y2),1);
if n mod 8000=0 then begin
line(250+round(x1),50round(y1),250+round(x2),50-round(y2));
line(251+round(x1),51round(y1),251+round(x2),51-round(y2));
circle(250+round(x1),50-round(y1),2);
circle(250+round(x2),50-round(y2),2);
51
circle(250+round(x2),50-round(y2),3);
end; inc(n);
until KeyPressed;
END.
Рис. 4.4.2. Колебания маятника на тележке.
Задача 4.5.
На горизонтальной поверхности покоится кольцо (труба), к внутренней
стороне которого прикреплен груз. Расстояние от оси кольца до его центра
масс известно. Кольцо смещают из положения равновесия от отпускают.
Изучите: 1) колебания кольца относительно положения равновесия; 2)
движение кольца после того, как ему сообщили начальную скорость.
Рис. 4.5.1. Колебания маятника на тележке.
52
Необходимо рассчитать расстояние от центра кольца O до центра масс C,
момент M силы тяжести, момент инерции I относительно мгновенной оси
вращения A. Для этого используют формулы:
Зная момент силы и момент инерции определяют угловое ускорение тела в
последовательные моменты времени, вычисляют угловую скорость и угол
поворота, горизонтальную координату центра кольца. При этом используется
программа ПР-1, результаты представлены на рис. 4.5.2, 4.5.3. Чтобы
промоделировать качение кольца со смещенным центром масс, следует задать
начальную скорость (рис. 4.5.4).
uses dos, crt, graph;
{ ПР - 4.5
}
const dt=0.005; g=9.8; R=60; l=55;
var x,w,fi,mt,mgr,lc,M,I,dd : real;
Gd, Gm : integer; k: longint;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
mt:=1; mgr:=10; x:=-10; fi:=3.0;w:=0;{-0.1;}
Repeat inc(k); lc:=mgr*l/(mgr+mt);
M:=(mgr+mt)*g*lc*sin(fi);
dd:=R*R+l*l-2*R*l*cos(fi);
I:=mgr*dd+2*mt*R*R;
w:=w-M/I*dt; fi:=fi+w*dt; x:=x-R*w*dt;
{
circle(10+round(k/100),300-round(0.4*x),1);}
circle(100+round(x+R*sin(fi)),300+round(R*cos(fi)),1);
if k mod 500=0 then begin {cleardevice;}
line(0,300+R,640,300+R); line(0,301+R,640,301+R);
line(100+round(x),300,100+round(x+R*sin(fi)),300+round
(R*cos(fi)));
circle(100+round(x),300,R);
circle(100+round(x),300,R-1); end;
until (k>7000)or(KeyPressed);
Repeat until KeyPressed; CloseGraph;
END.
53
Рис. 4.5.2. Зависимость угла поворота от времени.
Рис. 4.5.3. Колебания кольца на горизонтальной поверхности.
Рис. 4.5.4. Качение кольца со смещенным центром масс.
54
Задача 4.6.
Брусок в форме прямоугольного параллелепипеда плавает на поверхности
жидкости. Координаты центра масс, плотности жидкости и бруска известны.
Определите расположение бруска относительно поверхности жидкости.
Рис. 4.6.1. К расчету положения тела.
Расположение бруска относительно поверхности воды однозначно
определяется величинами d и φ (рис. 4.6.1). Пусть a=3, b=1. Задача решается
так. Положим, что φ=0. Будем увеличивать d от -3 с некоторым шагом, каждый
раз вычисляя объем погруженной части бруска и определяя силу Архимеда.
Плотность бруска ρ меньше плотности жидкости ρ0, поэтому сила Архимеда
превысит силу тяжести, когда тело не полностью погрузится в жидкость.
Нарисуем поверхность жидкости AB и определим положение центра
плавучести P.
Брусок будет находиться в положении устойчивого равновесия тогда, когда
центр масс C находится точно под центром плавучести P, то есть углы φ и
φ1 равны. Если это условие не выполняется, будем увеличивать угол φ с
некоторым шагом, каждый раз определяя величину d, положение центра
плавучести P и проверяя равенство углов φ и φ1 (оно может выполняться с
небольшой погрешностью). Когда углы φ и φ1 окажутся равными, программы
должна вывести результат вычислений.
55
Для нахождения объема погруженной части тела Vp необходимо найти
площадь S фигуры, выделенной точками. Для этого используется метод
прямоугольников:
For i:=-100 to 100 do begin
x:=dx*i; y:=sin(fi)/cos(fi)*x+d;
If y>b then y:=b; If y<-b then y:=-b;
S:=S+(y+b)*dx;
end;
Чтобы найти координаты xpl и ypl центра плавучести, внутрь прямоугольника
случайным образом бросим 100000 точек и подсчитаем количество точек,
попавших в заштрихованную область S, соответсвующую погруженной части
тела. Используется следующий фрагмент программы:
Repeat x:=(random(200)/100-1)*a;
y:=(random(200)/100-1)*b;
yl:=sin(fi)/cos(fi)*x+d; inc(N);
if y100000;
xpl:=sx/(nn+0.01); ypl:=sy/(nn+0.01);
Результаты работы программы ПР - 4.6 представлены на рис. 4.6.2 и 4.6.3.
Программа рисует прямоугольное сечение бруска и определяет положение
поверхности жидкости AB и центра плавучести. Сила Архимеда направлена
вдоль вертикали MN. В состоянии устойчивого равновесия центр масс C и
центр плавучести P лежат на одной вертикали MN. Изображение,
получающееся на экране монитора, представлено в левой части рис. 4.6.2 и
4.6.3.
{$N+}
uses dos, crt, graph;
const rho=900; rho0=1000; g=9.8;
{ ПР - 4.6
}
Ms=50; a=3; b=1; c=1; xc=1.2;
yc=-0.5; pi=3.1415;
var x,y,dx,d,yl,Vp,V,S,sx,sy,xpl,ypl,Fa,Ft,m,fi,fi1:
single;
i,j,k,Gd,Gm: integer; n,nn: Longint;
BEGIN
Gd:= Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
Randomize; dx:=a/100;
Repeat
inc(j); fi:=pi/300*j; d:=-3;
Repeat S:=0;
{cleardevice;}
For i:=-100 to 100 do
begin
56
x:=dx*i; y:=sin(fi)/cos(fi)*x+d;
If y>b then y:=b; If y<-b then y:=-b;
S:=S+(y+b)*dx;
end;
V:=4*a*b*c; Vp:=S*c;
Fa:=rho0*Vp*g; Ft:=rho*4*a*b*c*g;
d:=d+0.01;
until Fa>Ft;
rectangle(320-Ms*a,240-Ms*b,320+Ms*a,240+Ms*b);
rectangle(318-Ms*a,238-Ms*b,322+Ms*a,242+Ms*b);
circle(round(320+Ms*xc),round(240-Ms*yc),5);
N:=0; nn:=0; sx:=0; sy:=0;
Repeat
x:=(random(200)/100-1)*a;
y:=(random(200)/100-1)*b;
yl:=sin(fi)/cos(fi)*x+d; inc(N);
If y<yl then
begin
inc(nn); sx:=sx+x; sy:=sy+y;
end;
until N>100000;
xpl:=sx/(nn+0.01); ypl:=sy/(nn+0.01);
fi1:=arctan((xc-xpl)/abs(yc-ypl));
circle(round(320+Ms*xpl),round(240-Ms*ypl),2);
circle(round(320+Ms*xpl),round(240-Ms*ypl),3);
line(round(320+Ms*(xpl-5*sin(fi))),round(240Ms*(ypl+5*cos(fi))),
round(320+Ms*(xpl+5*sin(fi))),
round(240-Ms*(ypl-5*cos(fi))));
line(320+Ms*5,240round(Ms*sin(fi)/cos(fi)*5+Ms*d),
320-Ms*5,240-round(-Ms*sin(fi)/cos(fi)*5+Ms*d));
until fi1<fi;
Repeat until KeyPressed; CloseGraph;
END.
57
Рис. 4.6.2. Устойчивое состояние плавающего тела.
Рис. 4.6.3. Устойчивое состояние плавающего тела.
5. РАСЧЕТ ЭЛЕКТРИЧЕСКИХ ЦЕПЕЙ
Задача 5.1.
Электрическая цепь (рис. 5.1) состоит из источника постоянной ЭДС E=200 В,
резистора R1=400 Ом и нелинейного элемента, вольт--амперная
характеристика которого может быть апроксимирована многочленом третьей
степени i(u)=2+5u-0,18u2+0,002u3. Рассчитайте ток в цепи.
58
Рис. 5.1. Расчет нелинейной цепи.
Вольт--амперные характеристики обоих элементов изображены на рис. 5.1
(ВАХ резистора повернута вокруг оси ординат и смещена на E). Напряжение на
нелинейном элементе равно U=E-IR1, поэтому для нахождения искомого тока I
следует решить нелинейное алгебраическое уравнение:
Чтобы решить уравнение необходимо определить количество корней и
локализовать их, то есть установить интервалы, внутри которых находится
каждый корень. Воспользуемся графическим методом, для этого построим
график функции
и найдем точку его пересечения с осью абсцисс, для которой F(I)=0. Она лежит
в интервале 0,2 -- 0,4 мА. Самым простым способом решения подобных
уравнений является табулирование функции F(I). Это может быть реализовано
с помощью алгоритма A-1 (программа ПР - 5.1.1). При запуске программы на
экран выводятся те значения тока, для которых функция F(I) по модулю
меньше чем ε =0,01, то есть близка к нулю. Это позволяет уменьшить
неопределенность в нахождении корня до 0,01, корень уравнения лежит в
интервале от 2,960 до 2,965. Ответ: ток примерно равен 2,962 А.
uses crt, graph; const N=200;
{ ПР 5.1.1 }
var EC,D,DrV,MV,i,j,q1,q2,q3,x1,y1,x2,y2,x3,y3,k:
integer;
u,tok,tok1,a0,a1,a2,a3,r1,E: real;
BEGIN
clrscr; a0:=2; a1:=5; a2:=-0.18;
a3:=0.002; R1:=400; E:=200;
For i:=0 to 2000 do
59
begin
tok:=0.0005*i; u:=E-Tok*R1;
Tok1:=0.001*(a0+a1*u+a2*u*u+a3*u*u*u);
If abs(tok-tok1)<0.01 then
writeln(tok, ' ', tok1, ' ', toktok1);
end; readkey;
END.
Другой способ решения уравнения F(x)=0 состоит в использовании метода
половинного деления. Задается интервал [a0, b0], содержащий корень. График
функции y=F(x) должен пересекать ось абсцисс внутри интервала, на его
границах функция имеет противоположны знаки, в чем можно убедиться,
проверив условие F(a0)F(b0)<0. Отрезок [a0, b0] делится точкой с=(a+b)/2
попалам. Если F(c)=0, то значение x=c и есть корень уравнения. В противном
случае из двух отрезков [a0,c] и [c,b0] выбирается тот, внутри которого график
y=F(x) пересекает ось абсцисс. Для этого снова проверяется условие
F(c)F(b0)<0, если оно выполняется, то a1=c, b1=b0. После этого осуществляется
следующая итерация: отрезок [a1, b1] снова делится попалам и т.д. Так
продолжается до тех пор, пока длина отрезка [ai, bi] не окажется меньше
заданной точности ε.
Используется программа ПР - 5.1.2. Понятно, что ток в цепи не может
превышать значение E/R1, поэтому в качестве нулевого приближения к корню
выберем интервал [0, E/R1]. В результате последовательности итераций при
ε=0,0000001 получается корень уравнения 2,96296. Округляя до четырех
значащих цифр, получаем: ток равен 2,963 А.
uses crt;
{ ПР 5.1.2 }
var a0,a1,a2,a3,r1,E,u,tok,tok1,y1,y2,y3,a,b,c,eps:
real;
Label metka;
Function Funk(Tok: real): real;
begin
u:=E-Tok*R1;
Funk:=0.001*(a0+a1*u+a2*u*u+a3*u*u*u)-Tok;
end;
BEGIN
clrscr; a0:=2; a1:=5; a2:=-0.18; a3:=0.002;
R1:=400; E:=200; a:=0; b:=E/R1; eps:=0.0000001;
metka:
y1:=Funk(a); y2:=Funk(b); c:=(a+b)/2; y3:=Funk(c);
writeln(a, b); if (y1*y3)>0 then a:=c else b:=c;
If (b-a)>eps then goto metka;
writeln('Корень лежит в интервале ', a, b);
writeln('0= ',Funk(a)); readkey;
END.
60
Задача 5.2.
Напишите программу, рассчитывающую сопротивление цепи, состоящей из
бесконечной цепочки резисторов R1=80 Ом и R2=100 Ом (рис. 5.2).
Рис. 5.2. Схема из бесконечной цепочки резисторов.
Найдем сопротивление участка цепи MABN из двух ветвей, участка цепи
MACDBN из четырех ветвей, участка цепи MACEFDBN из шести ветвей.
Обобщим получающуюся формулу:
Программа ПР - 5.2 последовательно вычисляет сопротивление Z1, Z2, Z3, ... и
результат выводит на экран. Получающиеся значения стремятся к величине 138
Ом.
uses crt;
{ ПР - 5.2 }
const r1=80; r2=100;
var i: integer;
z: array [1..200] of real;
BEGIN
clrscr; i:=1; z[1]:=r1+r2;
Repeat
writeln(i,' ',z[i]); inc(i);
61
z[i]:=r1+r2*z[i-1]/(r2+z[i-1]);
until (i>20)or(KeyPressed);
readkey;
END.
Задача 5.3.
Напишите программу, решающую систему из N линейных алгебраических
уравнений.
Рассмотрим алгоритм, позволяющий решать систему из n линейных
алгебраических уравнений с n неизвестными, имеющую следующий вид:
От этой системы перейдем к матрице из элементов ai,j, где i=1, 2, ... , n и j=1, 2,
... , n+1.
Приведем данную матрицу к треугольному виду. Чтобы исключить деление на
ноль сложим левые и правые части первого и второго, первого и третьего,
второго и четвертого уравнений и т.д. Первый шаг состоит в следующем:
разделим все элементы каждой строки матрицы (или каждого уравнения
системы) на первый коэффициент ai1, где i=1, 2, ... , n. Тогда все элементы ai1 из
первого столбца будут равны 1. Вычтем из второго, третьего и последующих
уравнений первое. Матрица коэффициентов приобретет вид:
62
где a'i,j=ai,j/ai1- a1j/a11, где i=1, 2, ... , n и j=1, 2, ... , n+1. После этого сделаем
второй шаг: разделим вторую, третью и последующие строки матрица на
соответствующие коэффиценты $ai2, после чего вычтем из третьей, четвертой и
последующих строк вторую строку. Получим:
где a''ij=a'ij/a'i1- a'1j/a'11, где i=1, 2, ... , n и j=1, 2, ... , n+1. После n-ого шага
получим матрицу треугольного вида:
Искомые значения находятся по формулам:
Желательно, чтобы программа осуществляла проверку решения, подставляя
найденные значения x1, x2, ... в исходную систему уравнений.
63
uses crt; const n=6; var i,ii,j,k : integer;
{
ПР - 5.3 }
aa,a: array[1..N, 1..N+1] of real; b,x: array[1..N]
of real;
BEGIN
clrscr;
a[1,1]:=13; a[1,2]:=21; a[1,3]:=0; a[1,4]:=-8;
a[1,5]:=0; a[1,6]:=0; a[1,7]:=-24;
a[2,1]:=0; a[2,2]:=0; a[2,3]:=0; a[2,4]:=8;
a[2,5]:=-17;a[2,6]:=11; a[2,7]:=-14;
a[3,1]:=0; a[3,2]:=-21;a[3,3]:=15; a[3,4]:=0;
a[3,5]:=0; a[3,6]:=-11;a[3,7]:=30;
a[4,1]:=1; a[4,2]:=0; a[4,3]:=0; a[4,4]:=1;
a[4,5]:=1; a[4,6]:=0; a[4,7]:=0;
a[5,1]:=-1; a[5,2]:=1; a[5,3]:=1; a[5,4]:=0;
a[5,5]:=0; a[5,6]:=0; a[5,7]:=0;
a[6,1]:=0; a[6,2]:=0; a[6,3]:=-1; a[6,4]:=0;
a[6,5]:=-1; a[6,6]:=-1; a[6,7]:=0;
For i:=1 to N do For j:=1 to N+1 do aa[i,j]:=a[i,j];
For i:=1 to N do For j:=1 to N+1 do
a[i,j]:=a[i,j]+a[1,j]+a[N,j];
For i:=2 to N do For j:=1 to N+1 do
a[i,j]:=a[i,j]+a[2,j]+a[N-1,j];
For i:=3 to N do For j:=1 to N+1 do
a[i,j]:=a[i,j]+a[3,j]+a[4,j];
For i:=1 to N do
begin
For j:=1 to N+1 do write(a[i,j]:2:3, ' ');
writeln;
end; writeln;
For k:=1 to N do
begin
For i:=k to N do
For j:=1 to N+1 do a[i,N+2-j]:=a[i,N+2j]/a[i,k];
For i:=k+1 to N do
For j:=1 to N+1 do a[i,j]:=a[i,j]-a[k,j];
end;
For i:=1 to N do
begin
For j:=1 to N+1 do write(a[i,j]:2:3, ' ');
writeln;
end; writeln; delay(13000);
For ii:=1 to N do
begin
i:=N-ii+1; x[i]:=-a[i,N+1];
For j:=i+1 to N do x[i]:=x[i]-a[i,j]*x[j];
64
end;
writeln(' ОТВЕТ '); For i:=1 to N do
writeln('x[',i,']= ',x[i]);
writeln(' ПРОВЕРКА ');
For i:=1 to N do
begin
For j:=1 to N do b[i]:=b[i]+aa[i,j]*x[j];
writeln(b[i]+aa[i,N+1]:2:7);
end; ReadKey;
END.
Задача 5.4.
Рассчитате цепь постоянного тока, состоящую из нескольких контуров (рис.
5.4). Сопротивления резисторов R1=13 Ом, R2=21 Ом, R3=15 Ом, R4=8 Ом,
R5=17 Ом, R6=11 Ом. ЭДС источников E1=5 В, E2=13 В, E3=9 В, E4=-6 В, E5=12
В, E6=-8 В.
Рис. 5.4. Электрическая цепь постоянного тока.
Используя законы Кирхгофа составим систему уравнений (рис.01). Подставим
вместо сопротивлений и ЭДС конкретные значения, перенесем все члены в
левую часть:
65
Для решения системы уравнений с n неизвестными используется программа ПР
- 5.3. На экран выводятся значения переменных и осществляется проверка: в
исходную систему подставляются найденные значения xi, i=1, 2, ... ,n. При этом
левые части уравнений обращаются в ноль, что подтверждает правильность
решения. Итак, полученные значения токов: I1=0,481 А, I2=0,812 А, I3=-0,331 А,
I4=-0,086 А, I5=-0,395 А, I6=0,726 А. Знак минус означает, что реальное
направление тока в соответствующей ветви противоположно предполагаемому.
Задача 5.5.
Цепь состоит из источника переменной ЭДС и трех ветвей, в каждой из
которых резистор, конденсатор и катушка индуктивности. Вторая и третья
ветви соединены параллельно между собой, последовательно с ними
включена первая ветвь. Рассчитайте все токи и напряжения, полную,
активную и реактивную мощности. Постройте векторную диаграмму.
Определите действующие значения всех токов и напряжений.
Рис. 5.5. Однофазная цепь переменного тока.
Допустим, цепь имеет параметры: R1=10 Ом, L1=0.08 Гн, C1=1200 мкФ, R2=8
Ом, L2=0.42 Гн, C2=1500 мкФ, R3=14 Ом, L3=0.14 Гн, C3=1270 мкФ. Для
вычисления импедансов, токов и напряжений для каждой ветви используются
формулы:
66
Представленная ниже программа ПР - 5.5 содержит процедуры Sum, Razn,
Proizv, Delen, Modul, позволяющие определять сумму, разность, произведение,
отношение двух комплексных чисел и находить модуль комплексного числа. С
помощью этих процедур осуществляются расчеты комплексов тока и
напряжения, комплекса мощности.
uses crt, graph;
{ ПР 5.5 }
const n=4;
type komplex = record Re : real; Im : real; end;
var I1,Iba,Icb,Iac,E,EB,EC,z1,z2,z3,S,R,P,D,U,Z,C :
komplex;
var i,ii,j,jj,k : integer; w,m:real;
aa,a: array[1..N, 1..N+1] of komplex;
x,bb,b: array[1..N] of komplex;
Procedure Sum(Z1, Z2: komplex);
begin S.Re:=Z1.Re+Z2.Re; S.Im:=Z1.Im+Z2.Im; end;
Procedure Razn(Z1, Z2: komplex);
begin R.Re:=Z1.Re-Z2.Re; R.Im:=Z1.Im-Z2.Im; end;
Procedure Proizv(Z1, Z2: komplex);
begin P.Re:=Z1.Re*Z2.Re-Z1.Im*Z2.Im;
P.Im:=Z1.Re*Z2.Im+Z2.Re*Z1.Im; end;
Procedure Delen(Z1, Z2: komplex);
begin
D.Re:=(Z1.Re*Z2.Re+Z1.Im*Z2.Im)/(Z2.Re*Z2.Re+Z2.Im*Z2
.Im);
D.Im:=(Z1.Im*Z2.ReZ1.Re*Z2.Im)/(Z2.Re*Z2.Re+Z2.Im*Z2.Im); end;
Procedure Modul(Z1: komplex);
begin M:=sqrt(Z1.Re*Z1.Re+Z1.Im*Z1.Im); end;
67
BEGIN
clrscr; w:=2*3.1415926*50;
Z1.Re:=10; Z1.Im:=w*0.08-1000000/(w*1200);
Z2.Re:=8; Z2.Im:=w*0.42-1000000/(w*1500);
Z3.Re:=14; Z3.Im:=w*0.14-1000000/(w*1270);
writeln('Z1= ', Z1.Re:2:3,' ',Z1.Im:2:3,'j');
writeln('Z1= ', Z2.Re:2:3,' ',Z2.Im:2:3,'j');
writeln('Z1= ', Z3.Re:2:3,' ',Z3.Im:2:3,'j');
Proizv(Z2,Z3); Sum(Z2,Z3); Delen(P,S); Sum(Z1,D);
Modul(S);
writeln('Z = ',S.Re:2:3,' ',S.Im:2:3,'j ', M:2:3);
E.Re:=127; E.Im:=0; Delen(E,S); I1:=D; Modul(D);
writeln('I1= ', D.Re:2:3,' ',D.Im:2:3,'j ', M:2:3);
Proizv(D,Z1); Modul(P);
writeln('U1= ', P.Re:2:3,' ',P.Im:2:3,'j ', M:2:3);
Razn(E,P);
Modul(R);
writeln('U2= ', R.Re:2:3,' ',R.Im:2:3,'j ', M:2:3);
Delen(R,Z2); Modul(D);
writeln('I2= ', D.Re:2:3,' ',D.Im:2:3,'j ', M:2:3);
Delen(R,Z3); Modul(D);
writeln('I3= ', D.Re:2:3,' ',D.Im:2:3,'j ', M:2:3);
I1.Im:=-I1.Im;
Proizv(E,I1); writeln('S = ', P.Re:2:3,' ',
P.Im:2:3,'j');
ReadKey;
END.
Задача 5.6.
Напишите программу, решающую систему из N линейных уравнений в
комплексных числах и позволяющую рассчитать трехфазную цепь,
изображенную на рис. 5.6.
Рис. 5.6. Трехфазная цепь.
68
Изучение трехфазных цепей предполагает нахождение комплексных значений
токов, что требует решения системы уравнений в комплексных числах. По
законам Кирхгофа составим систему уравнений в комплексных числах. Цепь
имеет три независимых контура и два узла O и O', всего 4 ветви; получаем
систему из 4 независимых уравнений:
Эта системы уравнений может быть решена путем приведения матрицы
коэффициентов к треугольному виду. В используемой программе ПР - 5.6
операции сложения, вычитания, умножения и деления комплексных чисел
осуществляются в процедурах Sum, Razn, Proizv, Delen. Сначала, чтобы
исключить деление на 0, складываются второе, третье и последующие
уравнения с первым. Делят элементы каждой строки матрицы на первый
элемент, после чего вычитают из второй, третьей и т.д. строк первую. В
результате первые элементы второй, третьей и последующих строк
оказываются равными 0. Аналогичным образом приводят к 0 вторые элементы
третьей, четвертой и последующих строк и т.д. Эти операции повторяют до тех
пор, пока матрица не будет приведена к треугольному виду. Это позволяет
вычислить искомые значения комплексов токов и осуществить проверку
решения. Эта программа может быть использована для решения системы
уравнений в действительных числах.
uses crt, graph;
{ ПР 5.6 }
const n=4;
type komplex = record Re : real; Im : real; end;
var z1,z2,z3,S,R,P,D,U,Z,C :komplex;
var i,ii,j,jj,k : integer; m:real;
aa,a: array[1..N, 1..N+1] of komplex;
x,bb,b: array[1..N] of komplex;
Procedure Sum(Z1, Z2: komplex);
begin S.Re:=Z1.Re+Z2.Re; S.Im:=Z1.Im+Z2.Im; end;
Procedure Razn(Z1, Z2: komplex);
begin R.Re:=Z1.Re-Z2.Re; R.Im:=Z1.Im-Z2.Im; end;
Procedure Proizv(Z1, Z2: komplex);
begin P.Re:=Z1.Re*Z2.Re-Z1.Im*Z2.Im;
P.Im:=Z1.Re*Z2.Im+Z2.Re*Z1.Im; end;
Procedure Delen(Z1, Z2: komplex);
begin
D.Re:=(Z1.Re*Z2.Re+Z1.Im*Z2.Im)/(Z2.Re*Z2.Re+Z2.Im*Z2.
Im);
69
D.Im:=(Z1.Im*Z2.ReZ1.Re*Z2.Im)/(Z2.Re*Z2.Re+Z2.Im*Z2.Im);
end;
Procedure Modul(Z1: komplex);
begin M:=sqrt(Z1.Re*Z1.Re+Z1.Im*Z1.Im); end;
BEGIN
clrscr;
a[1,1].Re:=-1;a[1,2].Re:=1; a[1,3].Re:=1;
a[1,4].Re:=1; a[1,5].Re:=0;
a[2,1].Re:=10;a[2,2].Re:=100; a[2,3].Re:=0;
a[2,4].Re:=0; a[2,5].Re:=-220;
a[3,1].Re:=10;a[3,2].Re:=0; a[3,3].Re:=0;
a[3,4].Re:=0; a[3,5].Re:=110;
a[4,1].Re:=10;a[4,2].Re:=0; a[4,3].Re:=0;
a[4,4].Re:=0; a[4,5].Re:=110;
a[1,1].Im:=0; a[1,2].Im:=0; a[1,3].Im:=0;
a[1,4].Im:=0; a[1,5].Im:=0;
a[2,1].Im:=0; a[2,2].Im:=0; a[2,3].Im:=0;
a[2,4].Im:=0; a[2,5].Im:=0;
a[3,1].Im:=0; a[3,2].Im:=0; a[3,3].Im:=-120;
a[3,4].Im:=0; a[3,5].Im:=-110*1.73;
a[4,1].Im:=0; a[4,2].Im:=0; a[4,3].Im:=0;
a[4,4].Im:=80; a[4,5].Im:=+110*1.73;
For i:=1 to N do For j:=1 to N+1 do aa[i,j]:=a[i,j];
For i:=2 to N do For j:=1 to N+1 do
begin
Sum(a[i,j],a[1,j]); a[i,j]:=S;
end;
For i:=3 to N do For j:=1 to N+1 do
begin
Sum(a[i,j],a[2,j]); a[i,j]:=S;
end;
For i:=4 to N do For j:=1 to N+1 do
begin
Sum(a[i,j],a[3,j]); a[i,j]:=S;
end;
For k:=1 to N do
begin
For i:=k to N do For j:=1 to N+1 do
begin
Delen(a[i,N+2-j],a[i,k]); a[i,N+2-j]:=D;
end;
For i:=k+1 to N do For j:=1 to N+1 do
begin
Razn(a[i,j],a[k,j]); a[i,j]:=R;
end;
end;
For i:=1 to N do
70
begin
For j:=1 to N+1 do
write(a[i,j].Re:2:3, ' '); writeln;
end; writeln;
For i:=1 to N do
begin
For j:=1 to N+1 do write(a[i,j].Im:2:3, ' ');
writeln;
end; writeln;
For ii:=1 to N do
begin i:=N-ii+1;
x[i].Re:=-a[i,N+1].Re;
x[i].Im:=-a[i,N+1].Im;
For j:=i+1 to N do
begin
Proizv(a[i,j],x[j]);
Razn(x[i],P); x[i]:=R;
end;
end;
writeln(' ОТВЕТ ');
For i:=1 to N do
begin Modul(x[i]);
writeln('x[',i,']= ',x[i].Re,' ',x[i].Im, M);
end;
writeln(' ПРОВЕРКА ');
For i:=1 to N do
begin
Proizv(aa[i,1],x[1]); C:=P;
Proizv(aa[i,2],x[2]); Sum(P,C); C:=S;
Proizv(aa[i,3],x[3]); Sum(P,C); C:=S;
Proizv(aa[i,4],x[4]); Sum(P,C); C:=S;
Sum(aa[i,5],C); writeln(S.Re,' ',S.Im);
end; ReadKey;
END.
6. РАСЧЕТ ЭЛЕКТРИЧЕСКОГО И
МАГНИТНОГО ПОЛЕЙ
Задача 6.1.
Три точечных заряда q1, q2, q3 имеют координаты (x1, y1), (x2, y2), (x3, y3).
Рассчитайте потенциал электростатического поля во всех точках плоскости,
содержащей эти заряды.
71
В цикле будем перебирать все точки плоскости (пиксели экрана), задаваемые
целочисленными параметрами i и j. При этом будем вычислять расстояния от
данной точки до каждого заряда и находить алгебраическую сумму
потенциалов:
В зависимости от величины потенциала ставится точка соответствующего
цвета. Используется программа ПР - 6.1.1, результат моделирования --- на рис.
6.1.1.
uses crt, graph;
{ ПР - 6.1.1 }
var r1,r2,r3,x1,x2,x3,y1,y2,y3,fi,q1,q2,q3: real;
Gd,Gm,i,j :integer;
BEGIN
Gd:= Detect; InitGraph(Gd, Gm, 'c:\bp\bgi\');
q1:=15; q2:=-20; q3:=10; q1:=8; q2:=46;
x1:=180.5; y1:=150.5; x2:=400.5;
y2:=180.5; x3:=240.5; y3:=340.5;
For i:=0 to 640 do For j:=0 to 480 do
begin
r1:=sqrt(sqr(x1-i)+sqr(y1-j));
r2:=sqrt(sqr(x2-i)+sqr(y2-j));
r3:=sqrt(sqr(x3-i)+sqr(y3-j));
fi:=q1/r1+q2/r2+q3/r3;
putpixel(i,j,round((fi+1)*13));
{If round(fi/0.05)-fi/0.05<0.002 then
putpixel(i,j,15);}
end;
Repeat until Keypressed; CloseGraph;
END.
Рис. 6.1.1. Расчет потенциала поля точечных зарядов.
72
Рассмотренный метод может быть использован для расчета полей, созданных
протяженными заряженными телами. Например, чтобы промоделировать
электростатическое поле плоской пластины можно вместо нее расположить 1020 точечных зарядов, лежащих на прямой. Программа ПР - 6.1.2 рассчитывает
поле пластины и расположенного рядом с ней точечного заряда. Результат
вычислений приведен на рис. 6.1.2.
uses crt, graph;
const N=40;
var fi : real; Gd,Gm,i,j,k :integer;
q, x, y, r : array[1..N]of real;
BEGIN
Gd:= Detect; InitGraph(Gd, Gm, 'c:\bp\bgi\');
For k:=1 to 20 do
begin
q[k]:=10; y[k]:=100; x[k]:=200+20*k; end;
{For k:=21 to 40 do
begin
q[k]:=-10; y[k]:=200;
x[k]:=100+20*(k-20);
end;}
q[k]:=-40; y[k]:=200; x[k]:=400;
For i:=0 to 640 do For j:=0 to 480 do
begin
fi:=0;
For k:=1 to N do
begin
r[k]:=sqrt(sqr(x[k]-i)+sqr(y[k]-j));
If r[k]<>0 then fi:=fi+q[k]/r[k];
end;
putpixel(i,j,round((fi+1)*13));
end;
Repeat until Keypressed; CloseGraph;
END.
73
Рис. 6.1.2. Расчет потенциала поля точечных зарядов.
Задача 6.2.
Две пластины имеют потенциалы 100 В и -100 В. Между ними вблизи краев
находится металлический шарик с потенциалом 20 В. Рассчитайте
распределение потенциала.
Расчет распределения потенциала электрического поля, созданного
протяженными заряженными телами, требует решения уравнения Пуассона.
Запишем его в конечных разностях:
Для решения задачи используется программа ПР - 6.2. Результат расчета
распределения потенциала представлен на рис. 6.2.
74
{$N+}
uses crt, graph;
{ ПР 6.2 }
const N=100; M=100; NN=200; h=0.2; dt=0.1;
SizeOfReal=6;
type
RealPoint= ^real;
var t: single; i,j,ii,jj,DV,MV,EC: integer;
a: array[1..NN] of pointer; vv,rho,kk,k : real;
Function fi(i,j: word) : RealPoint;
begin
fi:=Ptr(Seg(a[i]^),ofs(a[i]^)+(j-i)*SizeOfReal);
end;
Procedure Raschet; begin vv:=1; k:=0.1;
For i:=2 to N-1 do for j:=2 to M-1 do
begin
If j<M then
begin
If (i=80)and(j>30) then fi(i,j)^:=100;
If (i=20)and(j>30) then fi(i,j)^:=-100;
end;
If sqr(i-60)+sqr(j-70)<100 then fi(i,j)^:=20;
fi(i+n,j)^:=(fi(i-1,j)^+fi(i+1,j)^+
fi(i,j-1)^+fi(i,j+1)^+rho*h*h)/4;
end;
For j:=2 to M-1 do for i:=2 to N-1 do
fi(i,j)^:=fi(i+n,j)^;
For j:=1 to M do fi(1,j)^:=0; For j:=1 to M do
fi(N,j)^:=0;
For i:=1 to N do fi(i,2)^:=0; For i:=1 to N do
fi(i,M)^:=fi(i,M-1)^;
end;
Procedure Draw;
begin
for i:=2 to N-1 do for j:=2 to M-1 do
begin
setcolor(round(fi(i,j)^/8)+1);
If sqr(i-60)+sqr(j-70)<100 then setcolor(15);
rectangle(11+i*4,450-j*4,13+i*4,453-j*4);
rectangle(10+i*4,450-j*4,12+i*4,452-j*4);
end;
end;
BEGIN
DV:=Detect; InitGraph(DV,MV,'c:\bp\bgi');
For i:=1 to NN do begin GetMem(a[i], M*SizeOfReal);
For j:=1 to M do fi(i,j)^:=0; end;
Repeat
t:=t+dt; Raschet; kk:=kk+1;
75
If kk=round(kk/25)*25 then Draw;
until KeyPressed;
Release(HeapOrg); CloseGraph;
END.
Рис. 6.2. Моделирование электростатического поля.
Задача 6.3.
Постройте силовые линии магнитного поля, созданного: 1) одной обмоткой с
током; 2) двумя обмотками, по которым текут токи в одном направлении или
в противоположных направлениях.
Рассмотрим виток с током радиусом r, лежащий в плоскости XOY. Разобъем
его на элементы и введем вектора
сонаправленные с током. Расположение этого элемента витка и точки A, в
которой определяется индукция магнитного поля, задаются векторами:
По закону Био-Савара-Лапласа для вектора индукции и его проекций можно
76
записать:
При этом используются формулы:
Используется программа ПР - 6.3. Для построения силовой линии задают
начальную точку A0, определяют в ней направление индукции магнитного
поля, строят небольшой отрезок в направлении вектора индукции, переходя в
новую точку A1. Затем повторяют все снова. Результаты вычислений -- на рис.
6.3.1, 6.3.2, 6.3.3.
Uses crt, graph;
{ ПР - 6.3
}
Const N=200; pi=3.1415;
Var S,k,kk,nn,ii,jj,i,j,DV,MV,r,r1,TOK: integer;
Rx,Ry,Rz,BBB: real;
Bx,By,Bz,dfi,deltax,deltay,deltaz,deltaR,dlx,dly,dlz,
alpha: real;
Procedure Raschet;
begin For i:=1 to N do begin
dfi:=2*pi/N; dlx:=TOK*r*sin(dfi*i)*dfi; dly:=TOK*r*cos(dfi*i)*dfi;
deltax:=r*cos(dfi*i)-Rx; deltay:=r*sin(dfi*i)-Ry;
deltaR:=sqrt(deltax*deltax+deltay*deltay+deltaz*delta
z);
Bz:=(dlx*deltaydly*deltax)/(deltaR*deltaR*deltaR)+Bz;
By:=(dlz*deltaxdlx*deltaz)/(deltaR*deltaR*deltaR)+By;
end; end;
Procedure Postroenie;
begin
Repeat Bz:=0; By:=0; r:=80;
77
For k:=0 to 3 do begin
deltaz:=50*k-Rz; TOK:=1; Raschet; end; r:=50;
For kk:=0 to 1 do begin
deltaz:=30*kk-Rz+300; TOK:=-1; Raschet; end;
BBB:=sqrt(By*By+Bz*Bz);
circle(320+round(Ry),450-round(Rz),1);
Ry:=Ry+By/BBB; Rz:=Rz+Bz/BBB; nn:=nn+1;
For k:=0 to 3 do begin
circle(320+80,450-50*k,3);
circle(320-80,450-50*k,3); end;
For kk:=0 to 1 do begin
circle(320+50,450-30*kk-300,3);
circle(320-50,450-30*kk-300,3); end;
until (KeyPressed)or(nn>300);
end;
BEGIN
DV:=Detect; InitGraph(DV,MV,'c:\bp\bgi'); Rx:=0;
For ii:=-4 to 5 do
begin
Ry:=-5+10*ii; Rz:=20; nn:=0; Postroenie;
end;
For ii:=-3 to 4 do
begin
Ry:=-5+10*ii; Rz:=350; nn:=0; Postroenie;
end;
Repeat until KeyPressed; CloseGraph;
END.
78
Рис. 6.3.1. Магнитное поле обмотки.
79
Рис. 6.3.2. Магнитное поле двух обмоток. Токи сонаправлены.
80
Рис. 6.3.3. Магнитное поле двух обмоток. Токи
противоположнонаправлены.
Задача 6.4.
Постройте силовые линии магнитного поля, созданного тремя параллельными
проводниками с током.
81
Рис. 6.4.1. Расчет магнитного поля двух токов.
Допустим, два проводника с токами I1 и I2 пересекают плоскость XOY в точках
с координатами (x1,y1) и (x2,y2). Индукция магнитного поля в точке A(x,y)
может быть найдена по формулам:
Используемая программа ПР-1 случайным образом выбирает точку A0,
определяет проекции вектора индукции и в его направлении строит отрезок
единичной длины, находя точку A1. Затем все повторяется снова. Выполнив
10000 шагов, программа снова случайно выбирает точку A0 и начинает строить
вторую силовую линию и т.д.
82
Uses crt, graph;
Var DrV,MV,i,x1,y1,x2,y2,x3,y3,k : integer;
cosa1,sina1,cosa2,sina2,cosa3,sina3,I1,I2,I3,
B,B1,B2,B3,Bx,By,r1,r2,r3,x,y,pi: real;
BEGIN
DrV:=Detect; InitGraph(DrV,MV,'c:\bp\bgi');
pi:=arctan(1)*4; x1:=150; y1:=100;
x2:=400; y2:=100; x3:=300; y3:=300;
circle(x1,y1,2); circle(x2,y2,2); circle(x3,y3,2);
x:=300; I1:=1; I2:=-2; I3:=2;
Randomize;
For i:=1 to 80 do
begin
k:=0; x:=round(random(64))*10;
y:=round(random(48))*10;
Repeat
k:=k+1;
r1:=sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1));
r2:=sqrt((x-x2)*(x-x2)+(y-y2)*(y-y2));
r3:=sqrt((x-x3)*(x-x3)+(y-y3)*(y-y3));
B1:=I1/r1; cosa1:=(x-x1)/r1; sina1:=(y-y1)/r1;
B2:=I2/r2; cosa2:=(x-x2)/r2; sina2:=(y-y2)/r2;
B3:=I3/r3; cosa3:=(x-x3)/r3; sina3:=(y-y3)/r3;
Bx:=B1*sina1+B2*sina2+B3*sina3;
By:=B1*cosa1+B2*cosa2+B3*cosa3;
B:=sqrt(Bx*Bx+By*By);
x:=x+0.1*Bx/B; y:=y-0.1*By/B;
putpixel(round(x),round(y),15);
until (k>10000)or KeyPressed;
end;
Repeat until KeyPressed; CloseGraph;
END.
83
Рис. 6.4.2. Магнитное поле трех проводников с током.
Задача 6.5.
Создайте компьютерную модель ферромагнетика Изинга. Промоделируйте
процесс образования областей спонтанной намагниченности (доменов).
Рассмотрим двумерную модель магнетика. Представим себе сетку, в каждом из
узлов которой находится атом, спин (собственный магнитный момент)
которого может быть направлен от нас, к нам или лежать в плоскости рисунка.
Энергия взаимодействия соседних атомов друг с другом -Jsi,jsi+1,j, атомы,
расположенные далеко друг от друга, не взаимодействуют. Внешнее магнитное
поле способствует повороту спина атома и изменяет энергию системы на H или
-H. Энергия всей системы равна:
Процесс моделирования состоит в следующем: 1) задается начальная
ориентация всех спинов случайным образом; 2) определяется энергия системы;
84
3) случайно выбирается один атом и его спин изменяется на противоположный,
определяется энергия системы в новой конфигурации; 4) если в результате
переориентации спина энергия уменьшилась, то такое изменение
конфигурации принимается, в противном случае -- отклоняется; 5) результат
выводится на экран; 6) возврат к операции 2. Для решения этой задачи
используется программа ПР - 6.5, при этом моделируется ситуация, в которой в
левом верхнем углу индукция магнитного поля направлена от нас, а в правом
нижнем углу -- к нам. Используется не квадратная, а шестиугольная сетка,
результат вычислений -- на рис. 6.5.
{$N+}
Uses crt, graph;
{ ПР - 6.5 }
Const N=50; M=50; J_vzaim=1;
Var i,j,k,l,u,d,Gd,Gm : integer;
p,H,E,EE,dE : real;
s : array [0..N+1,0..M+1] of single;
Energiya : string;
Label metka;
Procedure Energy;
Var i,j : integer;
begin E:=0; dE:=0;
For i:=1 to N do For j:=1 to M do begin
If j mod 2=0 then
E:=E-J_vzaim*(s[i,j]*s[i+1,j]+s[i,j]*s[i1,j]+s[i,j]*s[i,j+1]+
s[i,j]*s[i,j-1]+s[i,j]*s[i-1,j+1]+s[i,j]*s[i-1,j1]);
If j mod 2<>0 then
E:=E-J_vzaim*(s[i,j]*s[i+1,j]+s[i,j]*s[i1,j]+s[i,j]*s[i,j+1]+
s[i,j]*s[i,j-1]+s[i,j]*s[i+1,j+1]+s[i,j]*s[i+1,j1]);
end;
For i:=1 to N do For j:=1 to M do begin
h:=0; If (i>0.5*N)and(j>0.5*M) then H:=-2.5;
If (i<0.4*N)and(j<0.4*M) then H:=1.5;
dE:=dE-H*s[i,j]; end; E:=E+dE;
end;
Procedure Draw;
Var i,j : integer;
begin cleardevice; setbkcolor(white);
For i:=1 to N do
For j:=1 to M do
begin
If j mod 2=0 then d:=0 else d:=3;
If s[i,j]=1 then setcolor(12);
If s[i,j]=-1 then setcolor(9);
If s[i,j]=0 then setcolor(15);
85
circle(20+6*i+d,20+6*j,1);
circle(20+6*i+d,20+6*j,2);
circle(20+6*i+d,20+6*j,3);
end;
Str(E,Energiya); OuttextXY(10,400,Energiya);
end;
BEGIN
Gd:= Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
If GraphResult <> grOk then Halt(1);
Randomize;
For i:=1 to N do For j:=1 to M do
begin
p:=Random(100)/100; s[i,j]:=0;
If p<0.33 then s[i,j]:=-1;
If p>0.66 then s[i,j]:=1;
end;
Draw;
Repeat
For k:=1 to round(N*M/5) do
begin
Energy; EE:=E;
i:=round(random(N)); j:=round(random(M));
If s[i,j]=1 then
begin u:=1; s[i,j]:=0; goto metka; end;
If s[i,j]=-1 then
begin u:=-1; s[i,j]:=0; goto metka; end;
If (s[i,j]=0)and(random(100)>50) then
s[i,j]:=-1 else s[i,j]:=1;
u:=0; metka:
Energy;
If (E>EE) then s[i,j]:=u;
end;
Energy; Draw;
until KeyPressed;
Repeat until KeyPressed; CloseGraph;
END.
86
Рис. 6.5. Модель ферромагнетика Изинга.
7. МОДЕЛИРОВАНИЕ ТЕПЛОПРОВОДНОСТИ
Задача 7.1.
Имеется пластина с прямоугольным отверстием. Правая сторона пластины
теплоизолирована, остальные поддерживаются при постоянной температуре.
В противоположных углах пластины расположены источник тепла и источник
холода. Необходимо рассчитать распределение температуры в
последовательные моменты времени.
Уравнение теплопроводности для двумерной среды в конечных разностях
имеет вид:
Для расчета распределения температуры по поверхности пластины
87
используется программа ПР - 7.1. Она содержит цикл по времени с
вложенными в него двумя циклами по i и по j, в которых перебираются все
элементы пластины и вычисляются их температуры в последующие моменты
времени. Результат решения задачи представлен на рис. 7.1, -- на нем разными
цветами изображены области с различными температурами. Изотермы
(границы разноцветных областей) перепендикулярны теплоизолированным
краям пластины и параллельны краям, температура которых поддерживается
постоянной.
Uses crt, graph;
{ ПР - 7.1. }
Const n=75; m=70; h=1; dt=0.1;
Var kk, i, j, DV, MV : integer;
tt, t : array[1..N, 1..M] of real;
q, a : real; uslovie : boolean;
Procedure Istoch;
begin
If ((i>20)and(i<35))and((j>20)and(j<30))
then q:=20 else q:=0;
If ((i>45)and(i<65))and((j>50)and(j<60))
then q:=-10; end;
Procedure Nach_uslov;
begin For i:=1 to N do For j:=1 to M do t[i,j]:=1;
end;
Procedure Raschet;
begin Istoch;
If (abs(i-40)<10)and(abs(j-40)<10)
then a:=0 else
a:=1;
tt[i,j]:=t[i,j]+a*(t[i,j+1]-2*t[i,j]+t[i,j1])*dt/(h*h)+
a*(t[i+1,j]-2*t[i,j]+t[i-1,j])*dt/(h*h)+q; end;
BEGIN
DV:=Detect; InitGraph(DV,MV,'c:\bp\bgi');
Nach_uslov;
Repeat
kk:=kk+1;
For i:=2 to N-1 do For j:=2 to M-1 do
begin t[N,j]:=t[N-1,j]; Raschet; end;
For i:=2 to N-1 do For j:=2 to M-1 do
t[i,j]:=tt[i,j];
If kk/25=round(kk/25) then For i:=2 to N-1 do For
j:=2 to M-1 do
begin
setcolor(round(t[i,j]/300+1));
rectangle(i*5+50,j*5,i*5+54,j*5+4);
rectangle(i*5+51,j*5+1,i*5+53,j*5+3);
end;
until KeyPressed; CloseGraph;
88
END.
Рис. 7.1. Распределение температуры: двумерная среда.
Задача 7.2.
Пластина состоит из трех полосок с различными коэффициентами
теплопроводности. Нижняя сторона пластины теплоизолирована, остальные
поддерживаются при постоянной температуре. В разных местах пластины
расположены протяженный источник тепла и источник холода. Необходимо
рассчитать распределение температуры в последовательные моменты
времени.
Заменяя частные производные их конечно-разностными аппроксимациями,
запишем уравнение теплопроводности для неоднородной двумерной среды в
конечных разностях:
89
Для решения задачи используется программа ПР - 7.2. В ней последовательно
перебираются узлы двумерной сетки по строкам и по столбцам. Когда
переменная naprav равна 0, то элементы перебираются по столбцам сверху вниз
и снизу вверх. Когда переменная naprav равна 1, то элементы перебираются по
строкам слева направо и справа налево. Нижникй край пластины
теплоизолирован, это задается циклом:
For i:=1 to N do t[i,M]:=t[i,M-1];
Все остальные края пластины поддерживаются при постоянной температуре.
Используется программа ПР - 7.2, результат ее работы представлен на рис. 7.2.
Uses crt, graph;
{ ПР 7.2. }
Const n=72; m=72; h=1; dt=0.05;
Var naprav,ii,jj,kk,i,j,DV, MV, EC : integer;
k,t : array[1..N, 1..M] of real;
q,a,b,bb : real; uslovie : boolean;
Procedure Raschet;
begin q:=0;
If (i>20)and(i<50)and(j>50)and(j<60) then q:=20;
If (i>50)and(i<60)and(j>20)and(j<30) then q:=-30;
If naprav=1 then
t[i,j]:=t[i,j]+(k[i,j+1]-k[i,j-1])*(t[i,j+1]t[i,j-1])*dt/(4*h*h)+
k[i,j]*(t[i,j-1]-2*t[i,j]+t[i,j+1])*dt/(h*h)+q*dt
90
else
t[i,j]:=t[i,j]+(k[i+1,j]-k[i-1,j])*(t[i+1,j]-t[i1,j])*dt/(4*h*h)+
k[i,j]*(t[i-1,j]-2*t[i,j]+t[i+1,j])*dt/(h*h)+q*dt;
end;
BEGIN DV:=Detect; InitGraph(DV,MV,'c:\bp\bgi');
For i:=1 to N do For j:=1 to M do
begin k[i,j]:=1;
If (i>55) then k[i,j]:=2;
If (i<30) then k[i,j]:=0.3;
end;
Repeat
kk:=kk+1;
naprav:=0; For i:=2 to N-1 do For j:=2 to M-1 do
Raschet;
For i:=2 to N-1 do For j:=M-1 downto 2 do
Raschet;
naprav:=1; For j:=2 to M-1 do For i:=2 to N-1 do
Raschet;
For j:=2 to M-1 do For i:=N-1 downto 2 do
Raschet;
For i:=1 to N do t[i,M]:=t[i,M-1];
If kk/10=round(kk/10) then For i:=2 to N-1 do For
j:=2 to M-1 do
begin
setcolor(round(t[i,j]/100)+1);
rectangle(i*5+50,j*5,i*5+54,j*5+4);
rectangle(i*5+51,j*5+1,i*5+53,j*5+3);
end;
Line(55*5+52,0,55*5+52,480);
Line(30*5+52,0,30*5+52,480);
until KeyPressed;
CloseGraph;
END.
91
Рис. 7.2. Теплопроводность в неоднородной среде.
Задача 7.3.
Имеется неоднородный стержень, известна начальная температура различных
его точек, координаты и мощность источника тепла (холода). Один конец
теплоизолирован, другой поддерживается при постоянной температуре.
Необходимо рассчитать распределение температуры вдоль стержня.
Для решения задачи может быть использован алгоритм АЛ - 1.
Алгоритм АЛ - 1
НАЧАЛО ПРОГРАММЫ
ДЛЯ i:=1 ДО N ДЕЛАТЬ {ЕСЛИ (i>18)И(i<22) ТО T[i]:=5 ИНАЧЕ T[i]:=0.1; -}
ДЛЯ j:=1 ДО N ДЕЛАТЬ {ЕСЛИ j>20 ТО k[j]:=1.8 ИНАЧЕ k[j]:=1; -}
ПОВТОРЯТЬ ДО НАЖАТИЯ НА КЛАВИШУ
{==
kk:=kk+1;
ДЛЯ i:=2 ДО N-1 ДЕЛАТЬ {
ЕСЛИ (i>80) И (i<83) ТО q:=0.5 ИНАЧЕ q:=0;
TT[i]:=T[i]+k[i]*(T[i+1]-2*T[i]+T[i-1])*dt/(h*h)+
(k[i+1]-k[i-1])*(T[i+1]-T[i-1])*dt/(4*h*h)+q*dt; }
ДЛЯ i:=2 ДО N-1 ДЕЛАТЬ { T[i]:=TT[i]; }
T[1]:=0.1; T[N]:=T[N-1];
ЕСЛИ kk/1000=round(kk/1000) ТО {
ДЛЯ i:=2 ДО N ДЕЛАТЬ {ПОСТАВИТЬ ТОЧКУ (i, T[i]); -}
==}
КОНЕЦ ПРОГРАММЫ
В нем используются два массива T[i] и TT[i], в которых сохраняются значения
температуры элементов стержня в моменты t и t+1 соответственно. Расчет
92
температуры осуществляется по выведенной выше формуле в цикле. Будем
считать, что длина стержня l, его коэффициент температуропроводности k при
x>0,2l равен 1,8, а при x<0,2l равен 1. Температура точек с координатами от
0,18l до 0,22l равна T1; все остальные точки имеют температуру T2<t1. Точки,
координата $x$ которых лежит в интервале от 0,81l до 0,82l, нагреваются источником тепла известной мощностью q. Левый
конец поддерживается при постоянной температуре, а правый --- теплоизолирован. Результат решения задачи представлен
на рис. 7.3.</t
uses crt, graph;
{ ПР - 7.3 }
const n=100; m=1; h=1; dt=0.001;
var ii,jj,kk,i,j,DV,MV,EC: integer; q,q1 :real;
tt,t: array[1..N] of real;
k: array[1..N] of real;
BEGIN
DV:=Detect; InitGraph(DV,MV,'c:\bp\bgi');
EC:=GraphResult; If EC <> grOK then Halt(1);
For i:=1 to N do
If (i>18)and(i<22) then t[i]:=5 else t[i]:=0.1;
For j:=1 to N do
If j>20 then k[j]:=1.8 else k[j]:=1;
Repeat
For i:=2 to N-1 do
begin
If (i>80)and(i<83) then q:=0.5 else q:=0;
tt[i]:=t[i]+k[i]*(t[i+1]-2*t[i]+t[i1])*dt/(h*h)+
(k[i+1]-k[i-1])*(t[i+1]-t[i1])*dt/(4*h*h)+q*dt;
end;
For i:=2 to N-1 do t[i]:=tt[i];
t[1]:=0.1; t[N]:=t[N-1];
If kk/3000=round(kk/3000) then
For i:=2 to N do
begin
line(i*5+20,420-round(80*t[i]),
(i-1)*5+20,420-round(80*t[i-1]));
end;
delay(1); kk:=kk+1;
until KeyPressed;
CloseGraph;
END.
8. ВОЛНОВЫЕ И АВТОВОЛНОВЫЕ
ПРОЦЕССЫ
93
Задача 8.1.
Промоделируйте процесс распространения импульса в одномерной среде
(струне). Изучите прохождение импульса через границу раздела двух сред с
разными скоростями распространения возмущения.
Запишем одномерное волновое уравнение в конечных разностях:
Для получения движущегося профиля волны необходимо организовать цикл по
i, в котором перебираются все элементы среды, вычисляются их смещения из
положения равновесия. После этого стирается предыдущая моментальная
фотография волны и строится новая. Все это должно находиться внутри цикла
по времени (программа ПР - 8.1). Результат моделирования прохождения
волны через границу раздела двух сред приведен на рис. 8.1.
Uses crt, graph;
{ ПР - 8.1 }
Const n=200; h=1; dt=0.02;
Var i, j, DV, MV, EC : integer;
eta,xi,xi1,xi2 : array[1..N] of real; t, b, vv :
real;
BEGIN DV:=Detect; InitGraph(DV,MV,'c:\bp\bgi');
Repeat t:=t+dt;
If t<6.28 then xi1[1]:=2*sin(t) else xi1[1]:=0;
For i:=2 to N-1 do
begin
If i<N/2 then vv:=8 else vv:=3;
xi2[i]:=2*xi1[i]-xi[i]+vv*(xi1[i-1]2*xi1[i]+xi1[i+1])/h/h*dt*dt;
end;
For i:=2 to N-1 do
begin xi[i]:=xi1[i]; xi1[i]:=xi2[i]; end;
For i:=1 to N do
begin
setcolor(black);
circle(i*3-3,240-round(xi[i-1]*50),1);
setcolor(white);
circle(i*3-3,240-round(xi1[i-1]*50),1);
94
end;
until KeyPressed; CloseGraph;
END.
Рис. 8.1. Одномерная волна: отражение и прохождение через границу
раздела двух сред.
Задача 8.2.
Создайте компьютерную модель распространения волны в двумерной среде
(пластине). С помощью нее изучите прохождение волны от точечного
источника через границу раздела двух сред.
Запишем волновое уравнение в конечных разностях:
Для решения задачи используется программа ПР - 8.2.1. Для того, чтобы
увеличить число узлов сетки, на которую разбита прямоугольная пластина
используются указатели. В двумерном массиве xi[i,j] хранятся значения
смещения различных элементов среды (xi(i,j)^) и их скорости (xi(i+N,j)^) в
формате single (4 байта). Чтобы исключить влияние волн, отраженных от края
пластины, искусственно создается эффект затухания. Коэффициент затухания
волн вблизи краев пластины считается равным r=0,2. Директива компилятора
95
{$N+} необходима, чтобы включить математический сопроцессор. Результат
моделирования прохождения волны через границу раздела двух сред приведен
на рис. 8.2.
{$N+}
uses crt, graph;
{ ПР - 8.2.1 }
const N=200; M=200; h=1; dt=0.2; Size=4;
type RealPoint= ^single;
var i,j,DV,MV : integer; vv,t,r : single;
a: array[1..2*N] of pointer;
Function xi(i,j: word): RealPoint;
begin
xi:=Ptr(Seg(a[i]^),ofs(a[i]^)+(j-i)*Size);
end;
Procedure Formula;
begin vv:=4;
{If i<50 then vv:=2 else vv:=4; }
If (i>10)and(i<190)and(j>10)and(j<190) then r:=0
else r:=0.2;
xi(i+N,j)^:=xi(i+N,j)^+vv*(xi(i,j+1)^2*xi(i,j)^+xi(i,j-1)^+
xi(i+1,j)^-2*xi(i,j)^+xi(i-1,j)^)/h*dtr*xi(i+N,j)^*dt;
end;
Procedure Raschet;
begin
For i:=2 to N-1 do For j:=2 to M-1 do Formula;
For i:=2 to N-1 do For j:=2 to M-1 do
xi(i,j)^:=xi(i,j)^+xi(i+N,j)^*dt;
For i:=N-1 downto 2 do For j:=M-1 downto 2 do
Formula;
For j:=2 to M-1 do For i:=2 to N-1 do
xi(i,j)^:=xi(i,j)^+xi(i+N,j)^*dt;
end;
Procedure Draw;
begin
For i:=2 to N-1 do For j:=2 to M-1 do
begin
setcolor(round(xi(i,j)^/5));
rectangle(10+i*2,450-j*2,13+i*2,453-j*2);
rectangle(11+i*2,451-j*2,12+i*2,452-j*2);
end;
end;
BEGIN
DV:=Detect; InitGraph(DV,MV,'c:\bp\bgi');
setbkcolor(15); setcolor(8);
rectangle(11,451,12+200*2,450-200*2);
96
For i:=1 to 2*N+1 do
begin
GetMem(a[i], M*Size);
For j:=1 to M do xi(i,j)^:=0;
end;
Repeat
t:=t+dt;
xi(60,60)^:=100*sin(t*1);
xi(120,120)^:=100*sin(t*1);
Raschet; Draw;
until KeyPressed;
Release(HeapOrg); CloseGraph;
END.
Рис. 8.2. Двумерная волна: прохождение через границу раздела двух
сред.
В представленной ниже программе ПР - 8.2.2 использован другой прием: часть
данных (скорости элементов среды eta) записывается в файл a.dat. Это
позволяет увеличить число элементов массива xi[i,j].
{$N+}
{ ПР - 8.2.2 }
uses crt, graph;
const N=120; M=120; h=1; dt=0.2;
var k,i, j, DV, MV : integer;
vv,eta,a,t : single;
xi: array[1..N,1..M] of single;
var F: file of single;
Procedure Formula;
begin
97
eta:=eta+vv*(xi[i,j+1]-2*xi[i,j]+xi[i,j-1]+
xi[i+1,j]-2*xi[i,j]+xi[i-1,j])/h/h*dt;
end;
Procedure Raschet;
var aa: real; k: integer;
begin
Assign(F,'a.dat'); Reset(F); k:=0;
For i:=2 to N-1 do For j:=2 to M-1 do
begin
inc(k); Seek(F,K); Read(F,eta);
Formula; Seek(F,K); Write(F,eta);
end; k:=0;
For i:=2 to N-1 do For j:=2 to M-1 do
begin
inc(k); Seek(F,K); Read(F,eta);
xi[i,j]:=xi[i,j]+eta*dt;
end; k:=0;
For i:=2 downto N-1 do For j:=2 downto M-1 do
begin
inc(k); Seek(F,K); Read(F,eta);
Formula; Seek(F,K); Write(F,eta);
end; k:=0;
For i:=2 downto N-1 do For j:=2 downto M-1 do
begin
inc(k); Seek(F,K); Read(F,eta);
xi[i,j]:=xi[i,j]+eta*dt;
end; Close(F);
end;
Procedure Draw;
begin
for i:=2 to N-1 do for j:=2 to M-1 do
begin
setcolor(round(xi[i,j]/5));
rectangle(10+i*3,450-j*3,13+i*3,453-j*3);
rectangle(11+i*3,451-j*3,12+i*3,452-j*3);
end;
end;
Procedure FileCreate;
begin
Assign(F,'a.dat'); Rewrite(F);
For i:=1 to N do For j:=1 to M do Write(F,a);
end;
BEGIN vv:=2;
DV:=Detect; InitGraph(DV,MV,'c:\bp\bgi');
setbkcolor(15); setcolor(8);
rectangle(11,451,12+120*3,452-120*3); FileCreate;
Repeat
98
t:=t+dt;
xi[20,45]:=50*sin(t*2);
xi[60,65]:=50*sin(t*2);
Raschet; Draw;
until KeyPressed; CloseGraph;
END.
Задача 8.3.
Два источника колеблются с равными частотами и постоянным сдвигом фаз,
излучаемые волны создают интерференционную картину. Рассчитайте
смещение точек среды, лежащих на одной плоскости с источниками в
заданный момент времени.
Пусть источники имеют координаты (x1, y1), (x2, y2). Обозначим расстояния,
проходимые волнами от источников до произвольной точки с координатами (x,
y) через l1, l2. Результирующее смещение этой точки в момент T можно
рассчитать по формулам:
Задача решается с помощью программы ПР - 8.3. В ней перебираются все точки
экрана и вычисляются смещения; в зависимости от их величины ставится точка
соответствующего цвета.
uses crt, graph;
{ ПР 8.3 }
const m=500; h=1; dt=0.001;
var i,j,jj,k,DV, MV, EC : integer;
x1,x2,s,pi,lambda,xx,x,y : real;
a1,a2,d,l1,l2,II,In1,In2,razn,fi1,fi2 : real;
BEGIN
DV:=Detect; InitGraph(DV,MV,'c:\bp\bgi');
EC:=GraphResult; if EC <> grOK then Halt(1);
pi:=3.1415; lambda:=6; d:=15; x1:=32-d; x2:=32+d;
For i:=1 to 640 do For j:=0 to 480 do
begin
x:=0.1*i; y:=-10+0.1*j;
l1:=sqrt((x-x1)*(x-x1)+y*y); l2:=sqrt((x-x2)*(xx2)+y*y);
If l1<>0 then A1:=1/l1; if l2<>0 then A2:=2/l2;
s:=A1*sin(2*pi*l1/lambda)+A2*sin(2*pi*l2/lambda);
putpixel(i,j,round(s*50)+1);
end;
99
ReadKey; CloseGraph;
END.
Рис. 8.3. Интерференционная картина.
Задача 8.4.
Численными методами исследуйте двухкомпанентную модель автоволнового
процесса. Промоделируйте распространение автоволны в одномерной среде,
аннигиляцию автоволн.
Двухкомпанентная модель исходит из того, что автоволновой процесс
описывается двумя величинами: концентрацией активатора и концентрацией
ингибитора. Активатор вызывает протекание химической реакции, а ингибитор
препятствует этому. В случае распространения огня по полю, на котором
быстро растет трава, активатором является температура T: когда она достигает
критической температуры возгорания tkr трава загорается. Концентрация
ингибитора u тем больше, чем больше дыма и меньше травы в данной точке
плоскости. Когда концентрация ингибитора достигает порогового значения ukr
(вся трава выгорает), химическая реакция прекращается.
Изменение концентраций активатора и ингибитора описывается уравнением
теплопроводности (диффузии). Будем использовать следующую
математическую модель:
100
Когда трава горит (t[i]>tkr и u[i]>ukr) выделяется энергия (P=2), а количество
травы уменьшается (Q=-0,07). Если трава сгорела, но температура элемента
активной среды еще высока (t[i]>0), температура должна быстро уменьшаться
за счет охлаждения (P=-0,1). Когда элемент среды охладился (t[i]<0.2), а трава
не выросла (u[i]>u0), она растет, что описывается слагаемым r*u[i]*(u0-u[i]),
где r=0,003. При горении температура травы не может превышать 1,2 tkr.
Для численного решения рассмотренной выше системы двух
дифференциальных уравнений необходимо заменить производные их конечноразностными аппроксимациями и выразить t[i] и u[i] в дискретный момент
времени t+1. Используется программа ПР - 8.4. На рис. 8.4.1 и 2 представлены
результаты моделирования распространения автоволны в одномерной среде и
аннигиляции двух автоволн.
{$N+}
{ ПР
- 8.4 }
uses crt, graph;
const n=320; M=40; t0=10; tkr=5; u0=3; ukr=1; h=1;
dt=0.01;
var time,i,j,DV,MV,EC,k : integer; a,b,r,P,Q :
real;
t,u: array[1..N] of single;
gor: array[1..N] of integer;
Procedure Raschet; {---- Вычисление температуры ---}
begin
P:=0; Q:=0;
If (t[i]>tkr)and(u[i]>ukr) then gor[i]:=1 else
gor[i]:=0;
If gor[i]=1 then begin P:=2; Q:=-0.07; end; {трава
сгорает}
If (gor[i]=0)and(t[i]>0) then begin P:=-0.1; end;
{охлаждается}
If (gor[i]=0)and(u[i]<u0)and(t[i]1.2*tkr) then
t[i]:=1.2*tkr;
t[i]:=t[i]+a*(t[i+1]-2*t[i]+t[i-1])*dt/(h*h)+P*dt;
{u[i]:=u[i]+Q*dt+r*u[i]*(u0-u[i])/5;}
u[i]:=u[i]+b*(u[i+1]-2*u[i]+u[i-1])*dt/(h*h)+
Q*dt+r*u[i]*(u0-u[i]);
101
end;
BEGIN
DV:=Detect; InitGraph(DV,MV,'c:\bp\bgi');
a:=6; b:=3; setbkcolor(15);
For i:=1 to N do
begin u[i]:=u0;
If
(i>1)and(i<20){or(i>300)and(i100000)or(KeyPressed);
Repeat until KeyPressed; CloseGraph;
END.
</u0)and(t[i]
Рис. 8.4.1. Распространение одномерной автоволны.
Рис. 8.4.2. Аннигиляция одномерных автоволн.
Задача 8.5.
Методом компьютерного моделирования исследуйте процесс
распространения автоволны в двумерной активной среде, огибание
автоволной препятствия, образование спиральной автоволны.
Рассмотрим автоволновой процесс в двумерной активной среде на примере
распространения фронта огня по полю, на котором быстро растет трава. Исходя
из двухкомпанентной модели запишем дифференциальные уравнения для
активатора (температуры) T и количества травы u:
102
Разобъем прямоугольную область на элементы, каждый из которых
характеризуется величинами T[i,j] и u[i,j]. С целью увеличения числа элементов
подключим математический сопроцессор, переменную T[i,j] объявим как single,
а u[i,j] как word. Используется программа ПР - 8.5, результаты моделирования
представлены на рис. 8.5.1 и 2. Для того, чтобы получить сферическую волну,
элементы внутри круга небольшого радуса переводят в возбужденное
состояние, то есть "поджигают", задавая их начальную темепературу
достаточно высокой. Из рис. 8.5.1 видно, как образовавшаяся автоволна
огибает препятствие (группу элементов черного цвета с низкой
теплопроводностью). Для получения спиральной однорукавной автоволны
задают фронт волны, оборванный в центре экрана (рис. 8.5.2).
{$N+}
{ ПР 8.5 }
uses crt, graph;
const n=110; M=95; t0=10; tkr=5;
u0=65000; ukr=32000; h=1; dt=0.05;
var time,i,j,k,DV,MV,EC: integer; a,P,Q,uu: single;
t: array[1..N,1..M] of single;
u: array[1..N,1..M] of word;
gor: boolean;
Procedure Raschet; {---- Вычисление температуры ---}
begin P:=0; Q:=0;
If (t[i,j]>tkr)and(u[i,j]>ukr) then gor:=true else
gor:=false;
If gor=true then begin P:=1.9; Q:=-1600; end;
{трава сгорает}
If (gor=false)and(t[i,j]>0) then begin P:=-0.25;
end; {быстро охлаждается}
If (gor=false)and(u[i,j]<u0)and(t[i,j]2*tkr then
t[i,j]:=2*tkr;
If uu>=u0 then u[i,j]:=u0;
If (uu>1)and(uu40)and(j<70) then a:=0.1 else a:=0.8;
end;
BEGIN
a:=0.8;
DV:=Detect; InitGraph(DV,MV,'c:\bp\bgi');
103
setbkcolor(15);
For i:=1 to N do For j:=1 to M do
begin
u[i,j]:=u0; t[i,j]:=0;
{If sqr(i-45)+sqr(j-40)<100
then t[i,j]:=2*t0; {одиночная
волна}
If (i>45)and(i<55)and(j<40)
then t[i,j]:=2*t0; {однорукавная
волна}
If (i>40)and(i<46)and(j<40) then
begin
u[i,j]:=round(0.3*ukr); t[i,j]:=0.9*tkr;
end;
end;
Repeat
inc(time);
For i:=1 to N do For j:=1 to M do
begin
u[1,j]:=u[2,j]; u[N,j]:=u[N-1,j];
u[i,1]:=u[i,2]; u[i,M]:=u[i,M-1];
t[1,j]:=t[2,j]; t[N,j]:=t[N-1,j];
t[i,1]:=t[i,2]; t[i,M]:=t[i,M-1];
end;
For i:=2 to N-1 do For j:=2 to M-1 do Raschet;
For i:=N-1 downto 2 do For j:=M-1 downto 2 do
Raschet;
If time mod 100=1 then
begin cleardevice;
For i:=2 to N do For j:=2 to M-1 do
begin setcolor(9);
If u[i,j]>ukr then setcolor(2);
If (t[i,j]>tkr)and(u[i,j]>ukr) then
setcolor(12);
If u[i,j]90)and(i<94)and(j>40)and(j<70)
then setcolor(8);
rectangle(i*5,j*5,i*5+4,j*5+4);
rectangle(i*5+1,j*5+1,i*5+3,j*5+3);
end;
end;
until KeyPressed; CloseGraph;
END.
</u0)and(t[i,j]
104
Рис. 8.5.1. Огибание сферической автоволнрй препятствия.
Рис. 8.5.2. Однорукавная спиральная автоволна.
Задача 8.6.
Имеется модель одномерной упругой среды, состоящая из осцилляторов,
связанных пружинами жесткостью q. Каждый осциллятор представляет собой
материальную точку массой m, подвешенную на пружине жесткостью k.
Промоделируйте распространение волны в данной среде, убедитесь в том, что
фазовая скорость в общем случае не равна групповой, то есть имеет место
дисперсия.
Рис. 8.6.1. Модель одномерной упругой среды.
105
На каждый осциллятор рассматриваемой модели одномерной упругой среды
действуют: 1) сила упругости со стороны пружины осциллятора; 2) силы
упругости со стороны соседних осцилляторов; 3) силы вязкого стрения. Из
второго закона Ньютона следует, что ускорение θ, скорость η и смещение ξ iого осциллятора в момент времени t+1 могут быть найдены из формул:
Ниже представлена программа ПР - 8.8.1, моделирующая распространение
импульса по цепочке осцилляторов, связанных упругими связями. Она
содержит цикл по времени t, и вложенный в него цикл по i, в котором
последовательно перебираются все осцилляторы и вычисляются их ускорения,
скорости и смещения. Тут же определяется кинетическая и потенциальная
энергия колеблющихся осцилляторов. На экране строится "моментальная
фотография волны" (зависимость смещения ξ от координаты x в
фиксированный момент времени t) и зависимость энергии осцилляторов от
координаты x.
Эта компьютераная модель позволяет "пронаблюдать" распространение
импульса, его отражение от края упругой среды, от "границы раздела двух
сред". В случае когда k=0 импульс распространяется, не изменяя своей формы,
его фазовая скорость (быстрота переноса колебаний) и групповая скорость
(быстрота переноса энергии) равны (рис. 8.6.2). Если жесткость k и массу m
осциллятора подобрать так, чтобы частота волны w была бы близка к его
собственной частоте колебаний, то происходит дисперсия. Импульс
растягивается, фазовая скорость заметно отличается от групповой (рис. 8.6.3).
Ниже приведен другой вариант программы (ПР - 8.6.2) и результат ее
использования (рис. 8.6.4).
{$N+}
{ ПР 8.6.1 }
uses dos, crt, graph;
Const m=0.5; r=0.1; dt=0.0015; q=150; N=150; w=6;
k=13;
Var F,teta,Sum,S,t : single; i,x,Gd,Gm : integer;
eta, ksi, y,a,b : array [0..N] of single;
BEGIN
Gd:= Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
setbkcolor(15); setcolor(8); line(10,250,630,250);
Repeat t:=t+dt; cleardevice;
For i:=1 to N-1 do y[i]:=ksi[i];
For i:=1 to N-1 do
106
begin
b[i]:=a[i]; x:=10+4*i;
F:=q*(ksi[i-1]-ksi[i])+q*(ksi[i+1]-ksi[i]);
teta:=(F-r*eta[i]-k*ksi[i])/m;
eta[i]:=eta[i]+teta*dt;
ksi[i]:=ksi[i]+eta[i]*dt;
If w*t<2*3.142 then ksi[1]:=9*sin(w*t) else
begin ksi[1]:=0;
eta[1]:=0; end;
a[i]:=(k*sqr(ksi[i])+q*sqr(ksi[i+1]ksi[i])+m*sqr(eta[i]))/2/10;
circle(x,370-round(ksi[i]*10),2);
circle(x,370-round(ksi[i]*10),3);
line(10+4*(i-1),369-round(ksi[i-1]*10),x,369round(ksi[i]*10));
rectangle(x,250-round(a[i]),x+1,250);
rectangle(x+2,250-round(a[i]),x+3,250);
end;
Sum:=0; S:=0;
For i:=1 to N do
begin
Sum:=Sum+a[i];
S:=S+a[i]*i;
end;
circle(10+4*round(S/Sum),260,2);
circle(10+4*round(S/Sum),260,3); delay(1000);
until KeyPressed;
CloseGraph;
END.
Рис. 8.6.2. Дисперсия отсутствует. Групповая и фазовая скорости
равны.
107
Рис. 8.6.3. Групповая скорость меньше фазовой. Имеет место
дисперсия.
uses dos, crt, graph;
{ ПР 8.6.2 }
const m=0.05; r=0.015; k=12; dt=0.0005; q=100;
N=120; pi=3.1415;
var F,teta: Real; i,j,t,Gd,Gm: integer;
eta,ksi,y,e,e0: array [1..N] of real;
BEGIN
Gd:= Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
Repeat inc(t);
For i:=2 to N-1 do
begin y[i]:=ksi[i]; e0[i]:=e[i]; ksi[N]:=0;
If (5*pi*t*dt)<2*pi then
ksi[1]:=2*sin(5*pi*t*dt) else ksi[1]:=0;
F:=q*(ksi[i-1]-ksi[i])+q*(ksi[i+1]-ksi[i]);
teta:=(F-r*eta[i]-k*ksi[i])/m;
ksi[i]:=ksi[i]+eta[i]*dt+teta*dt*dt/2;
eta[i]:=eta[i]+teta*dt;
e[i]:=q*sqr(ksi[i-1]-ksi[i])/2+q*sqr(ksi[i+1]ksi[i])+k*ksi[i]*ksi[i]/2+m*eta[i]*eta[i]/2;
end;
For i:=2 to N-1 do
begin setcolor(8);
line(5*i,400,5*i,400-round(y[i]*30));
line(5*i,250,5*i,250-round(e0[i]*2));
setcolor(15);
line(5*i,400,5*i,400-round(ksi[i]*30));
line(5*i,250,5*i,250-round(e[i]*2));
end;
until KeyPressed; CloseGraph;
END.
108
Рис. 8.6.4. Перемещение фазы волны в диспергирующей среде.
9. РАСЧЕТ ТЕЧЕНИЯ ЖИДКОСТИ
Задача 9.1.
Изучите установившееся потенциальное течение идеальной жидкости по
трубе прямоугольного сечения. Внутри трубы имеются выступы и различные
препятствия. Постройте линии тока.
Функция тока, характеризующая потенциальное течение жидкости,
удовлетворяет уравнению Лапласа. Запишем его в конечных разностях:
Для решения задачи используется программа ПР - 9.1. Результаты расчета
функции тока представлены на рис. 9.1.
Uses crt, graph;
Const n=140; m=50;
Var i,ii,j,jj,k,DV,MV,EC : integer;
psi: array[1..N, 1..M] of real;
Procedure Raschet;
begin
psi[i,j]:=(psi[i+1,j]+psi[i1,j]+psi[i,j+1]+psi[i,j-1])/4;
end;
{ ПР - 9.1 }
109
Procedure Gran_usl;
begin
For i:=1 to N do
begin
psi[i,2]:=-200; psi[i,M-1]:=200; psi[i,1]:=-200;
psi[i,M]:=200;
end;
For j:=1 to M do
begin
psi[N-1,j]:=-204+8*j; psi[N,j]:=-204+8*j;
end;
For j:=1 to 25 do
begin
psi[2,j]:=-204+16*j; psi[N-1,j]:=-204+8*j;
psi[1,j]:=-204+16*j; psi[N,j]:=-204+8*j;
end;
For i:=1 to N do For j:=1 to M do
If (j>25)and((i-60)*(i-60)+(j-25)*(j-25)<200)
then psi[i,j]:=0;
For i:=1 to N do For j:=1 to M do
If (abs(j-25)<15)and(abs(i-110)<5) then psi[i,j]:=0;
For i:=1 to N do For j:=1 to M do
If (j>25)and(i<30) then psi[i,j]:=200;
end;
Procedure Draw; {---- Вывод на экран ----}
begin
setcolor(round((psi[i,j]+200)/30));
If ((j>25)and((i-60)*(i-60)+(j-25)*(j-25)<200)) or
((j>25)and(i<30))or((abs(j-25)<15)
and(abs(i-110)<5)) then
setcolor(15);
rectangle(i*4+50,j*4,i*4+53,j*4+3);
rectangle(i*4+51,j*4+1,i*4+52,j*4+2);
end;
BEGIN
DV:=Detect; InitGraph(DV,MV,'c:\bp\bgi');
Repeat
inc(k);
Gran_usl;
For i:=2 to N-1 do For j:=2 to M-1 do Raschet;
Gran_usl;
For j:=M-1 downto 2 do For i:=N-1 downto 2 do
Raschet;
If k/10=round(k/10) then
begin
cleardevice;
For i:=2 to N-1 do For j:=2 to M-1 do Draw;
110
end;
until KeyPressed; CloseGraph;
END.
Задача 9.2.
Исследуйте установившееся безвихревое течение вязкой жидкости в длинной
трубе (канале) постоянного сечения, внутри которой движется бесконечно
длинное тело.
Это течение инвариантно по отношению к переносам в направлении движения.
Для его расчета следует определить скорости в сечении, перпендикулярном
направлению течения (оси z), то есть решить уравнение:
Необходимо правильно задать граничные условия. Слои вязкой жидкости,
прилегающие к поверхности твердого тела, имеют одинаковую с ним скорость.
Если жидкость имеет свободную поверхность, то скорость частиц этой
111
поверхности равна скорости частиц, расположенных слоем ниже. Результаты
расчета обтекания длинного корпуса корабля и катамарана (рис. 9.2).
Uses crt, graph;
{ ПР - 9.2 }
Const n= 90; m=58; h=1; dt=0.02;
Var ii,jj,kk,i,j,DV, MV, EC : integer;
vv, v: array[1..N, 1..M] of real;
Procedure Gr_usl;
begin
For i:=1 to N do For j:=1 to M do v[i,j]:=vv[i,j];
For i:=2 to N-1 do For j:=2 to M-1 do
begin
If (j<5)and(abs(5-i)<5) then v[i,j]:=0;
If (j<40)and(abs(i-50)<1+20*sqr(cos(j/25)))
then
v[i,j]:=300;
end;
For i:=1 to N do v[i,M]:=0;
For j:=1 to M do begin v[1,j]:=0; v[N,j]:=0; end;
end;
Procedure Raschet;
begin
vv[i,j]:=v[i,j]+(v[i,j+1]-2*v[i,j]+v[i,j1])*dt/(h*h)
+(v[i+1,j]-2*v[i,j]+v[i1,j])*dt/(h*h);
end;
procedure Draw;
begin
setcolor(round(v[i,j]/30)+1);
If v[i,j]<1 then setcolor(9);
rectangle(i*3+9,j*3,i*3+2,j*3+2);
rectangle(i*3+10,j*3,i*3+1,j*3+1);
end;
BEGIN
DV:=Detect; InitGraph(DV,MV,'c:\bp\bgi');
Repeat
Gr_usl; For i:=1 to N-1 do For j:=2 to M-1 do
Raschet;
Gr_usl; For j:=M-1 downto 2 do For i:=N-1 downto 2
do Raschet;
For i:=1 to N do vv[i,1]:=vv[i,2]; kk:=kk+1;
If kk/30=round(kk/30) then For i:=2 to N-1 do For
j:=2 to M-1 do Draw;
until KeyPressed;
CloseGraph;
END.
112
Рис. 9.2. Течение вязкой жидкости.
10. РЕШЕНИЕ ВАРИАЦИОННЫХ ЗАДАЧ НА КОМПЬЮТЕРЕ
Задача 10.1.
Имеются два кольца, центры которых лежат на одной оси, перпендикулярной
содержащим их плоскостям. Кольца погружают в мыльный раствор и
вынимают. Рассчитайте форму мыльной пленки, если радиусы колец и
расстояние между их центрами известны.
Рис. 10.1.1. К вычислению профиля мыльной пленки.
113
Мыльная пленка принимает такую форму, при которой ее потенциальная
энергия, пропорциональная площади пленки, минимальна. Таким образом,
задача состоит в нахождении формы мыльной пленки, соответствующего
минимуму потенциальной энергии. Очевидно, что мыльная пленка примет
осесимметричную форму, однозначно определяемую функцией y=y(x),
задаваемой с помощью массива yi=y(xi), где xi=iΔx и Δx=l/N. Площадь
поверхности фигуры вращения можно найти по формуле:
Для решения этой задачи используется программа ПР - 10.1. Сначала задаются
заведомо большие значения yi=y(xi). В процедуре Ploshad осуществляется
вычисление площади мыльной пленки. Затем перебираются все значения
yi=y(xi) и уменьшаются на малую величину 0.0001. При этом каждый раз
вычисляется новое значение площади S1. Если при этом площадь уменьшается,
то изменение yi=y(xi) принимается, а если нет --- отвергается. Все это
многократно повторяется, результаты вычислений выводятся в виде графика на
экран. Получающийся результат при различных радиусах колец и расстояниях
между ними представлен на рисунке 10.1.2. Можно убедиться в том, что когда
расстояние между кольцами превышает некоторое критическое значение,
устойчивого состояния, соответствующего минимуму потенциальной энергии,
несуществует.
{$N+}
{ ПР - 10.1 }
uses dos, crt, graph;
const N=100; R1=1; R2=0.7; pi=3.1415926;
var l,S,dx,a,S0,S1: real; i,j,k,Gd, Gm: integer;
y: array[1..N]of single;
Procedure Ploshad;
begin S:=0;
For i:=1 to N-1 do
S:=S+pi*(y[i]+y[i+1])*sqrt(sqr(y[i]-y[i+1])+dx*dx);
end;
BEGIN S:=0; dx:=1/N;
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
For i:=1 to N do y[i]:=R1; y[N]:=R2;
Repeat inc(k);
For j:=2 to N-1 do
begin
a:=y[j]; Ploshad; S0:=S;
y[j]:=a-0.0001; Ploshad; S1:=S;
If S1>S0 then y[j]:=a;
end;
If k mod 100=0 then
begin cleardevice;
114
For i:=1 to 100 do
circle(20+round(300*i*dx),400round(300*y[i]),2);
line(0,400,640,400);
end;
until KeyPressed;
CloseGraph;
END.
Рис. 10.1.2. Результаты вычислений профиля мыльной пленки.
Задача 10.2.
Имеется неоднородная нить. Какую форму она примет в однородном поле
тяжести если концы ее закрепить в фиксированных точках.
Нить примет форму, при которой ее потенциальная энергия минимальна.
Мысленно заменим нить совокупностью материальных точек с массами mi,
которые связаны друг с другом пружинками жесткостью k и длиной b.
Расстояние между соседними частицами и потенциальная энергия всей
системы определяются уравнениями:
Допустим, правый конец нити привязан математическому маятнику длиной
b1 и массой mN. Заменим нить маятника пружиной жесткостью k, тогда к
потенциальной энергии системы следует прибавить величину:
115
Используется программа ПР - 10.2. В ней последовательно перебираются
материальные точки mi, случайным образом изменяются их координаты и
каждый раз вычисляется получающееся значение потениальной энергии
системы. Если при смещении данной частицы потенциальная энергия
уменьшилась, то это новое состояние системы принимается, иначе -отвергается. Результат моделирования представлен на рис. 10.2.
{$N+}
{ ПР - 10.2
}
uses dos, crt, graph;
const N=20; b=20; b1=100; k=400; g=10; pi=3.1415;
var U,U0,U1,x1,y1,l,l1,dU: Real; i,j,t,Gd,Gm:
integer;
x,y,m: array [1..N] of single; Energiya: string;
Procedure Energy;
var i: integer;
begin U:=0;
For i:=2 to N do
begin
l:=sqrt(sqr(x[i]-x[i-1])+sqr(y[i]-y[i-1]));
If l>b then dU:=k*sqr(l-b)/2;
U:=U+dU+m[i]*g*y[i];
end;
l1:=sqrt(sqr(x[N]-400)+sqr(y[N]-60));
U:=U+k*sqr(l1-b1)/2;
end;
BEGIN Randomize;
Gd:= Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
For i:=1 to N do
begin
x[i]:=20*i; y[i]:=-2*i;
If i<N then m[i]:=2 else m[i]:=10;
end;
Repeat inc(t);
For i:=2 to N do
begin
x1:=x[i]; y1:=y[i]; Energy; U0:=U;
x[i]:=x[i]+random(100)/25-2;
y[i]:=y[i]+random(100)/25-2; Energy; U1:=U;
If U1>U0 then begin x[i]:=x1; y[i]:=y1; end;
end; Energy; Str(U,Energiya);
If t mod 500=1 then
begin
cleardevice;
116
For i:=1 to N-1 do
begin
circle(10+round(x[i]),150-round(y[i]),3);
line(10+round(x[i]),150-round(y[i]),
10+round(x[i+1]),150-round(y[i+1]));
end;
line(10+round(x[N]),150-round(y[N]),410,15060);
OuttextXY(10,450,Energiya);
end;
until KeyPressed;
CloseGraph;
END.
Рис. 10.2. Результат вычисления формы нити.
Задача 10.3.
Имеется неоднородная цепь, ее концы закреплены в некоторых точках. К
заданной точке цепи привязана невесомая нить, которая перекинута через
неподвожный блок и привязана к грузу известной массы M.
Как и при решении задачи 10.2, заменим цепь совокупностью материальных
точек, соединенных пружинами жесткостью k и длиной b. Пусть блок имеет
небольшие размеры и его координаты равны X и Y, а перекинутая через него
нить привязана к k-ой материальной точке с координатами xk и yk. Тогда при
расчете потенциальной энергии системы следует учесть потенциальную
энергию груза массы M:
117
Если к некоторой i-ой точке цепи привязан груз известной массы (без блока), то
при рассчете формы цепи необходимо увеличить массу i-ой точки на массу
груза. Во всем остальном задача решается аналогично предыдущей задаче 10.2:
случайным образом на небольшие величины изменяются координаты частиц,
вычисляется потенциальная энергия системы, определяется положение
системы, при которой потенциальная энергия минимальна (приграмма ПР 10.3). Результат решения -- на рис. 10.3.
{$N+}
{ ПР - 10.3
}
uses dos, crt, graph;
const N=80; b=5; k=200; g=10; pi=3.1415;
var U,U0,U1,x1,y1,l,dU,S,mm: real;
i,j,t,r,Gd,Gm: integer; Energiya: string;
x,y,m: array [1..N] of single;
Procedure Energy;
var i: integer;
begin U:=0;
For i:=2 to N do
begin
l:=sqrt(sqr(x[i]-x[i-1])+sqr(y[i]-y[i-1]));
If l>b then dU:=k*sqr(l-b)/2;
U:=U+dU+m[i]*g*y[i];
end;
S:=sqrt(sqr(x[40]-200)+sqr(y[40]-20));
U:=U+mm*g*S;
end;
BEGIN
Randomize;
Gd:= Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
For i:=1 to N do
begin
x[i]:=6*i; y[i]:=-i;
If i<40 then m[i]:=2 else m[i]:=4; m[20]:=30;
end; mm:=25;
Repeat inc(t);
For i:=2 to N-1 do
begin
x1:=x[i]; y1:=y[i]; Energy; U0:=U;
x[i]:=x[i]+random(100)/25-2;
y[i]:=y[i]+random(100)/25-2; Energy; U1:=U;
If U1>U0 then begin x[i]:=x1; y[i]:=y1; end;
end;
Energy; Str(U,Energiya);
If t mod 500=1 then
118
begin
cleardevice;
For i:=1 to N-1 do
begin
If i<40 then r:=1 else r:=4;
circle(10+round(x[i]),150-round(y[i]),2);
circle(10+round(x[i]),150-round(y[i]),r);
line(10+round(x[i]),150-round(y[i]),
10+round(x[i+1]),150-round(y[i+1]));
end;
line(10+round(x[40]),150-round(y[40]),200,20);
OuttextXY(10,450,Energiya);
end;
until KeyPressed; CloseGraph;
END.
Рис. 10.3. Результат вычисления формы нити.
Задача 10.4.
Рассчитайте форму длинной упругой пластины, находящейся в однородном
поле тяжести. Пластина неоднородная, один ее конец закреплен.
119
Рис. 10.4. К вычислению формы упругой пластины.
Пластину представим как систему материальных точек m[i], связанных
недеформируемыми стержнями длиной b. При изгибе пластины изменяются
угол φ[i] и координаты x[i], y[i]. Потенциальная энергия системы равна:
В используемой программе ПР - 10.4 реализуется следующий алгоритм.
Последовательно перебираются материальные точки m[i] и случайным образом
изменяются углы φ[i]. Каждый раз пересчитывается энергия системы. Если она
увеличилась, то эта конфигурация отвергается, а если уменьшилась --принимается. В результате определяется устойчивое состояние равновесия
системы, соответствующее минимуму потенциальной энергии. На рис. 10.4
представлены результаты расчетов для неоднородного стержня (жесткости
левой и правой половин различны), к концу которого прикреплен груз (масса
m[N] в 5 раз больше масс других материальных точек).
{$N+}
{ ПР 10.4 }
uses dos, crt, graph;
const N=20; b=20; g=10; pi=3.1415;
var U,U0,U1,x1,y1,fi0,l,l1,dU: Real; i,j,t,Gd,Gm:
integer;
fi,x,y,m,k: array [0..N] of single; Energiya:
string;
Procedure Energy;
var i: integer;
120
begin
U:=0;
For i:=1 to N do
begin
x[i]:=x[i-1]+b*cos(fi[i]);
y[i]:=y[i-1]-b*sin(fi[i]);
end;
For i:=1 to N do
begin
dU:=k[i]*sqr(fi[i]-fi[i-1])/2;
U:=U+dU+m[i]*g*y[i];
end;
end;
BEGIN Randomize;
Gd:= Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
For i:=0 to N do
begin fi[i]:=0;
If i<N-1 then m[i]:=0.02 else m[i]:=0.1;
If i<N/2 then k[i]:=20000 else k[i]:=1000;
end; fi[0]:=-0.5;
Repeat inc(t);
For i:=N downto 1 do
begin
fi0:=fi[i]; Energy; U0:=U;
fi[i]:=fi[i]+pi*(random(200)/100-1)/20;
Energy; U1:=U;
If U1>U0 then fi[i]:=fi0;
end;
Energy; Str(U,Energiya);
For i:=1 to N do
begin
x[i]:=x[i-1]+b*cos(fi[i]);
y[i]:=y[i-1]-b*sin(fi[i]);
end;
If t mod 50=1 then
begin cleardevice;
For i:=0 to N do
begin
circle(20+round(x[i]),150-round(y[i]),3);
line(20+round(x[i]),150-round(y[i]),
20+round(x[i-1]),150-round(y[i-1]));
end;
circle(20+round(x[N]),150-round(y[N]),5);
OuttextXY(10,450,Energiya);
end;
until KeyPressed; CloseGraph;
END.
121
Рис. 10.4. Изгиб неоднородного стержня с грузом на конце.
Задача 10.5.
Показатель преломления неоднородной среды зависит от координат: n=n(x,y).
Используя принцип Ферма, рассчитайте траекторию распространения
светового луча из фиксированной точки A в фиксированную точку B,
оптическая длина которой минимальна.
Согласно принципу Ферма, свет распространяется по пути, оптическая длина
которого минимальна (экстремальна). Рассмотрим сетку, состоящую из
вертикалей, пересекающих ось абсцисс в точках xi=iΔx, i=0,1,2,..,N. Траектория
аппроксимируется ломанной, пересекающей линии сетки в точках y1=y(x1),
y2=y(x2), y3=y(x3), ..., yN=y(xN). Оптическая длина пути такой траектории
определяется формулой:
Будем случайным образом варьировать величины yi=y(xi), каждый раз
определяя изменение оптической длины пути L. Если вариация yi вызывает
уменьшение оптической длины пути, то она принимается, а в противном
случае, --- отвергается. Используется программа ПР - 10.5, результат ее работы
--- представлен на рис. 10.5.
{$N+}
{ ПР
- 10.5 }
uses dos, crt, graph;
const N=106; M=80; R1=1; R2=0.7; pi=3.1415926;
var s,s1,l,dx,a,xx,yy,L0,L1,n_sr: real;
x,j,k,Gd, Gm: integer;
y: array[1..N] of single; Dlina: string;
Procedure Opt_plotn;
begin
s:=sqr(20-xx)+sqr(20-yy);
s1:=sqr(80-xx)+sqr(50-yy);
122
n_sr:=1+50/(s+1)+100/(s1+1);
If n_sr>5 then n_sr:=5;
end;
Procedure Opt_Dlina;
var x:integer;
begin
L:=0;
For x:=1 to N-1 do
begin
xx:=x; yy:=y[x]; Opt_plotn;
L:=L+n_sr*sqrt(sqr(y[x]-y[x+1])+dx*dx);
end;
end;
BEGIN
Randomize; dx:=1;
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
For x:=1 to N do y[x]:=2+0.7*x;
Repeat inc(k);
For x:=2 to N-1 do
begin
a:=y[x]; Opt_Dlina; L0:=L;
y[x]:=a+random(20)/100-0.1; Opt_Dlina; L1:=L;
If L1>L0 then y[x]:=a;
end;
Opt_Dlina; Str(L,Dlina);
If k mod 100=0 then
begin cleardevice;
For x:=1 to N do For j:=1 to M do
begin
xx:=x; yy:=j; Opt_plotn;
setcolor(round(n_sr*5)+5);
rectangle(20+5*x,20+5*j,24+5*x,24+5*j);
rectangle(21+5*x,21+5*j,23+5*x,23+5*j);
end;
OuttextXY(20,440,Dlina); setcolor(8);
For x:=1 to N do
begin
circle(20+round(5*x),20+round(5*y[x]),1);
circle(20+round(5*x),20+round(5*y[x]),2);
circle(20+round(5*x),20+round(5*y[x]),3);
end;
end;
until KeyPressed; CloseGraph;
END.
123
Рис. 10.5. Распространение света в неоднородной среде.
11. МОДЕЛИРОВАНИЕ БИОЛОГИЧЕСКИХ ПРОЦЕССОВ
Задача 11.1.
Размножение насекомых на изолированном острове описывается
квадратичным отображением xi+1=axi(1-xi). Изучите поведение этой функции в
зависимости от параметра a, изменяющегося в интервале от 0 до 4. Постройте
график x=x(r) и найдите точки бифуркации, в которых происходит
расщепление пути эволюции системы и наступает динамический хаос.
Численность насекомых Ni+1 в (i+1)-ом поколении с одной стороны
пропорциональна числу насекомых Ni в предыдущем i-ом поколении. С другой
стороны, с ростом Ni насекомые начинают испытывать нехватку
энергетического ресурса (еды) и их коэффициент размножения уменьшается.
При достижении числа насекомых Ni своего предела A коэффициент
размножения уменьшается до 0. Получаем уравнение:
124
Напишем программу ПР - 11.1, вычисляющую по 100-1000 значений xi при
различных значениях параметра a, который изменяется от 0 до 4 и выводит
результаты на экран в графическом виде. Результат ее работы представлен на
рис. 11.1. Видно, что пока a меньше 3 каждому значению параметра a
соответствует одно значение x. Дальнейшее увеличение a приводит к каскаду
бифуркаций удвоения периода: сначала одному значению a отвечают два
значения x, затем 4, затем 8 и т.д. Послдедовательность бифуркаций, начинаясь
слева переходит в хаос справа, которому соответствует уже не непрерывная
линия, а фрактальное множество точек. Полосы хаоса перемежаются с "окнами
периодичности".
Uses crt, graph;
{ ПР - 11.1 }
Var DrV,MV,i,j: integer;
a,x : real;
BEGIN
DrV:=Detect; InitGraph(DrV,MV,'c:\bp\bgi');
Repeat
a:=a+0.003; x:=0.01;
For i:=1 to 1000 do
begin
x:=a*x*(1-x);
If i>100 then putpixel(round(150*a),
450-round(x*350),15);
end;
until a>3.99;
For j:=1 to 4 do line(150*j,0,150*j,480);
Repeat until KeyPressed; CloseGraph;
END.
125
Рис. 11.1. Квадратичное отображение.
Задача 11.2.
На изолированном острове имеется популяция волков (хищников) и
популяция зайцев (жертв). Встречаясь с зайцем волк съедает его, при этом
число зайцев уменьшается, а популяция волков растет. Без пищи волки
вымирают от голода. Изучите динамику хищника и жертвы на компьютере.
Численность популяции зайцев и волков обозначим через N и C. Быстрота
увеличения числа зайцев dN/dt зависит от их числа N, коэффициента
рождаемости r, а также частоты встреч волков и зайцев, которая
пропорциональна NC. Скорость изменения числа волков dC/dt определяется их
количеством C, коэффициентом смертности q, а также частотой встречи с
зайцами, пропорциональной NC:
Ниже представлена программа ПР - 11.2, позволяющая вычислить численность
популяции волков и зайцев в последовательные моменты времени и строящая
фазовую кривую системы. Результат вычислений -- на рис. 11.2.
126
uses crt, graph;
{ ПР - 11.2 }
var t,N,C,dN,dC : real;
Gd,Gm : integer;
const
r=0.03; q=0.01; a=0.00001; f=0.15; dt=0.1;
BEGIN
Gd:= Detect; InitGraph(Gd, Gm, 'c:\bp\bgi\');
N:=5000; C:=1000;
Line(0,400,640,400); Line(20,0,20,480);
Repeat
t:=t+dt;
dN:=(r*N-a*N*C)*dt; {зайцы}
dC:=(-q*C+f*a*N*C)*dt; {волки}
N:=N+dN; C:=C+dC; t:=t+dt;
circle(20+round(t/5),400-round(N/100),1);
circle(20+round(t/5),400-round(C/100),2);
{circle(20+round(N/50),400-round(C/50),2);}
until t>3000;
Repeat until keypressed;
CloseGraph;
END.
Рис. 11.2. Динамика популяции волков и зайцев.
Задача 11.3.
Имеется популяция животных одного вида. Известен коэффициент
рождаемости r, коэффициент смертности s и максимально возможная
численность животных K. Как изменяется численность популяции с течением
времени, если смертность на некоторое время резко увеличивается (например,
вследствие эпидемии).
127
Быстрота увеличения численности животных dN/dt пропорциональна их
количеству N. При этом имеет место внутривидовая конкуренция, состоящая в
использовании энергетического ресурса одним животным, что снижает
доступность этого ресурса для другого животного того же вида. Это приводит к
тому, что с ростом численности N коэффициент рождаемости уменьшается, а
когда N приближается к максимально возможному числу K, рождаемость
падает до 0. Чтобы учесть уменьшение числа животных N вследствие
смертности, вводят слагаемое -sN, где s --- коэффициент смертности.
Получается:
Для численного решения этого уравнения используется программа ПР - 11.3. В
интервале [t1;t2] смертность увеличивается в 5 раз. Результат моделирования -на рис. 11.3.
uses crt, graph;
{ ПР - 11.3 }
var t,s,N,C,dN,dC: real; Gd,Gm: integer;
const r=0.03; K=100; dt=0.1;
BEGIN
Gd:= Detect; InitGraph(Gd, Gm, 'c:\bp\bgi\');
Line(0,400,640,400); Line(20,0,20,480); N:=2;
Repeat
t:=t+dt;
If (t>1000)and(t<1500) then s:=0.01 else s:=0.002;
dN:=(r*N*(K-N)/K-s*N)*dt;
N:=N+dN; t:=t+dt;
circle(20+round(t/4),400-round(N*3),2);
until t>3000;
Repeat until keypressed; CloseGraph;
END.
128
Рис. 11.3. Зависимость численности популяции от времени.
12. АВТОМАТЫ. КЛЕТОЧНЫЕ АВТОМАТЫ
Задача 12.1.
Напишите программу, моделирующую работу автомата с четырьмя
внутренними состояниями. Диаграмма Мура задана. На вход автомата
поступает последовательность символов "baba ... acbb".
129
Рис. 12.1. Диаграмма Мура автомата с четырьмя состояниями.
Автомат -- это дискретное устройство, имеющее конечное множество
внутренних состояний Q={q1, q2, ...}, и преобразующий входные сигналы
(символы) X={x1, x2, ...} в выходные сигналы (символы) Y={y1, y2, ...} в
соответствии с определенными правилами, задаваемыми функцией перехода и
функцией выходов. Для задания автомата строят диаграмму Мура, которая
представляет собой ориентированный граф. Вершины графа изображают
состояния автомата Q={1, 2, 3, 4}. Каждой команде соответствует ребро,
идущее из qi в qj. Из диаграммы на рис. 12.1 видно, что если автомат находится
в состоянии 2, на вход поступает символ "c", то автомат переходи в состояние
4, на выходе получается символ A.
Компьютерная программа ПР - 12.1 моделирует работу автомата с четырьмя
внутренними состояниями, на вход которого поступает последовательность
символов S:="baba ... acbb". При ее работе на экране появляется номер
состояния автомата символ на его выходе в результате первого, второго,
третьего ... шага.
uses crt;
{ ПР
- 12.1 }
var i: integer; x,y,S,a,b,c: string;
q: integer; label m;
BEGIN S:='babacaabcbabcbcbaaccbcbabcbccaacbb';
writeln('S=',S);q:=1;
For i:=1 to length(S) do begin x:=copy(S,i,1);
If (x='a')and(q=1) then begin q:=1; y:='B'; goto
m; end;
If (x='c')and(q=1) then begin q:=2; y:='A'; goto
m; end;
130
If (x='b')and(q=1) then
m; end;
If (x='b')and(q=2) then
m; end;
If (x='a')and(q=2) then
m; end;
If (x='c')and(q=2) then
m; end;
If (x='a')and(q=3) then
m; end;
If (x='c')and(q=3) then
m; end;
If (x='b')and(q=3) then
m; end;
If (x='a')and(q=4) then
m; end;
If (x='b')and(q=4) then
m; end;
If (x='c')and(q=4) then
m; end;
m: write(q,' ',y,' | ');
end; ReadKey;
END.
begin q:=4; y:='C'; goto
begin q:=2; y:='D'; goto
begin q:=3; y:='B'; goto
begin q:=4; y:='A'; goto
begin q:=4; y:='C'; goto
begin q:=3; y:='E'; goto
begin q:=2; y:='C'; goto
begin q:=4; y:='E'; goto
begin q:=3; y:='F'; goto
begin q:=1; y:='D'; goto
Задача 12.2.
Создайте компьютерную модель ученика, представляющего собой
вероятностный автомат с несколькими внутренними состояниями. Ученик
случайным образом переходит из одного состояния в другое, совершая
определенную последовательность действий. Промоделируйте процесс
обучения.
Рис. 12.2.1. Диаграмма Мура автомата с двумя состояниями.
Рассмотрим абстрактную модель ученика, представляющую собой
вероятностный автомат с двумя состояниями. При переходе из одного
состояния в другое автомат как-бы выполняет некоторую операцию (действие).
Будем считать, что автомат обучен, когда из состояния 1 он переходит в
состояние 2, а из состояния 2 --- в состояние 1 и т.д.: 1-2-1-2-1-2-... Если из
состояния 1 автомат переходит в состояние 1 или из состояния 2 переходит в
состояние 2, то он совершает ошибку. Вероятность правильного действия
131
обозначим через p, тогда вероятность неправильного действия равна q=1-p. В
принципе можно изучать работу вероятностного автомата с большим числом
состояний, но при этом всегда один из переходов будет правильным, а
остальные --- неправильными.
Изначально автомат необучен. Пусть он может совершить 100 различных
операций с равными вероятностями, тогда вероятность правильного действия
p=0.01. Программа ПР - 12.2.1, моделирующая ученика, содержит цикл, в
котором выбор каждой операции осуществляется с помощью генератора
случайных чисел. Если случайное число x, находящееся в интервале [0;1],
меньше p, то АМУ совершает правильное действие, если нет --- то делает
ошибку. Процесс обучения приводит к изменению матрицы вероятностей:
вероятность правильного выбора p увеличивается на a*q, где a --- коэффициент
научения, а вероятность ошибки уменьшается на ту же величину. Уровень
знаний Z будем считать равным вероятности p правильного перехода.
Чтобы учесть забывание необходимо на каждом временном шаге уменьшать p
на g*p (g --- коэффициент забывания) и на такую же величину увеличивать q:
p:=p-g*p; q:=q+g*p; {забывание}
Программа позволяет промоделировать ситуации:
Обучение с поощрением: при выполнении правильного действия ученика
"поощряют", пересчитывая вероятности p и q. Так как сначала ученик
ошибается гораздо чаще (q превосходит p), то сначала обучение происходит
медленно (рис. 12.2.2). Зато по мере увеличения "знаний" вероятность
совершения правильного действия растет. Акты обучения происходят все чаще,
вероятность p увеличивается до 1. Программа содержит строку:
If (x<p)and(t<4000) then
begin p:=p+a*q; q:=q-a*q; end;
Обучение с наказанием: в случае ошибки ученика "наказывают", подсказывая
ему правильный ответ, что приводит к росту p и уменьшению q. Сначала
ученик ошибается часто, поэтому уровень его "знаний" быстро растет,
вероятность ошибки q падает (рис. 12.2.3). Акты обучения происходя реже,
вероятность правильного действия не достигает 1 (за счет забывания).
Программа содержит строку:
If (x>p)and(t<4000) then
begin p:=p+a*q; q:=q-a*q; end;
Обучение с поощрением и наказанием: при правильном ответе ученика
поощряют, а при неправильном наказывают, подсказывая правильный ответ. В
обоих случаях вероятность правильного действия p растет, а вероятность
ошибки снижается. За счет того, что при любом действии учащегося его учат,
уровень знаний быстро растет и достигает 1 (рис. 12.2.4). Программа содержит
132
строку:
If t<4000 then begin p:=p+a*q; q:=q-a*q; end;
uses dos, crt, graph;
{ ПР - 12.2.1
}
var t,Gd,Gm : integer; x,p,q,a,g : real;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
Randomize;
line(0,450,640,450); line(10,0,10,480);
p:=0.01; q:=1-p; a:=0.003; g:=0.0004;
Repeat
inc(t); x:=random(1000)/1000;
If (x>p)and(t<4000) then
begin
p:=p+a*q; q:=q-a*q;
end;
p:=p-g*p; q:=q+g*p; {забывание}
Circle(10+round(t/15),450-round(400*p),2);
until (t>10000)or(KeyPressed);
Repeat until KeyPressed; CloseGraph;
END.
Рис. 12.2.2. Обучение с поощрением.
133
Рис. 12.2.3. Обучение с наказанием.
Рис. 12.2.4. Обучение с поощрением и наказанием.
Рассмотрим другой вариант решения задачи (программа ПР - 12.2.2). В
процедуре Uchenik случайным образом, исходя из матрицы вероятностей,
производится переход в следующее состояние. В процедуре Obuchenie
осуществляется пересчет вероятностей переходов из одного состояния в
другое, в процедуре Zabyvan различие между вероятностями правильных и
неправильных переходов уменьшается. На экране получаются графики
зависимости уровня знаний от времени при различных коэффициентах
научения и забывания (рис. 12.2.5).
134
uses crt, graph;
{ ПР 12.2.2 }
const N=2; NN=4000;
var x : array[1..NN] of integer;
p : array[1..2,1..2] of real;
EC,DV,MV,k,i,j : integer;
alpha,beta,s,rnd : real;
Procedure Uchenik;
begin
rnd:=random(1000)/1000; inc(i);
If rnd500 then goto met;
If (x[i-1]=1)and(x[i]=2) then
begin
p[1,2]:=p[1,2]+alpha*(1-p[1,2]);
p[1,1]:=(1-alpha)*p[1,1];
end;
If (x[i-1]=2)and(x[i]=1) then
begin
p[2,1]:=p[2,1]+alpha*(1-p[2,1]);
p[2,2]:=(1-alpha)*p[2,2];
end;
met:
end;
Procedure Zabyvan;
begin
p[1,2]:=p[1,2]-beta*(p[1,2]-p[1,1]);
p[1,1]:=p[1,1]+beta*(p[1,2]-p[1,1]);
p[2,1]:=p[2,1]-beta*(p[2,1]-p[2,2]);
p[2,2]:=p[2,2]+beta*(p[2,1]-p[2,2]);
end;
Procedure Raschet;
begin
For i:=1 to 2 do For j:=1 to 2 do p[i,j]:=0.5;
For k:=1 to NN do
begin
Uchenik; Obuchenie; Zabyvan; j:=x[i];
circle(10+round(0.3*i),450-round(800*((p[1,2]0.5))),1);
end;
end;
BEGIN
DV:=Detect; InitGraph(DV,MV,'c:\bp\bgi');
Randomize; Line(0,450,640,450);
beta:=0.001; alpha:=0.01; Raschet;
beta:=0.002; alpha:=0.01; Raschet;
beta:=0.001; alpha:=0.02; Raschet;
Repeat until Keypressed; CloseGraph;
135
END.
Рис. 12.2.5. Кривые обучения.
Задача 12.3.
Промоделируйте работу гомеостата Эшби --- адаптирующегося устройства с
тремя степенями свободы x1, x2, x3, которое при выводе из положения
равновесия (0,0,0) самостоятельно в него возвращается.
Гомеостат описывается тремя дифференциальными уравнениями:
Программа ПР - 12.3.1 для нахождения коэффициентов ai,j, определяющих
работы гомеостата, работает так. Значения ai,j и xjзадаются случайным образом.
Вычисляются скорости v1, v2, v3 и координаты x1, x2, x3 в последовательные
моменты времени. Если модуль хотя бы одной из координат превысил 1, то
коэффициенты ai,j изменяются случайным образом. Так продолжается до тех
136
пор, пока система не вернется в положение равновесия (0,0,0). Найденные
значения коэффициентов ai,j печатаются в файл.
uses dos, crt, graph;
{ ПР - 12.3.1
}
const n=3; dt=0.01;
var x1,x2,x3,v1,v2,v3 : real; Gd, Gm,i,j,k : integer;
a: array[1..n,1..n]of real; F: text;
BEGIN
Assign(F,'111.bak');Append(F);
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
Randomize; x1:=0.1;
For i:=1 to n do For j:=1 to n do a[i,j]:=0.1random(200)/1000;
line(10,100,640,100);line(100,10,100,480);line(400,10,
400,480);
Repeat
v1:=a[1,1]*x1+a[1,2]*x2+a[1,3]*x3;
v2:=a[2,1]*x1+a[2,2]*x2+a[2,3]*x3;
v3:=a[3,1]*x1+a[3,2]*x2+a[3,3]*x3;
x1:=x1+v1*dt; x2:=x2+v2*dt; x3:=x3+v3*dt;
If abs(x1)>1 then For j:=1 to n do a[1,j]:=0.1random(200)/1000;
If abs(x2)>1 then For j:=1 to n do a[2,j]:=0.1random(200)/1000;
If abs(x3)>1 then For j:=1 to n do a[3,j]:=0.1random(200)/1000;
If x1>1 then x1:=0.99; if x1<-1 then x1:=-0.99;
If x2>1 then x2:=0.99; if x2<-1 then x2:=-0.99;
If x3>1 then x3:=0.99; if x3<-1 then x3:=-0.99;
circle(100+round(x1*100),100-round(x2*100),1);
circle(400+round(x2*100),100-round(x3*100),1);
k:=k+1;
until (k>40000)or(keypressed);
For i:=1 to 3 do Writeln(F,a[i,1],' ',a[i,2],'
',a[i,3],' ');
Readkey; Close(F);
END.
137
Рис. 12.3.1. Подбор параметров гомеостата.
В результате работы программы ПР-1 рассчитываются коэффициенты ai,j, при
которых гомеостат находится в положении равновесия (0,0,0). Эта задача имеет
несколько решений. Допустим, получились следующие значения:
После того, как найдены оптимальные параметры гомеостата, можно
исследовать, как ведет себя гомеостат при выводе его из положения
равновесия. В программе ПР - 12.3.2 случайным образом задаются начальные
координаты x1, x2, x3 из интервала [-0,9; 0,9] и рассчитывается "поведение"
гомеостата в последующие моменты времени. Во всех случаях гомеостат
возвращается в положение равновесия.
uses dos, crt, graph;
{ ПР 12.3.2 }
const n=3; dt=0.01;
var x1,x2,x3,v1,v2,v3,k : real; Gd, Gm,i,j :
integer;
a: array[1..n,1..n]of real; F: text;
begin Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
Randomize; x1:=0.1;
a[1,1]:=-0.089; a[1,2]:=-0.001; a[1,3]:=0.07;
a[2,1]:=0.082; a[2,2]:=-0.043; a[2,3]:=-0.028;
a[3,1]:=-0.072; a[3,2]:=-0.045; a[3,3]:=0.027;
138
Repeat k:=k+0.1;
v1:=a[1,1]*x1+a[1,2]*x2+a[1,3]*x3;
v2:=a[2,1]*x1+a[2,2]*x2+a[2,3]*x3;
v3:=a[3,1]*x1+a[3,2]*x2+a[3,3]*x3;
x1:=x1+v1*dt; x2:=x2+v2*dt; x3:=x3+v3*dt;
if k>5000 then begin x1:=0.9-random(1800)/1000;
x2:=0.9-random(1800)/1000; x3:=0.9random(1800)/1000;
k:=0; delay(10000);
cleardevice; line(0,240,640,240);
line(150,10,150,480); line(450,10,450,480); end;
circle(150+round(x1*150),240-round(x2*150),1);
circle(450+round(x2*150),240-round(x3*150),1);
until keypressed;
Repeat until keypressed; CloseGraph;
end.
Рис. 12.3.2. Функционирование гомеостата.
Задача 12.4.
Промоделируйте игру Жизнь. Плоская поверхность разбита на клетки,
ведущие себя как автоматы, способные находиться в двух состояниях:
"живой" и "метртвый". Клетка оживает при наличии 3 живых соседей. Если
живых соседей 4 и больше, она умирает от перенаселенности. Если живых
соседей меньше 2, она умирает от одиночества.
Представим двумерную сетку, в каждом узле --- автомат, реализующий
заданное правило. Используется программа ПР - 12.4. Состояния клеток
закодированы так: клетка "жива" - 1, "мертва" - 0. Вычисление числа "живых"
соседей и установление "жива" данная клетка или нет на следующем
временном шаге осуществляется в процедуре Raschet и записывается в массив
x[i,j]. В массив x1[i,j] записывается состояние клеток на предыдущем
временном шаге. В начале программы следует задать исходное распределение
"живых" клеток.
139
uses crt; const N=26;
{ ПР - 12.4 }
type z1=record x,y,xy,x1,y1:real end;
massiv = array[-1..N+1,-1..N+1] of integer;
var z,y,x,x1: massiv; s,i,j,k,l,m:integer;
procedure Print;
var i,j:integer;
begin
clrscr;
For i:=1 to N do For j:=1 to N do
begin
If x[i,j]=1 then Write(' * ');
If x[i,j]=0 then Write('
');
end; Writeln;
end;
procedure Oboznach;
var i,j:integer;
begin
For i:=1 to N do For j:=1 to N do x1[i,j]:=x[i,j];
end;
procedure Raschet;
var i,j:integer;
begin
For i:=1 to N do For j:=1 to N do
begin
S:=x1[i-1,j-1]+x1[i-1,j]+x1[i-1,j+1]+x1[i,j-1]+
x1[i,j+1]+x1[i+1,j-1]+x1[i+1,j]+x1[i+1,j+1];
If s=3 then x[i,j]:=1;
If (s<2)or(s>3) then x[i,j]:=0;
end;
end;
BEGIN
For i:=-1 to N+1 do For j:=-1 to N+1 do x[i,j]:=0;
{x[14,18]:=1; x[14,17]:=1; x[14,16]:=1;
x[14,15]:=1;}
{x[14,17]:=1; x[14,16]:=1; x[14,15]:=1;}
{x[14,17]:=1; x[14,16]:=1; x[14,15]:=1;
x[13,15]:=1; x[12,16]:=1;}
{x[15,13]:=1; x[15,14]:=1; x[15,15]:=1;
x[16,14]:=1;}
{x[14,17]:=1; x[14,16]:=1; x[14,15]:=1;
x[15,16]:=1; x[15,15]:=1; x[15,14]:=1;}
x[14,17]:=1; x[14,16]:=1; x[14,15]:=1;
x[15,16]:=1; x[15,15]:=1; x[15,14]:=1;
x[14,10]:=1; x[14,11]:=1; x[14,12]:=1;
x[15,11]:=1; x[15,15]:=1; x[15,13]:=1; Print;
Repeat delay(6000); Oboznach; Raschet; Print;
until keypressed;
140
END.
Задача 12.5.
Промоделируйте распространение автоволн в двумерной активной среде.
Изучите однорукавную и двурукавную автоволны, подавление
высокочастотного источника низкочастотным, дифракцию автоволн.
Каждый элемент активной среды может находиться в трех различных
состояниях: покое, возбуждении и рефрактерности. При отсутствии внешнего
воздействия, элемент находится в состоянии покоя. В результате воздействия
элемент переходит в возбужденное состояние, приобретая способность
возбуждать соседние элементы. Через некоторое время после возбуждения
элемент переключается в состояние рефрактерности, находясь в котором он не
может быть возбужден. Затем элемент сам возвращается в исходное состояние
покоя, то есть снова приобретает способность переходить в возбужденное
состояние.
Рассмотрим обобщенную модель Винера--Розенблюта. Пусть состояние
каждого элемента в момент t описывается фазой yi,jt, и концентрацией
активатора ui,jt. Если элемент находится в покое, то будем считать, что yi,jt=0.
Если вследствие близости возбужденных элементов концентрация активатора
ui,jt достигает порогового значения h, то элемент возбуждается и переходит в
состояние 1. Затем на следующем шаге он переключается в состояние 2, затем -- в состояние 3 и т.д., оставаясь при этом возбужденным. Достигнув состояния
r элемент переходит в состояние рефрактерности. Через s (s>r) шагов после
возбуждения элемент возвращается в состояние покоя:
Будем считать, что при переходе из состояния s в состояние покоя 0
концентрация активатора становится равной 0. При наличии соседнего
элемента, находящегося в возбужденном состоянии, она увеличивается на 1.
Можно ограничиться учетом ближайших восьми соседних элементов.
Используется программа ПР - 12.5, получающиеся результаты представлены на
рис. 12.5.1 и 2.
141
uses dos, crt, graph;
{ ПР - 12.5 }
Const N=110; M=90; s=18; r=10; h=10;
Var y, yy, u : array [1..N,1..M] of integer;
ii, jj, j, k, Gd, Gm: integer; i: Longint;
Label met;
BEGIN Gd:= Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
If GraphResult <> grOk then Halt(1);
setcolor(8); setbkcolor(15);
(* y[50,50]:=1;
{ Одиночная волна } *)
(* For j:=1 to 40 do
{ Однорукавная волна }
For i:=1 to s do y[50+i,j]:=i; *)
(* For j:=1 to M do
{ Двурукавная волна }
For i:=1 to s do begin
y[50+i,j]:=i;
If j>40 then y[50+i,j]:=14-i; end; *)
Repeat k:=k+1;
{If k=round(k/20)*20 then y[60,40]:=1; {Осциллятор
1}
If k=round(k/30)*30 then y[20,30]:=1; {Осциллятор
2}
For i:=2 to N-1 do For j:=2 to M-1 do
begin
If (y[i,j]>0) and (y[i,j]<=""> 0 then goto
met;
For ii:=i-1 to i+1 do For jj:=j-1 to j+1 do
begin
If (y[ii,jj]>0) and (y[ii,jj]<=r) then
u[i,j]:=u[i,j]+1;
If u[i,j]>=h then yy[i,j]:=1;
end;
met:
end;
Delay(1000); cleardevice;
(* For i:=21 to 70 do
begin
yy[i,60]:=0; yy[i,61]:=0;
end;
rectangle(6*21-10,500-6*60,6*70-10,500-6*61); *)
For i:=1 to N do For j:=1 to M do
begin
y[i,j]:=yy[i,j]; setcolor(12);
If (y[i,j]>=1) and (y[i,j]<=r) then
begin
circle(6*i-10,500-6*j,3);
circle(6*i-10,500-6*j,2);
circle(6*i-10,500-6*j,1);
end; setcolor(8);
If (y[i,j]>r) and (y[i,j]<=s) then
142
begin
circle(6*i-10,500-6*j,3);
circle(6*i-10,500-6*j,2);
circle(6*i-10,500-6*j,1);
end;
end;
until KeyPressed; CloseGraph;
END.
Рис. 12.5.1. Однорукавная и двурукавная автоволны.
Рис. 12.5.2. Подавление низкочастотного источника высокочастотным.
Дифракция автоволн.
Задача 12.6.
С помощью двумерных клеточных автоматов создайте модель наполнения
сосуда вязкой жидкостью. Сосуд содержит внутри себя различные
препятствия: цилиндрический стержень, пластину, перегородки и т.д.
143
Рис. 12.6.1. Струя жидкости, наполняющая сосуд.
Рассмотрим струю вязкой жидкости, падающую в сосуд (рис. 12.6). Будем
различать три области: 1) собственно струя, то есть область, включающая
падающие вниз частицы жидкости; 2) область, включающая часть жидкости,
которая растекается в горизонтальном направлении; 3) область, включающая
неподвижные частицы жидкости, полностью заполняющие горизонтальные
строки матрицы ai,j. Промоделируем это явление с помощью двумерных
клеточных автоматов. Разобъем плоскость на клетки с координатами i и j (ось i
направим вправо, ось j вверх) и введем двумерный массив ai,j. Будем считать,
что если клетка пустая, то ai,j=0, если в клетке имеется жидкость, то ai,j=1.
Препятствия, дно и стенки сосуда состоят из клеток, для которых xi,j=-2 (можно
было бы присвоить значение -1, но в этом случае произведение двух элементов
массива ai,j равно 1, когда эти элементы равны 1 или -1, что неудобно). Если
произведение a13,24и a13,25 равно 1, то в обоих клетках находится жидкость.
<="" p="">
Рис. 12.6.2. Опускание частиц жидкости.
Чтобы промоделировать опускание частиц жидкости под действием силы
тяжести (рис. 12.6.2) должны выполняться следующие правила:
Если a[i,j]=1 (жидкость), то
1. Если a[i,j-1]=0, то a[i,j-1]:=1, a[i,j]:=0;
2. Если a[i,j]=1 и a[i-1,j-1]=0 и a[i+1,j-1]=0,
то a[i,j]:=0 и с вероятностью 0,5
a[i-1,j-1]:=1 или a[i+1,j-1]:=1;
3. Если a[i-1,j-1]=0 и a[i+1,j-1]=1,
то a[i-1,j-1]:=1, a[i,j]:=0;
4. Если a[i+1,j-1]=0 и a[i-1,j-1]=1,
то a[i+1,j-1]:=1, a[i,j]:=0;
144
Рис. 12.6.4. Растекание струи.
Когда вертикальная струя жидкости падает на горизонтальную поверхность, то
направление движения частиц жидкости изменяется на 90 градусов. При этом
жидкость растекается по поверхности так, что частицы жидкости из средней
части струи перемещаются в горизонтальном направлении вправо или влево.
Это можно промоделировать следующим образом (рис. 12.6.4):
Если a[i,j]=1 и (a[i,j-1]=-2 или a[i,j-2]=-2 или
a[i,j-3]=-2 или a[i,j-4]=-2), то с вероятностью 0,1
смещать элемент по горизонтали влево или вправо до
первой пустой клетки;
Аналогичное правило должно выполняться при наполнении сосуда. Компьютер
подсчитывает толщину области 3, частицы которой полностью заполняют
горизонтальные строки двумерной матрица ai,j между стенками сосуда.
Растекание жидкости в области 2, которая содержит пустые клетки с ai,j=0
моделируется так: случайно выбирается наполненная жидкостью клетка (ai,j=1)
и смещается по горизонтали влево или вправо (случайный выбор) до
ближайшей пустой клетки, после чего эти клетки меняются местами (рис.
12.6.4).
Предложенный алгоритм реализован в программе ПР - 12.6, представленной
ниже. Результаты моделирования заполнения жидкостью сосуда с
препятствиями представлены на рис. 1.
Uses crt, graph;
{ ПР - 12.6
}
Const n=180; m=120;
Var b,s,f,i,ii,i1,j,k,DV,MV: integer; x: real;
a: array[1..N,1..M] of integer;
Procedure Obmen(ii,jj: integer);
begin a[i,j]:=0; a[ii,jj]:=1; end;
Procedure Smeshenie; {смещение частиц по
горизонтали}
label m5, m2, m6;
begin
begin x:=random(100)/100;
If (a[i,j]=1)and(x<0.5) then
begin i1:=i-1; m5:
If a[i1,j]=-2 then goto m2;
If a[i1,j]=0 then begin Obmen(i1,j); goto m2;
end
else i1:=i1-1; goto m5;
end;
145
If (a[i,j]=1)and(x>0.5) then
begin
i1:=i+1; m6:
If a[i1,j]=-2 then goto m2;
If a[i1,j]=0 then begin
a[i,j]:=0; a[i1,j]:=1; goto m2; end
else i1:=i1+1; goto m6;
end;
end; m2:
end;
Procedure Raschet1;
var i1 :integer; label m1; {расчет струи}
begin
If (k<250)and(abs(100-i)<8) then a[i,M]:=1;
If (a[i,j]=0)or(a[i,j]=-2) then goto m1;
If (a[i,j-1]=0) then
begin Obmen(i,j-1); goto m1; end;
If (a[i,j]=1)and(a[i-1,j-1]=0)and(a[i+1,j-1]=0)
then
begin
x:=Random(100)/100;
If x<0.5 then Obmen(i-1,j-1) else Obmen(i+1,j1);
goto m1;
end;
If (a[i,j-1]<>0)and(a[i-1,j-1]=0)and(a[i+1,j-1]=1)
then
begin Obmen(i-1,j-1); goto m1;
end;
If (a[i,j-1]<>0)and(a[i+1,j-1]=0)and(a[i-1,j-1]=1)
then
begin Obmen(i+1,j-1); goto m1;
end;
x:=random(100)/100;
If (x<0.1)and(j>30)and(a[i,j]=1)and((a[i,j-1]=2)or(a[i,j-2]=-2)
or(a[i,j-3]=-2)or(a[i,j-4]=-2)) then Smeshenie;
m1:
end;
Procedure Raschet2;
label m1; {поверхностное натяжение}
begin
If (a[i,j]*a[i+1,j]*a[i+2,j-1]=1)and(a[i+1,j1]=0)then
begin Obmen(i+1,j-1); goto m1;
end;
If (a[i,j]*a[i-1,j]*a[i-2,j-1]=1)and(a[i-1,j146
1]=0)then
begin Obmen(i-1,j-1); goto m1;
end;
If
(a[i,j]*a[i+1,j]*a[i+2,j+1]=1)and(a[i+1,j+1]=0)then
begin Obmen(i+1,j+1); goto m1;
end;
If (a[i,j]*a[i-1,j]*a[i-2,j+1]=1)and(a[i1,j+1]=0)then
begin Obmen(i-1,j+1); goto m1;
end;
m1:
end;
Procedure Raschet3;
begin b:=2; {жидкость в сосуде}
For j:=2 to 40 do
begin
s:=0;
For i:=2 to N-1 do If a[i,j]=1 then s:=s+1;
If s>22 then begin b:=j+1; end;
end; Randomize;
For j:=2 to b+2 do For ii:=1 to 25 do
begin
i:=round(random(n)); Smeshenie;
end;
end;
BEGIN
DV:=Detect; InitGraph(DV,MV,'c:\bp\bgi');
Randomize; Setbkcolor(15);
For i:=1 to N do For j:=1 to M do
begin
If (abs(60-i)<2)and(j<8) then a[i,j]:=-2;
If (j<20-0.5*i)or(i=1)or(i=N)or(j=1) then
a[i,j]:=-2;
If (95-i)*(95-i)+(j-85)*(j-85)<70 then a[i,j]:=2;
If (i>50)and((150-i)*(150-i)+j*j<150) then
a[i,j]:=-2;
If (abs(j-60)<2)and(abs(110-i)<8) then a[i,j]:=2;
end;
Repeat inc(k);
For i:=1 to N do For j:=1 to M do
begin
If a[i,j]=0 then setcolor(15);
If a[i,j]=1 then setcolor(8);
If a[i,j]=-2 then setcolor(9);
147
rectangle(15+3*i,450-3*j,15+3*i+2,450-3*j+2);
end;
For j:=1 to M do For i:=1 to N do Raschet1;
For j:=1 to M do For i:=N downto 1 do Raschet1;
For i:=1 to N do For j:=50 to M do Raschet2; f:=0;
For i:=1 to N do If a[i,2]=1 then f:=1;
If f=1 then Raschet3; Delay(1); ClearDevice;
until KeyPressed or(k>300);
Repeat until KeyPressed; CloseGraph;
END.
Рис. 12.6.5. Наполнение сосуда жидкостью.
148
Рис. 12.6.6. Наполнение сосуда жидкостью (увеличено).
Рис. 12.6.7. Наполнение сосуда жидкостью (t=40, 80, 160 и 240).
13. ИНФОРМАЦИЯ И ЕЕ КОДИРОВАНИЕ
Задача 13.1.
Задано сообщение из 50 символов на алфавите из 5 букв. Напишите
программу, которая вычисляет вероятности каждого символа и по формуле
Шеннона определяет среднюю информацию, приходящуюся на 1 символ и
общую информацию в сообщении. Убедитесь в том, что: 1) если все символы
одинаковы, информативность сообщения минимальна; 2) если символы
149
алфавита встречаются с равными вероятностями, то сообщение несет
максимальное количество информации.
В программе ПР - 13.1 из сообщения r="aqws...ea" вырезается первый, второй,
третий и последующие символы и определяется, частота (эмпирическая
вероятность) каждой буквы алфавита, результат выводится на экран. Для
нахождения средней информации приходящейся на 1 символ используется
формула Шеннона:
Чтобы определить информативность всего сообщения необходимо
получившуюся величину умножить на число символов N. Если какая-либо
буква ни разу не встречается в тексте, то ее эмпирическая вероятность равна 0
и логарифм неопределен. Чтобы избежать этого вместо ln(pa) в программе
вычисляется ln(pa+0.001). С помощью программы можно убедиться в том, что
информативность сообщения максимальна тогда, когда все символы
используются с равными вероятностями. Если в сообщении повторяется один и
тот же символ, то информативность сообщения равна 0.
uses crt;
{ ПР - 13.1 }
var N,i,a,q,w,s,e: integer; r,s1: string;
h1,pi,pa,pq,pw,ps,pe,h: real;
BEGIN clrscr;
r:='aqwseaeswaqeawseqweasesaeseeewawwqwwesassea';
a:=0; q:=0; w:=0; s:=0; e:=0; N:=length(r);
For i:=1 to N do
begin
If r[i]='a' then a:=a+1;
If r[i]='q' then q:=q+1;
If r[i]='w' then w:=w+1;
If r[i]='s' then s:=s+1;
If r[i]='e' then e:=e+1;
end;
Writeln ('буква а встречается ',a,' раз');
Writeln ('буква q встречается ',q,' раз');
Writeln ('буква w встречается ',w,' раз');
Writeln ('буква s встречается ',s,' раз');
Writeln ('буква e встречается ',e,' раз');
pa:=a/N; pq:=q/N; pw:=w/n; ps:=s/n; pe:=e/n;
Writeln ('Pa=',pa); Writeln ('Pq=',pq);
Writeln ('Pw=',pw); Writeln ('Ps=',ps); Writeln
('Pe=',pe);
h1:=N*(((pa*(ln(pa+0.001)/ln(2)))+(pq*(ln(pq+0.0000001)/ln
(2)))));
150
h:=h1N*((pw*(ln(pw+0.001)/ln(2)))+(ps*(ln(ps+0.001)/ln(2)))
+(pe*(ln(pe+0.001)/ln(2))));
writeln('H=',h); readkey;
END.
Задача 13.2.
Напишите программу, кодирующую двоичным кодом сообщение из 20 букв
на алфавите из 8 букв. На каждую букву приходится три двоичных разряда:
a - 000, b - 001, c - 010, ... , h - 111. На экран выводится закодированное
сообщение, затем осуществляется декодирование.
Используется программа ПР - 13.2. Из заданного сообщения s="abc..defa" она
вырезает по одному символу, он кодируется тремя битами и изаписывается в
стринговую переменную b. Аналогичным образом осуществляется
декодирование.
uses crt;
{ ПР - 13.2 }
var f,s,a,b:string;
i,k:integer; x:real;
BEGIN clrscr;
s:='aaabbcbddeeebbcadeaabbddeeffgh';
writeln(s); b:='';
{======= КОДИРОВАНИЕ ==========}
For i:=1 to length(s) do
begin
a:=s[i];
If a='a' then b:=b+'000'; If a='b' then
b:=b+'001';
If a='c' then b:=b+'010'; If a='d' then
b:=b+'011';
If a='e' then b:=b+'100'; If a='f' then
b:=b+'101';
If a='g' then b:=b+'110'; If a='h' then
b:=b+'111';
end; write(b); writeln;
{====== ДЕКОДИРОВАНИЕ =========}
s:='';
For i:=1 to length(b) do
begin
f:=copy(b,3*i-2,3);
If f='000' then s:=s+'a'; If f='001' then
s:=s+'b';
If f='010' then s:=s+'c'; If f='011' then
s:=s+'d';
151
If f='100' then s:=s+'e'; If f='101' then
s:=s+'f';
If f='110' then s:=s+'g'; If f='111' then
s:=s+'h';
end;
write(s); readln;
END.
Задача 13.3.
Имеется сообщение 01101 ... 01. Напишите программу, кодирующую его
помехоустойчивым кодом, в котором каждый бит утраивается, затем вносит
ошибки с заданной вероятностью p и декодирует сообщение.
Используется программа ПР - 13.3. Из заданного сообщения aa1="01101 ... 01"
вырезается по одному символу 0 или 1, он утраивается, то есть получается 000
или 111. Результат выводится на экран.
После этого в получившееся закодированное сообщение с заданной
вероятностью вносятся ошибки, сообщение выводится на экран. Затем оно
декодируется в соответствии с правилом: кодовые последовательности 111,
011, 101, 110 воспринимаются как 1, а кодовые последовательности 000, 100,
010, 001 воспринимаются как 0. Данный код исправляет часть ошибок.
Программа вычисляет относительное число ошибок при заданной вероятности
p и позволяет изучить k от p и построить график.
uses crt;
13.3 }
var aa1,aa,y,z,zz,x1,x : string;
i : byte; s,k,p : real;
BEGIN clrscr;
writeln('Исходное сообщение: ');
{ ПР -
aa1:='101010101010101010101010101010101010101010101010
101010';
writeln(aa1); writeln('Задайте вероятность ошибки:
');
readln(p);
{======== КОДИРОВАНИЕ ===========}
For i:=1 to length(aa1) do
begin
x:=copy(aa1,i,1);
If x='0' then y:='000';
If x='1' then y:='111'; z:=z+y;
end;
writeln('Закодированное сообщение: '); writeln(z);
{======== ВНЕСЕНИЕ ОШИБОК ===========}
152
randomize; zz:='';
For i:=1 to length(z) do
begin
s:=random(1000)/1000;
If (s=p then zz:=zz+z[i];
end;
writeln('Сообщение с ошибкой: '); writeln(zz);
{=== ДЕКОДИРОВАНИЕ, ИСПРАВЛЕНИЕ ОШИБОК ===}
aa:=''; i:=1;
while i < length(zz) do
begin
x:=copy(zz,i,3);
If x='000' then y:='0'; If x='001' then y:='0';
If x='010' then y:='0'; If x='011' then y:='1';
If x='100' then y:='0'; If x='101' then y:='1';
If x='110' then y:='1'; If x='111' then y:='1';
aa:=aa+y;
i:=i+3;
end;
writeln('Декодированное сообщение: '); writeln(aa);
{=== ПОДСЧЕТ ЧИСЛА ОШИБОК ===}
For i:=1 to length(aa) do
begin
x1:=copy(aa1,i,1);
x:=copy(aa,i,1);
If x1<>x then k:=k+1;
end; k:=k/length(aa);
writeln('Относительное количество ошибок: ',k);
readln;
END.
Задача 13.4.
Имеется сообщение 01101 ... 01. Напишите программу, которая разбивает
его на кадры по 7 бит и добавляет восьмой бит четности.
Программа ПР - 13.4 содержит цикл, в котором вырезаются по 7 бит и
определяется количество в них единиц. Если число единиц нечетно, то
добавляется восьмой бит четности 1, а если четно, -- то 1. Результат выводится
на экран, затем в сообщение добавляются ошибки, -- случайным образом
инвертируются некоторые биты.
153
uses crt;
{ ПР - 13.4 }
var s,s1,a,a1,b,b1,p,f: string;
i,i1,j,j1,k,k1,q,q1,n,x,x1: integer; w: real;
BEGIN
clrscr; n:=49; s1:='';
s:='001010010111011000101010101001010110010010';
writeln('Исходное сообщение');
writeln(s); k:=round(length(s)/7);
writeln('Сообщение с битом четности');
For i:=1 to k do
begin
a:=copy(s,7*i-6,7); q:=round(length(a)/7);
For j:=1 to q do
begin
x:=0; b:=copy(a,j-1,1);
If b='1' then x:=x+1;
end;
If (x mod 2)=0 then a:=a+'0' else a:=a+'1';
write(a); s1:=s1+a; f:=s1;
end;
writeln; randomize;
For i:=1 to length(f) do
begin
w:=random(100)/100;
If (w<0.1) then
If s1[i]='1' then s1[i]:='0' else s1[i]:='1';
end;
writeln('Сообщение с ошибкой'); writeln(s1); readln;
END.
14. МАШИНА ПОСТА И ТЬЮРИНГА
Задача 14.1.
Машина Поста состоит из ленты, разбитой на ячейки, и каретки, которая
может считывать содержимое обозреваемой ячейки, стирать метки и ставить
метки. Создайте компьютерную модель машины Поста, вычитающей два
числа.
Алгоритм вычитания целых чисел для машины Поста приведен ниже. В первых
двух строчках указывается положение каретки и состояние ленты, на которой в
унарной системе счисления записаны два числа (в данном случае 6 и 4). В
результате исполнения программы на ленте останется число 2 в унарной
системе счисления.
154
7
-- координата каретки
VVVVVV-VVVV------------------------лента
1 сместить влево, команда 2
2 если пусто -- команда 1, если метка -- команда 3
3 удалить метку, команда 4
4 сместить вправо, команда 5
5 если пусто -- команда 4, если метка -- команда 6
6 удалить метку, команда 7
7 сместить вправо, команда 8
8 если пусто -- команда 9, если метка -- команда 1
9 остановить МП.
Используется программа ПР - 14.1, результат -- на рис. 14.1.
Uses crt, dos;
const N=35; t=100;
Var z,lenta: string; a, kom : array [1..N] of
string;
k, kk : array [1..N] of integer;
x, p, i, ii : integer; Label m1, m2;
Procedure Programma;
Begin x:=7; {Программа МП: вычитание двух чисел}
lenta:='VVVVVV-VV----------------------------------------------';
kom[1]:='left'; k[1]:=2;
kom[2]:='if';
k[2]:=1; kk[2]:=3;
kom[3]:='erase'; k[3]:=4;
kom[4]:='right'; k[4]:=5;
kom[5]:='if';
k[5]:=4; kk[5]:=6;
kom[6]:='erase'; k[6]:=7;
kom[7]:='right'; k[7]:=8;
kom[8]:='if';
k[8]:=9; kk[8]:=1;
kom[9]:='stop'; k[9]:=0;
end;
Procedure Pechat;
begin writeln; p:=p+1; For i:=1 to N do write(a[i],'
');
writeln('| ',p,' |');
For i:=1 to x-1 do write('--'); write('M');
delay(200*t); Sound(1000); delay(200*t); Nosound;
end;
BEGIN clrscr; Programma;
For i:=1 to N do begin a[i]:=copy(lenta,i,1);
end;
Pechat; ii:=1; m2: If Keypressed then goto m1;
If kom[ii]='stop' then goto m1;
If kom[ii]='left' then begin x:=x-1; Pechat;
ii:=k[ii]; goto m2;
155
end;
If kom[ii]='right' then begin x:=x+1; Pechat;
ii:=k[ii]; goto m2;
end;
If kom[ii]='erase' then begin a[x]:='-'; Pechat;
ii:=k[ii]; goto m2;
end;
If kom[ii]='metka' then begin a[x]:='V'; Pechat;
ii:=k[ii]; goto m2;
end;
If kom[ii]='if' then begin z:=a[x];
If z='-' then ii:=k[ii] else ii:=kk[ii]; goto m2;
end;
writeln; writeln('ОШИБКА В СТРОКЕ ', ii);
m1: writeln; writeln('КОНЕЦ РАБОТЫ');
Repeat until KeyPressed;
END.
Вычитание 6 - 2 = 4
V V V V V V - V V - - ------------M
V V V V V V - V V - - ----------M
V V V V V - - V V - - ----------M
V V V V V - - V V - - ------------M
V V V V V - - V V - - --------------M
V V V V V - - - V - - --------------M
V V V V V - - - V - - ----------------M
V V V V V - - - V - - --------------M
V V V V V - - - V - - ------------M
V V V V V - - - V - - ----------M
V V V V V - - - V - - --------M
V V V V - - - - V - - --------M
V V V V - - - - V - - ----------M
V V V V - - - - V - - ------------M
- - - - - - - - - - - - - - - - - | 1 |
- - - - - - - - - - - - - - - - - | 2 |
- - - - - - - - - - - - - - - - - | 3 |
- - - - - - - - - - - - - - - - - | 4 |
- - - - - - - - - - - - - - - - - | 5 |
- - - - - - - - - - - - - - - - - | 6 |
- - - - - - - - - - - - - - - - - | 7 |
- - - - - - - - - - - - - - - - - | 8 |
- - - - - - - - - - - - - - - - - | 9 |
- - - - - - - - - - - - - - - - - | 10 |
- - - - - - - - - - - - - - - - - | 11 |
- - - - - - - - - - - - - - - - - | 12 |
- - - - - - - - - - - - - - - - - | 13 |
- - - - - - - - - - - - - - - - - | 14 |
156
V V V V - - - - V --------------M
V V V V - - - - V ----------------M
V V V V - - - - - ----------------M
V V V V - - - - - ------------------M
КОНЕЦ РАБОТЫ
- - - - - - - - - - - - - - - - - - - | 15 |
- - - - - - - - - - - - - - - - - - - | 16 |
- - - - - - - - - - - - - - - - - - - | 17 |
- - - - - - - - - - - - - - - - - - - | 18 |
Рис. 14.1. Вычитание целых чисел.
Задача 14.2.
Напишите компьютерную программу, моделирующую машину Поста,
которая увеличивает целое число на 2.
Алгоритм увеличения целого числа на 2 представлен ниже:
3
-- координата каретки
VVVVVVV----------------------------- лента
1 сместить вправо, команда 2
2 если пусто - команда 3, если метка - команда 1
3 поставить метку, команда 4
4 сместить вправо, команда 5
5 поставить метку, команда 6
6 остановить МП.
Для реализации этого алгоритма в процедуру Programma программы ПР - 14.1
необходимо вставить следующий код:
x:=3;
{координата головки}
lenta:='VVVVVVV------------------------------------';
kom[1]:='right'; k[1]:=2;
kom[2]:='if';
k[2]:=3; kk[2]:=1;
kom[3]:='metka'; k[3]:=4;
kom[4]:='right'; k[4]:=5;
kom[5]:='metka'; k[5]:=6;
kom[6]:='stop'; k[6]:=0;
Результат работы программы -- на рис. 14.3.
Сложение 7 + 2 = 9
V V V V V V V - - - - - - - - - - - - - - - - - - - - - - | 1 |
----M
157
V V V V V V V - ------M
V V V V V V V - --------M
V V V V V V V - ----------M
V V V V V V V - ------------M
V V V V V V V - --------------M
V V V V V V V V --------------M
V V V V V V V V ----------------M
V V V V V V V V V
----------------M
КОНЕЦ РАБОТЫ
- - - - - - - - - - - - - - - - - - - - | 2 |
- - - - - - - - - - - - - - - - - - - - | 3 |
- - - - - - - - - - - - - - - - - - - - | 4 |
- - - - - - - - - - - - - - - - - - - - | 5 |
- - - - - - - - - - - - - - - - - - - - | 6 |
- - - - - - - - - - - - - - - - - - - - | 7 |
- - - - - - - - - - - - - - - - - - - - | 8 |
- - - - - - - - - - - - - - - - - - - - | 9 |
Рис. 14.2. Увеличение числа на 2.
Задача 14.3.
Напишите компьютерную программу, моделирующую машину Поста,
которая уменьшает целое число на 2.
Пусть на ленте машины Поста записано число 6, каретка находится напротив
левой ячейки (координата x=1). Для моделирования вычитания из любого
целого числа числа 2 в процедуру Programma программы ПР-14.1 следует
вставить следующий код:
x:=1; lenta:='VVVVVV-------------------------------';
kom[1]:='right'; k[1]:=2;
kom[2]:='if';
k[2]:=3; kk[2]:=1;
kom[3]:='left'; k[3]:=4;
kom[4]:='erase'; k[4]:=5;
kom[5]:='left'; k[5]:=6;
kom[6]:='erase'; k[6]:=7;
kom[7]:='stop';
Результат работы программы -- на рис. 14.3.
Вычитание 6 - 2 = 4
V V V V V V - - - - - - - - - - - - - - - - - - - - - - - | 1 |
M
V V V V V V - - - - - - - - - - - - - - - - - - - - - - - | 2 |
158
--M
V V V V V V ----M
V V V V V V ------M
V V V V V V --------M
V V V V V V ----------M
V V V V V V ------------M
V V V V V V ----------M
V V V V V - ----------M
V V V V V - --------M
V V V V - - --------M
КОНЕЦ РАБОТЫ
- - - - - - - - - - - - - - - - - - - - - - | 3 |
- - - - - - - - - - - - - - - - - - - - - - | 4 |
- - - - - - - - - - - - - - - - - - - - - - | 5 |
- - - - - - - - - - - - - - - - - - - - - - | 6 |
- - - - - - - - - - - - - - - - - - - - - - | 7 |
- - - - - - - - - - - - - - - - - - - - - - | 8 |
- - - - - - - - - - - - - - - - - - - - - - | 9 |
- - - - - - - - - - - - - - - - - - - - - - | 10 |
- - - - - - - - - - - - - - - - - - - - - - | 11 |
Рис. 14.3. Уменьшение целого числа на 2.
Задача 14.4.
Напишите компьютерную программу, моделирующую машину Поста,
которая складывает два целых числа.
Программа сложения целых чисел на машине Поста выглядит так:
5
-- координата каретки
VVVV-VVV------------------------------------- лента
1 поставить метку, команда 2
2 сместить вправо, команда 3
3 если пусто -- команда 4, если метка -- команда 2
4 сместить влево, команда 5
5 удалить метку, команда 6
6 остановить МП.
В программу ПР - 14.1 следует вставить код:
x:=5;
{сложение двух чисел}
lenta:='VVVV-VVV------------------------------------';
komand[1]:='metka'; k[1]:=2;
komand[2]:='right'; k[2]:=3;
159
komand[3]:='if';
komand[4]:='left';
komand[5]:='erase';
komand[6]:='stop';
k[3]:=4; kk[3]:=2;
k[4]:=5;
k[5]:=6;
k[6]:=0;
Результат работы программы -- на рис. 14.4.
Сложение 4 + 3 = 7
V V V V - V V V - - --------M
V V V V V V V V - - --------M
V V V V V V V V - - ----------M
V V V V V V V V - - ------------M
V V V V V V V V - - --------------M
V V V V V V V V - - ----------------M
V V V V V V V V - - --------------M
V V V V V V V - - - --------------M
КОНЕЦ РАБОТЫ
- - - - - - - - - - - - - - - - - - | 1 |
- - - - - - - - - - - - - - - - - - | 2 |
- - - - - - - - - - - - - - - - - - | 3 |
- - - - - - - - - - - - - - - - - - | 4 |
- - - - - - - - - - - - - - - - - - | 5 |
- - - - - - - - - - - - - - - - - - | 6 |
- - - - - - - - - - - - - - - - - - | 7 |
- - - - - - - - - - - - - - - - - - | 8 |
Рис. 14.4. Сложение двух целых чисел.
Задача 14.5.
Напишите компьютерную программу, моделирующую машину Поста,
которая умножает целое число на 2.
x:=2; {Умножение числа на 2}
lenta:='-VVV-------------------------------------';
kom[1]:='right'; k[1]:=2;
kom[2]:='if';
k[2]:=3; kk[2]:=1;
kom[3]:='left';
k[3]:=4;
kom[4]:='erase'; k[4]:=5;
kom[5]:='right'; k[5]:=6;
kom[6]:='metka'; k[6]:=7;
kom[7]:='right'; k[7]:=8;
kom[8]:='metka'; k[8]:=9;
kom[9]:='left'; k[9]:=10;
kom[10]:='if';
k[10]:=11; kk[10]:=9;
160
kom[11]:='left';
kom[12]:='if';
kom[13]:='erase';
kom[14]:='left';
kom[15]:='if';
kom[16]:='right';
kom[17]:='if';
kom[18]:='right';
kom[19]:='if';
kom[20]:='right';
kom[21]:='if';
kom[22]:='right';
kom[23]:='if';
kom[24]:='metka';
kom[25]:='right';
kom[26]:='metka';
kom[27]:='stop';
k[11]:=12;
k[12]:=11; kk[12]:=13;
k[13]:=14;
k[14]:=15;
k[15]:=20; kk[15]:=16;
k[16]:=17;
k[17]:=16; kk[17]:=18;
k[18]:=19;
k[19]:=6; kk[19]:=18;
k[20]:=21;
k[21]:=20; kk[21]:=22;
k[22]:=23;
k[23]:=24; kk[23]:=22;
k[24]:=25;
k[25]:=26;
k[26]:=27;
k[28]:=0;
Результат решения представлен на рис. 14.5. Возможен другой способ решения:
x:=9; lenta:='-VVVVV---------------------------';
kom[1]:='metka'; k[1]:=2;
kom[2]:='right'; k[2]:=3;
kom[3]:='metka'; k[3]:=4;
kom[4]:='left'; k[4]:=5;
kom[5]:='if';
k[5]:=6; kk[5]:=4;
kom[6]:='left'; k[6]:=7;
kom[7]:='if';
k[7]:=6; kk[7]:=8;
kom[8]:='erase'; k[8]:=9;
kom[9]:='left'; k[9]:=10;
kom[10]:='if'; k[10]:=15; kk[10]:=11;
kom[11]:='right'; k[11]:=12;
kom[12]:='if'; k[12]:=11; kk[12]:=13;
kom[13]:='right'; k[13]:=14;
kom[14]:='if'; k[14]:=1; kk[14]:=13;
kom[15]:='stop'; k[15]:=0;
Умножение 3 * 2 = 6
- V V V - - - - - - - --M
- V V V - - - - - - - ----M
- V V V - - - - - - - ------M
- V V V - - - - - - - --------M
- V V V - - - - - - - ------M
- - - - - - - - - - - - - - - - - | 1 |
- - - - - - - - - - - - - - - - - | 2 |
- - - - - - - - - - - - - - - - - | 3 |
- - - - - - - - - - - - - - - - - | 4 |
- - - - - - - - - - - - - - - - - | 5 |
161
- V V - - - - ------M
- V V - - - - --------M
- V V - V - - --------M
- V V - V - - ----------M
- V V - V V - ----------M
- V V - V V - --------M
- V V - V V - ------M
- V V - V V - ----M
- V - - V V - ----M
- V - - V V - --M
- V - - V V - ----M
- V - - V V - ------M
- V - - V V - --------M
- V - - V V - ----------M
- V - - V V - ------------M
- V - - V V V ------------M
- V - - V V V --------------M
- V - - V V V V
--------------M
- V - - V V V V
------------M
- V - - V V V V
----------M
- V - - V V V V
--------M
- V - - V V V V
------M
- V - - V V V V
----M
- V - - V V V V
--M
- - - - - - - - - - - - - - - - - - - - - | 6 |
- - - - - - - - - - - - - - - - - - - - - | 7 |
- - - - - - - - - - - - - - - - - - - - - | 8 |
- - - - - - - - - - - - - - - - - - - - - | 9 |
- - - - - - - - - - - - - - - - - - - - - | 10 |
- - - - - - - - - - - - - - - - - - - - - | 11 |
- - - - - - - - - - - - - - - - - - - - - | 12 |
- - - - - - - - - - - - - - - - - - - - - | 13 |
- - - - - - - - - - - - - - - - - - - - - | 14 |
- - - - - - - - - - - - - - - - - - - - - | 15 |
- - - - - - - - - - - - - - - - - - - - - | 16 |
- - - - - - - - - - - - - - - - - - - - - | 17 |
- - - - - - - - - - - - - - - - - - - - - | 18 |
- - - - - - - - - - - - - - - - - - - - - | 19 |
- - - - - - - - - - - - - - - - - - - - - | 20 |
- - - - - - - - - - - - - - - - - - - - - | 21 |
- - - - - - - - - - - - - - - - - - - - - | 22 |
- - - - - - - - - - - - - - - - - - - - - | 23 |
- - - - - - - - - - - - - - - - - - - - - | 24 |
- - - - - - - - - - - - - - - - - - - - - | 25 |
- - - - - - - - - - - - - - - - - - - - - | 26 |
- - - - - - - - - - - - - - - - - - - - - | 27 |
- - - - - - - - - - - - - - - - - - - - - | 28 |
- - - - - - - - - - - - - - - - - - - - - | 29 |
162
- - - - V V V V - --M
- - - - V V V V - M
- - - - V V V V - --M
- - - - V V V V - ----M
- - - - V V V V - ------M
- - - - V V V V - --------M
- - - - V V V V - ----------M
- - - - V V V V - ------------M
- - - - V V V V - --------------M
- - - - V V V V - ----------------M
- - - - V V V V V ----------------M
- - - - V V V V V ------------------M
- - - - V V V V V V
------------------M
КОНЕЦ РАБОТЫ
- - - - - - - - - - - - - - - - - - - | 30 |
- - - - - - - - - - - - - - - - - - - | 31 |
- - - - - - - - - - - - - - - - - - - | 32 |
- - - - - - - - - - - - - - - - - - - | 33 |
- - - - - - - - - - - - - - - - - - - | 34 |
- - - - - - - - - - - - - - - - - - - | 35 |
- - - - - - - - - - - - - - - - - - - | 36 |
- - - - - - - - - - - - - - - - - - - | 37 |
- - - - - - - - - - - - - - - - - - - | 38 |
- - - - - - - - - - - - - - - - - - - | 39 |
- - - - - - - - - - - - - - - - - - - | 40 |
- - - - - - - - - - - - - - - - - - - | 41 |
- - - - - - - - - - - - - - - - - - - | 42 |
Рис. 14.5. Умножение целого числа на 2.
Задача 14.6.
Машина Тьюринга состоит из бесконечной ленты и головки, которая
перемещается относительно ленты, стирает символы, ставит новые символы.
Напишите программу, моделирующую работу машины Тьюринга, которое
увеличивает заданное число на 2.
Используется программа ПР - 14.6. Состояние ленты машины Тьюринга
записывается в массиве:
c=('_','1','1','1','1','1','1',
'_','_','_','_','_','_','_','_');
Положение головки определяется переменной m, исходное состояние машины
Тьюринга -- переменной q:
m:=2;
{ положение головки }
163
q:='1';
Программа для машины Тьюринга записывается в виде последовательности
команд, представленных в общепринятом формате:
"(Состояние q1) (Читаю символ s1) ==>
(Новое состояние q2) (Напечатать символ s1)
(Сместить головку вправо (R), влево (L) или
остановиться (S))"
Программа для машины Тьюринга, увеличивающая целое число на 2 состоит из
3 команд:
kom[1]:='11>11R';
kom[2]:='1_>21R';
kom[3]:='2_>21S';
Результат ее использования -- на рис. 14.5.
Uses crt, graph;
{ ПР - 14.6 }
Type c=array[1..15] of string;
Const a : c=('_','1','1','1','1','1',
'1','_','_','_','_','_','_','_','_'); N=50;
Var i,k,m,s,flag : integer;
x1,x2,x4,x5,x6,q: string;
kom : array[1..N] of string;
Label m1;
BEGIN
clrscr; m:=2; { положение головки }
q:='1';
{ Программа МТ: увеличение числа на 2
}
kom[1]:='11>11R';
kom[2]:='1_>21R';
kom[3]:='2_>21S';
Repeat
flag:=0; s:=s+1;
For i:=1 to N do
begin
x1:=copy(kom[i],1,1);
x2:=copy(kom[i],2,1);
x4:=copy(kom[i],4,1);
x5:=copy(kom[i],5,1);
x6:=copy(kom[i],6,1);
If (flag=0)and(x1=q)and(x2=a[m]) then
begin
q:=x4; a[m]:=x5;
If x6='R' then m:=m+1;
If x6='L' then m:=m-1;
164
If x6='S' then goto m1; flag:=1;
end;
end;
m1:
k:=k+1;
For i:=1 to 15 do write(a[i],' ');
writeln('
',q,'
k=',k);
delay(5000); sound(1000); Delay(5000); Nosound;
For i:=1 to m-1 do write('=='); write('|');
writeln;
until x6='S'; Readkey;
END.
_ 1 1 1 1 1 1 _ _
====|
_ 1 1 1 1 1 1 _ _
======|
_ 1 1 1 1 1 1 _ _
========|
_ 1 1 1 1 1 1 _ _
==========|
_ 1 1 1 1 1 1 _ _
============|
_ 1 1 1 1 1 1 _ _
==============|
_ 1 1 1 1 1 1 1 _
================|
_ 1 1 1 1 1 1 1 1
================|
q=1
k=1
q=1
k=2
q=1
k=3
q=1
k=4
q=1
k=5
q=1
k=6
q=2
k=7
q=2
k=8
Рис. 14.6. Увеличение целого числа на 2.
Задача 14.7.
Напишите программу для МТ, складывающую два целых числа, заданных
набором единиц.
Пусть начальное состояние ленты машины Тьюринга: _11111_1111__ , головка
находится напротив левой единицы. МТ находится в состоянии 1. Программа
выглядит так:
q
"1"
"_"
165
1
2_R
2
21R
31R
3
31R
4_L
4
1_S
В программу ПР - 14.6 следует вставить код:
c=('_','1','1','1','1','1','_','1','1','1','1',
'_','_','_','_');
m:=2; q:='1';
kom[1]:='11>11R';
kom[2]:='1_>21R';
kom[3]:='21>21R';
kom[4]:='2_>3_L';
kom[5]:='31>3_S';
Результат работы программы представлен на рис. 14.6.
_ 1 1 1 1 1 _ 1 1 1 1 _
====|
_ 1 1 1 1 1 _ 1 1 1 1 _
======|
_ 1 1 1 1 1 _ 1 1 1 1 _
========|
_ 1 1 1 1 1 _ 1 1 1 1 _
==========|
_ 1 1 1 1 1 _ 1 1 1 1 _
============|
_ 1 1 1 1 1 1 1 1 1 1 _
==============|
_ 1 1 1 1 1 1 1 1 1 1 _
================|
_ 1 1 1 1 1 1 1 1 1 1 _
==================|
_ 1 1 1 1 1 1 1 1 1 1 _
====================|
_ 1 1 1 1 1 1 1 1 1 1 _
======================|
_ 1 1 1 1 1 1 1 1 1 1 _
====================|
_ 1 1 1 1 1 1 1 1 1 _ _
====================|
_ _ _
q=1
k=1
_ _ _
q=1
k=2
_ _ _
q=1
k=3
_ _ _
q=1
k=4
_ _ _
q=1
k=5
_ _ _
q=2
k=6
_ _ _
q=2
k=7
_ _ _
q=2
k=8
_ _ _
q=2
k=9
_ _ _
q=2
k=10
_ _ _
q=3
k=11
_ _ _
q=3
k=12
166
Рис. 14.7. Сложение целых чисел.
Задача 14.8.
На ленте МТ -- конечный набор единиц: _11111__. Напишите программу,
которая ставит звездочки вместо первой и последней единицы, остальные
стирает.
Пусть машина Тьюринга находится в состоянии 1. В компьютерную программу
ПР-2 необходимо вставить следующий код:
c=('_','1','1','1','1','1','1','1','1',
'1','1','_','_','_','_');
m:=1; q:='1';
kom[1]:='1_>1_R';
kom[2]:='2_>2_L';
kom[3]:='3_>3_S';
kom[4]:='11>21R';
kom[5]:='21>2*R';
kom[6]:='31>3*L';
kom[7]:='2*>3*L';
kom[8]:='3*>3_L';
_ 1 1 1 1 1 1 1 1 1 1
==|
_ 1 1 1 1 1 1 1 1 1 1
====|
_ 1 * 1 1 1 1 1 1 1 1
======|
_ 1 * * 1 1 1 1 1 1 1
========|
_ 1 * * * 1 1 1 1 1 1
==========|
_ 1 * * * * 1 1 1 1 1
============|
_ 1 * * * * * 1 1 1 1
==============|
_ 1 * * * * * * 1 1 1
================|
_ 1 * * * * * * * 1 1
==================|
_ 1 * * * * * * * * 1
====================|
_ 1 * * * * * * * * *
_ _ _ _
q=1
k=1
_ _ _ _
q=2
k=2
_ _ _ _
q=2
k=3
_ _ _ _
q=2
k=4
_ _ _ _
q=2
k=5
_ _ _ _
q=2
k=6
_ _ _ _
q=2
k=7
_ _ _ _
q=2
k=8
_ _ _ _
q=2
k=9
_ _ _ _
q=2
k=10
_ _ _ _
q=2
k=11
167
======================|
_ 1 * * * * * * * * * _
====================|
_ 1 * * * * * * * * * _
==================|
_ 1 * * * * * * * _ * _
================|
_ 1 * * * * * * _ _ * _
==============|
_ 1 * * * * * _ _ _ * _
============|
_ 1 * * * * _ _ _ _ * _
==========|
_ 1 * * * _ _ _ _ _ * _
========|
_ 1 * * _ _ _ _ _ _ * _
======|
_ 1 * _ _ _ _ _ _ _ * _
====|
_ 1 _ _ _ _ _ _ _ _ * _
==|
_ * _ _ _ _ _ _ _ _ * _
|
_ * _ _ _ _ _ _ _ _ * _
|
_ _ _
q=2
k=12
_ _ _
q=3
k=13
_ _ _
q=3
k=14
_ _ _
q=3
k=15
_ _ _
q=3
k=16
_ _ _
q=3
k=17
_ _ _
q=3
k=18
_ _ _
q=3
k=19
_ _ _
q=3
k=20
_ _ _
q=3
k=21
_ _ _
q=3
k=22
_ _ _
q=3
k=23
Рис. 14.8. Замена единиц на звездочки и пробелы.
Задача 14.9.
На ленте МТ -- конечный набор единиц: _111111__. Напишите программу,
которая заменяет единицы звездочками. Головка -- левее первой единицы.
Программа для машины Тьюринга имеет вид:
q
"_"
"1"
"*"
1
1_R
3*R
2
2_L
2*R
3*L
3
3_S
2*R
3*L
168
Для решения этой задачи в программу ПР - 14.6 следует вставить код:
c=('_','_','1','1','1','1','1','1',
'1','1','1','1','_','_','_');
m:=1; q:='1';
kom[1]:='1_>1_R';
kom[2]:='2_>2_L';
kom[3]:='3_>3_S';
kom[4]:='11>3*R';
kom[5]:='21>2*R';
kom[6]:='31>2*R';
kom[7]:='2*>3*L';
kom[8]:='3*>3*L';
Результат работы программы представлен на рис. 14.9.
_ _ 1 1 1 1 1 1 1 1 1 1 _
==|
_ _ 1 1 1 1 1 1 1 1 1 1 _
====|
_ _ * 1 1 1 1 1 1 1 1 1 _
======|
_ _ * * 1 1 1 1 1 1 1 1 _
========|
_ _ * * * 1 1 1 1 1 1 1 _
==========|
_ _ * * * * 1 1 1 1 1 1 _
============|
_ _ * * * * * 1 1 1 1 1 _
==============|
_ _ * * * * * * 1 1 1 1 _
================|
_ _ * * * * * * * 1 1 1 _
==================|
_ _ * * * * * * * * 1 1 _
====================|
_ _ * * * * * * * * * 1 _
======================|
_ _ * * * * * * * * * * _
========================|
_ _ * * * * * * * * * * _
======================|
_ _ * * * * * * * * * * _
====================|
_ _ * * * * * * * * * * _
==================|
_ _
q=1
k=1
_ _
q=1
k=2
_ _
q=3
k=3
_ _
q=2
k=4
_ _
q=2
k=5
_ _
q=2
k=6
_ _
q=2
k=7
_ _
q=2
k=8
_ _
q=2
k=9
_ _
q=2
k=10
_ _
q=2
k=11
_ _
q=2
k=12
_ _
q=2
k=13
_ _
q=3
k=14
_ _
q=3
k=15
169
_ _ * * * * * * *
================|
_ _ * * * * * * *
==============|
_ _ * * * * * * *
============|
_ _ * * * * * * *
==========|
_ _ * * * * * * *
========|
_ _ * * * * * * *
======|
_ _ * * * * * * *
====|
_ _ * * * * * * *
==|
_ _ * * * * * * *
==|
* * * _ _ _
q=3
k=16
* * * _ _ _
q=3
k=17
* * * _ _ _
q=3
k=18
* * * _ _ _
q=3
k=19
* * * _ _ _
q=3
k=20
* * * _ _ _
q=3
k=21
* * * _ _ _
q=3
k=22
* * * _ _ _
q=3
k=23
* * * _ _ _
q=3
k=24
Рис. 14.9. Замена единиц на звездочки.
Задача 14.10.
На ленте МТ -- последовательность _ABBAABAB____. Головка МТ -напротив левого символа. Напишите программу, чтобы МТ группировала
символы "A" в правой части строки, а вместо них ставила звездочки.
Программа для машины Тьюринга выглядит так:
q
"_"
"A"
"B"
"*"
"|"
1
1_R
2*R
1BR
1*R
1|S
2
3|R
2AR
2BR
2*R
3|R
3
4AL
3AR
4
1_R
4AL
4BL
4*L
4|L
В компьютерную программу ПР - 14.6 следует вставить код:
c=('_','A','B','B','A','A','B','A','B','_',
'_','_','_','_','_');
m:=1; q:= '1';
170
kom[1]:='1_>1_R';
kom[2]:='2_>3|R';
kom[3]:='3_>4AL';
kom[4]:= '4_>1_R';
kom[5]:='1A>2*R';
kom[6]:='2A>2AR';
kom[7]:='3A>3AR';
kom[8]:='4A>4AL';
kom[9]:='1B>1BR';
kom[10]:='2B>2BR';
kom[11]:='4B>4BL';
kom[12]:='1*>1*R';
kom[13]:='2*>2*R';
kom[14]:='4*>4*L';
kom[15]:='1|>1|S';
kom[16]:='2|>3|R';
kom[17]:='4|>4|L';
_ A B B A A B A B _ _
==|
_ * B B A A B A B _ _
====|
_ * B B A A B A B _ _
======|
_ * B B A A B A B _ _
========|
_ * B B A A B A B _ _
==========|
_ * B B A A B A B _ _
============|
_ * B B A A B A B _ _
==============|
_ * B B A A B A B _ _
================|
_ * B B A A B A B _ _
==================|
_ * B B A A B A B | _
====================|
_ * B B A A B A B | A
==================|
_ * B B A A B A B | A
================|
. . . . . . . . . . .
_ * B B * * B * B | A
================|
_ * B B * * B * B | A
==================|
_ _ _ _
q=1
k=1
_ _ _ _
q=2
k=2
_ _ _ _
q=2
k=3
_ _ _ _
q=2
k=4
_ _ _ _
q=2
k=5
_ _ _ _
q=2
k=6
_ _ _ _
q=2
k=7
_ _ _ _
q=2
k=8
_ _ _ _
q=2
k=9
_ _ _ _
q=3
k=10
_ _ _ _
q=4
k=11
_ _ _ _
q=4
k=12
. . . .
A A A _
q=1
k=100
A A A _
q=1
k=101
171
_ * B B * * B * B | A A A A _
==================|
q=1
k=102
Рис. 14.10. Группировка символов A.
Задача 14.11.
На ленте МТ -- число в десятичной системе счисления, например, 134999.
Напишите программу, увеличивающую это число на 1.
Программа для машины Тьюринга представлена в таблице:
q
"_"
"1"
"2"
"3"
"4"
"5"
"6"
"7"
"8"
"9"
"0"
1
2_L
11R
12R
13R
14R
15R
16R
17R
18R
19R
10R
2
21S
22S
23S
24S
25S
26S
27S
28S
29S
20L
21S
В программу ПР - 14.6 следует вставить код:
c=('_','1','3','4','9','9','9','_','_','_','_',
'_','_','_','_');
m:=2; q:= '1';
kom[1]:='1_>2_L';
kom[2]:='2_>2_S';
kom[3]:='11>11R';
kom[4]:='21>22S';
kom[5]:='12>12R';
kom[6]:='22>23S';
kom[7]:='13>13R';
kom[8]:='23>24S';
kom[9]:='14>14R';
kom[10]:='24>25S';
kom[11]:='15>15R';
kom[12]:='25>26S';
kom[13]:='16>16R';
kom[14]:='26>27S';
kom[15]:='17>17R';
kom[16]:='27>28S';
kom[17]:='18>18R';
kom[18]:='28>29S';
kom[19]:='19>19R';
kom[20]:='29>20L';
172
Результат работы программы -- на рис. 14.11.
_ 1 3 4 9 9 9 _
====|
_ 1 3 4 9 9 9 _
======|
_ 1 3 4 9 9 9 _
========|
_ 1 3 4 9 9 9 _
==========|
_ 1 3 4 9 9 9 _
============|
_ 1 3 4 9 9 9 _
==============|
_ 1 3 4 9 9 9 _
============|
_ 1 3 4 9 9 0 _
==========|
_ 1 3 4 9 0 0 _
========|
_ 1 3 4 0 0 0 _
======|
_ 1 3 5 0 0 0 _
======|
_ _ _ _ _ _ _
q=1
k=1
_ _ _ _ _ _ _
q=1
k=2
_ _ _ _ _ _ _
q=1
k=3
_ _ _ _ _ _ _
q=1
k=4
_ _ _ _ _ _ _
q=1
k=5
_ _ _ _ _ _ _
q=1
k=6
_ _ _ _ _ _ _
q=2
k=7
_ _ _ _ _ _ _
q=2
k=8
_ _ _ _ _ _ _
q=2
k=9
_ _ _ _ _ _ _
q=2
k=10
_ _ _ _ _ _ _
q=2
k=11
Рис. 14.11. Увеличение числа на 1.
15. АЛГОРИФМЫ МАРКОВА
Задача 15.1.
Напишите программу, позволяющую автоматически реализовать
нормальный алгоритм Маркова, обрабатывающий входное слово с помощью
системы подстановок. Например, дано слово из алфавита {a,b,c,d}, следует
расположить буквы в алфавитном порядке.
Нормальная система подстановок осуществляется так: сначала выполняется
первая подстановка (x[1] заменяется на y[1]), слово переписывается. Затем --снова первая подстановка; если невозможно --- вторая; если вторая не
проходит, --- третья. Слово переписывается. Снова первая подстановка, если
невозможно --- вторая; если невозможно --- третья. Слово переписывается.
Система подстановок, позволяющая расположить буквы в алфавитном порядка,
представлена ниже:
173
slovo:='dabadbcadcbd';
----------------------x[1]:='ba'; y[1]:='ab';
x[2]:='ca'; y[2]:='ac';
x[3]:='da'; y[3]:='ad';
x[4]:='cb'; y[4]:='bc';
x[5]:='db'; y[5]:='bd';
x[6]:='dc'; y[6]:='cd';
Для атоматического выполнения нормальный алгоритм Маркова используется
программа ПР - 15.1. Результат работы пргограммы -- на рис. 15.1.
uses crt, graph;
{ ПР - 15.1
}
const Chislo_podstan=30; label m1;
var i,j,k,m,p,s,flag: integer; x1,x2,x4,x5,x6,q:
string;
x,y: array[1..100] of string; slovo, slovo1:
string;
Procedure Podstanovka(j:integer); label m;
begin flag:=0; i:=0;
Repeat inc(i);
If copy(slovo,i,length(x[j]))=x[j] then begin
flag:=1;
slovo1:=copy(slovo,1,i-1)+y[j]+copy(slovo,
i+length(x[j]),length(slovo)-i-length(x[j])+1);
slovo:=slovo1;
If (x[j]='')or(y[j]='') then flag:=0;
goto m; end;
until i>length(slovo); m:
If flag=1 then writeln(k,' ',slovo,' | подстановка
',j);
end;
BEGIN clrscr;
slovo:='dabadbcadcbd';
writeln(slovo);
{====== Система подстановок =======}
x[1]:='ba';
y[1]:='ab';
x[2]:='ca'; y[2]:='ac';
x[3]:='da';
y[3]:='ad';
x[4]:='cb';
y[4]:='bc';
x[5]:='db'; y[5]:='bd';
x[6]:='dc'; y[6]:='cd';
m1: k:=k+1; delay(5000);
For p:=1 to Chislo_podstan do begin
Podstanovka(p); If flag=1 then goto m1; end;
Readkey;
END.
174
1 daabdbcadcbd | подстановка 1
2 daabdbacdcbd | подстановка 2
3 daabdabcdcbd | подстановка 1
4 adabdabcdcbd | подстановка 3
5 aadbdabcdcbd | подстановка 3
6 aadbadbcdcbd | подстановка 3
7 aadabdbcdcbd | подстановка 1
8 aaadbdbcdcbd | подстановка 3
9 aaadbdbcdbcd | подстановка 4
10 aaabddbcdbcd | подстановка 5
11 aaabdbdcdbcd | подстановка 5
12 aaabbddcdbcd | подстановка 5
13 aaabbddcbdcd | подстановка 5
14 aaabbddbcdcd | подстановка 4
15 aaabbdbdcdcd | подстановка 5
16 aaabbbddcdcd | подстановка 5
17 aaabbbdcddcd | подстановка 6
18 aaabbbcdddcd | подстановка 6
19 aaabbbcddcdd | подстановка 6
20 aaabbbcdcddd | подстановка 6
21 aaabbbccdddd | подстановка 6
Рис. 15.1. Перестановка букв по алфавиту.
Задача 15.2.
Дана последовательность скобок. С помощью нормальной системы
подстановок Маркова определите правильность скобочной структуры.
Чтобы реализовать нормальную систему подстановок Маркова, в программу
ПР - 15.1 следует вставить код:
slovo:='()()(())(()())(())';
---------------------------x[1]:='**';
y[1]:='*';
x[2]:='()*'; y[2]:='*';
x[3]:='*()'; y[3]:='*';
x[4]:='(*)'; y[4]:='*';
x[5]:='()'; y[5]:='*';
Результат исполнения программы представлен на рис. 15.2.
1 *()(())(()())(()) | подстановка 5
2 *(())(()())(()) | подстановка 3
175
3 *(*)(()())(()) | подстановка 5
4 **(()())(()) | подстановка 4
5 *(()())(()) | подстановка 1
6 *(*())(()) | подстановка 5
7 *(*)(()) | подстановка 3
8 **(()) | подстановка 4
9 *(()) | подстановка 1
10 *(*) | подстановка 5
11 ** | подстановка 4
12 * | подстановка 1
Рис. 15.2. Определение правильности скобочной структуры.
Задача 15.3.
Напишите программу, автоматически реализующий нормальный алгоритм
Маркова, переводящий число из двоичной системы счисления в унарную.
Чтобы решить эту задачу, в программу ПР - 15.1 следует вставить код:
slovo:='10011';
------------------x[1]:='|0'; y[1]:='0||';
x[2]:='1'; y[2]:='0|';
x[3]:='0|'; y[3]:='|';
Результат решения задачи -- на рис. 15.3.
1 0|0011 | подстановка 2
2 00||011 | подстановка 1
3 00|0||11 | подстановка 1
4 000||||11 | подстановка 1
5 000||||0|1 | подстановка 2
6 000|||0|||1 | подстановка 1
7 000||0|||||1 | подстановка 1
8 000|0|||||||1 | подстановка 1
9 0000|||||||||1 | подстановка 1
10 0000|||||||||0| | подстановка 2
11 0000||||||||0||| | подстановка 1
12 0000|||||||0||||| | подстановка 1
13 0000||||||0||||||| | подстановка 1
14 0000|||||0||||||||| | подстановка 1
15 0000||||0||||||||||| | подстановка 1
16 0000|||0||||||||||||| | подстановка 1
17 0000||0||||||||||||||| | подстановка 1
176
18
19
20
21
22
23
24
0000|0||||||||||||||||| | подстановка 1
00000||||||||||||||||||| | подстановка 1
0000||||||||||||||||||| | подстановка 3
000||||||||||||||||||| | подстановка 3
00||||||||||||||||||| | подстановка 3
0||||||||||||||||||| | подстановка 3
||||||||||||||||||| | подстановка 3
Рис. 15.3. Перевод числа из двоичной системы в унарную.
Задача 15.4.
Напишите программу, автоматически реализующий нормальный алгоритм
Маркова, складывающий два числа.
В программу ПР - 15.1 следует вставить код:
slovo:='8eight+5five';
------------------------x[1]:='1one'; y[1]:='|';
x[2]:='2two'; y[2]:='||';
x[3]:='3three'; y[3]:='|||';
x[4]:='4four'; y[4]:='||||';
x[5]:='5five'; y[5]:='|||||';
x[6]:='6six'; y[6]:='||||||';
x[7]:='7seven'; y[7]:='|||||||';
x[8]:='8eight'; y[8]:='||||||||';
x[9]:='9nine'; y[9]:='|||||||||';
x[10]:='|+|'; y[10]:='||';
x[11]:='||||||||||'; y[11]:='10';
x[12]:='0|||||||||'; y[12]:='9';
x[13]:='0||||||||'; y[13]:='8';
x[14]:='0|||||||'; y[14]:='7';
x[15]:='0||||||'; y[15]:='6';
x[16]:='0|||||'; y[16]:='5';
x[17]:='0||||'; y[17]:='4';
x[18]:='0|||'; y[18]:='3';
x[19]:='0||'; y[19]:='2';
x[20]:='0|'; y[20]:='1';
x[21]:='|||||||||'; y[21]:='9';
x[22]:='||||||||'; y[22]:='8';
x[23]:='|||||||'; y[23]:='7';
x[24]:='||||||'; y[24]:='6';
x[25]:='|||||'; y[25]:='5';
x[26]:='||||'; y[26]:='4';
177
x[27]:='|||'; y[27]:='3';
x[28]:='||'; y[28]:='2';
x[29]:='|'; y[29]:='1';
Результат решения задачи -- на рис. 15.4.
slovo:='8eight+5five';
-------------------------------1 8eight+||||| | подстановка 5
2 ||||||||+||||| | подстановка 8
3 ||||||||||||| | подстановка 10
4 10||| | подстановка 11
5 13 | подстановка 18
Рис. 15.4. Сложение двух чисел.
Задача 15.5.
Напишите программу, автоматически реализующий нормальный алгоритм
Маркова, умножающий два числа.
В программу ПР - 15.1 следует вставить код:
slovo:='1111*111';
------------------x[1]:='*11'; y[1]:='A*1';
x[2]:='*1'; y[2]:='A';
x[3]:='1A'; y[3]:='A1B';
x[4]:='BA'; y[4]:='AB';
x[5]:='B1'; y[5]:='1B';
x[6]:='A1'; y[6]:='A';
x[7]:='AB'; y[7]:='B';
x[8]:='B'; y[8]:='1';
Результат работы программы - на рис. 15.5. Другой пример решения задачи:
slovo:='1111*111';
--------------------x[1]:='1*'; y[1]:='X';
x[2]:='_1'; y[2]:='1_Z';
x[3]:='Z1'; y[3]:='1Z';
x[4]:='1X'; y[4]:='X_';
x[5]:='X'; y[5]:='';
x[6]:='_'; y[6]:='';
x[7]:='Z'; y[7]:='1';
178
slovo:='1111*111';
-------------------------1 1111A*11 | подстановка 1
2 1111AA*1 | подстановка 1
3 1111AAA | подстановка 2
4 111A1BAA | подстановка 3
5 11A1B1BAA | подстановка 3
6 1A1B1B1BAA | подстановка 3
7 A1B1B1B1BAA | подстановка 3
8 A1B1B1B1ABA | подстановка 4
9 A1B1B1BA1BBA | подстановка 3
10 A1B1B1AB1BBA | подстановка 4
11 A1B1BA1BB1BBA | подстановка 3
12 A1B1AB1BB1BBA | подстановка 4
13 A1BA1BB1BB1BBA | подстановка 3
14 A1AB1BB1BB1BBA | подстановка 4
15 AA1BB1BB1BB1BBA | подстановка 3
16 AA1BB1BB1BB1BAB | подстановка 4
17 AA1BB1BB1BB1ABB | подстановка 4
18 AA1BB1BB1BBA1BBB | подстановка 3
...............................
56 1111BBBBBBBB | подстановка 8
57 11111BBBBBBB | подстановка 8
58 111111BBBBBB | подстановка 8
59 1111111BBBBB | подстановка 8
60 11111111BBBB | подстановка 8
61 111111111BBB | подстановка 8
62 1111111111BB | подстановка 8
63 11111111111B | подстановка 8
64 111111111111 | подстановка 8
Рис. 15.5. Умножение целых чисел.
Задача 15.6.
Имеется число в четверичной системе счисления. Предложите систему
нормальных подстановок,которая переводит это число в двоичную систему
счисления. Апробируйте решение на компьютере.
В программу ПР - 15.1 следует вставить код:
slovo:='*3021032';
----------------------x[1]:='*0'; y[1]:='00*';
x[2]:='*1'; y[2]:='01*';
179
x[3]:='*2';
x[4]:='*3';
x[5]:='*';
y[3]:='10*';
y[4]:='11*';
y[5]:=' ';
Задача 15.7.
Дано двоичное число. Предложите систему нормальных подстановок,
которая инвертирует все 0 и 1. Апробируйте решение на компьютере.
В программу ПР - 15.1 следует вставить код:
slovo:='*011010101';
---------------------x[1]:='*0'; y[1]:='1*';
x[2]:='*1'; y[2]:='0*';
x[3]:='*';
y[3]:=' ';
Задача 15.8.
Дано число в унарной системе счисления от 1 до 15. Предложите систему
нормальнух подстановок, которая представляет его как сумму степеней
числа 2. Апробируйте решение на компьютере.
В программу ПР - 15.1 следует вставить код:
slovo:='|||||||||||||_';
------------------------x[1]:='||||||||';
y[1]:='8+';
x[2]:='||||';
y[2]:='4+';
x[3]:='||';
y[3]:='2+';
x[4]:='|';
y[4]:='1+';
x[5]:='+_';
y[5]:=' ';
Задача 15.9.
Имеется слово 'BAB_BA_AA_BABB_ABA'. Создайте нормальный алгоритм
Маркова, который символы 'A' переносит влево, символы 'B' --- вправо, а
пробелы оставляет посередине. Промоделируйте на компьютере. (Ответ: 1)
'BA' => 'AB'; 2) 'B_' => '_B'; 3) '_A' => 'A_').
180
Задача 15.10.
Имеется слово 'abcbacbdacdb'. Создайте нормальный алгоритм Маркова,
который кодирует это слово. Промоделируйте на компьютере. (Ответ: 1) 'a'
=> '00-'; 2) 'b' => '01-'; 3) 'c' => '10-'; 4) 'd' => '11-'; 5) 'e' => '111-').
16. НЕЙРОСЕТИ И ПЕРСЕПТРОНЫ
Задача 16.1.
На базе формального нейрона создайте компьютерную модель однослойного
персептрона, который бы осуществлял распознавание образов и
классификацию объектов на два класса.
Рис. 16.1. Однослойный персептрон на базе нейрона.
Под формальным нейроном понимают гипотетический автомат с n входами x1,
x2,..., xn и одним выходом y, характеризующийся порогом h и весами w1, w2,...,
wn. Он состоит из суммирующего и порогового элементов. Его выход
возбужден (y=1), когда сумма всех весов возбужденных входов превышает
порог срабатывания: w1x1+w2x2+...+ wnxn> h. В противном случае выход не
возбужден (y=0). Это можно записать так:
181
Если вес i-ого входа положительный (wi>0), то вход возбуждающий, если
отрицательный (wi<0), --- вход тормозящий.
Так как выход искусственного нейрона может находиться в двух состояниях, то
он может разделять объекты только на два класса. Чтобы симмитировать
работу нейрона достаточно найти взвешенную сумму его входов и
использовать оператор условного перехода. Так работает программа ПР-1:
формальному нейрону последовательно предъявляются 6 объектов,
образующих два класса: K1={10000, 11000, 11100} и K2={00111, 00111, 00010}.
Веса входов подобраны так: wi=(1,1,1,-1,-1), порог срабатывания равен h=0,2.
После запуска программы получаем:
Объект
Объект
Объект
Объект
Объект
Объект
1:
2:
3:
4:
5:
6:
S= 1.0; y= 1
S= 2.0; y= 1
S= 3.0; y= 1
S= -1.0; y= 0
S= -1.0; y= 0
S= -1.0; y= 0
uses crt;
const N=6; h=0.2;
x: array[1..N,1..5]of
integer=((1,0,0,0,0),(1,1,0,0,0),
{ ПР - 16.1 }
(1,1,1,0,0),(0,0,1,1,0),(0,0,1,1,1),(0,0,0,1,0));
w: array[1..5] of real=(1,1,1,-1,-1);
var m,i,j,k,y,DV,MV,EC : integer; S: real;
BEGIN
Clrscr;
For m:=1 to N do
begin
S:=0;
For i:=1 to 5 do S:=S+w[i]*x[m,i];
If S>h then y:=1 else y:=0;
Writeln('Объект ',m,': ','S= ',S:2:1,'; y= ',y);
end;
Readkey;
END.
Задача 16.2.
Рассчитайте нейросеть с 2 входами и 4 нейронами (рис. 16.2). При подаче на
вход сигналов o[1]={00}, o[2]={01}, o[3]={10}, o[4]={11}, на выходах
нейронов должно появиться y[1,j]={1000}, y[2,j]={0100}, y[3,j]={0010},
y[4,j]={0001}, то есть соответствующий нейрон должен быть возбужден.
182
Рис. 16.2. Схема нейросети с 2 входами и 4 нейронами.
Написать программу, моделирующую работу этой нейросети, несложно. Веса
синапсов и порог срабатывания нейрона задаются матрицами:
w[1,j]=(-1, -2, 1, 1), w[2,j]=(-1, 1, -2, 1), h[j]= (-0.5, 0, 0, 1.5).
Решением задачи является программа ПР - 16.2.
uses crt;
{ ПР 16.2 }
const
w: array[1..2,1..4]of real =((-1,-2,1,1),(-1,1,2,1));
h: array[1..4]of real =(-0.5,0,0,1.5);
var i,j,y1,y2,y3,y4,x1,x2 : integer;
Function Neiron_2(j,a1,a2:integer):integer;
begin
If w[1,j]*a1+w[2,j]*a2>h[j] then Neiron_2:=1 else
Neiron_2:=0;
end;
BEGIN clrscr;
For x1:=0 to 1 do
For x2:=0 to 1 do
begin
y1:=Neiron_2(1,x1,x2);
y2:=Neiron_2(2,x1,x2);
y3:=Neiron_2(3,x1,x2);
y4:=Neiron_2(4,x1,x2);
writeln(x1,x2,' | ',y1,y2,y3,y4);
end;
Readkey;
END.
183
Задача 16.3.
Промоделируйте персептрон (двухслойную нейросеть) с 8 входами
(сенсорами), 4 ассоциативными элементами и 2 реагирующими элементами
(рис. 2). При предъявлении объектов o[1]={11110000}, o[2]={0000 1111},
o[3]={00111100}, o[4]={11000011} на выходах персептрона должны появиться
сигналы y[1,j] = {00}, y[2,j] = {01}, y[3,j] ={10}, y[4,j] ={11}.
Рис. 16.3. Схема персептрона с 8 входами.
Программа ПР - 16.3, моделирующая работу этой нейросети, представлена
ниже. Для задания параметров нейронов используются записи.
uses dos, crt;
{ ПР 16.3 }
type Neiron_8 = record
w : array[1..8]of real; h: real; end;
Neiron_4 = record
v : array[1..4]of real; h: real; end;
const
Ne8: array[1..4]of Neiron_8=((w:(1,1,1,1,-1,-1,-1,1); h: 2.5),
(w:(-1,-1,-1,-1,
1,1,1,1); h: 2.5),
(w:(-1,-1,1,1,1,1,-1,1); h: 2.5),
(w:(1,1,-1,-1,-1,1,1,1); h: 2.5));
Ne4: array[1..2]of Neiron_4=((v:(-1,0,1,1); h: 0.5),
(v:(-1,1,0,1); h:
0.5));
184
objekt: array[1..4,1..8]of integer
=((1,1,1,1,0,0,0,0),
(0,0,0,0,1,1,1,1),
(0,0,1,1,1,1,0,0),
(1,1,0,0,0,0,1,1));
var i,j,k,o,z1,z2 : integer; S: real;
x: array[1..8]of integer;
y: array[1..4]of integer;
Function Neiron8(j: integer; a :array of
integer):integer;
begin
S:=0;
For i:=1 to 8 do S:=S+Ne8[j].w[i]*objekt[o,i];
If S>Ne8[j].h then Neiron8:=1 else Neiron8:=0;
end;
Function Neiron4(j: integer; a :array of
integer):integer;
begin
S:=0;
For i:=1 to 4 do S:=S+Ne4[j].v[i]*y[i];
If S>Ne4[j].h then Neiron4:=1 else Neiron4:=0;
end;
BEGIN clrscr;
For o:=1 to 4 do
begin
y[1]:=Neiron8(1,objekt[o,i]);
y[2]:=Neiron8(2,objekt[o,i]);
y[3]:=Neiron8(3,objekt[o,i]);
y[4]:=Neiron8(4,objekt[o,i]);
z1:=Neiron4(1,y[k]); z2:=Neiron4(2,y[k]);
For i:=1 to 8 do write(objekt[o,i],' ');
For j:=1 to 4 do write(' : ',y[j],' ');
writeln(' | ',z1,' ',z2);
end;
Readkey;
END.
Задача 16.4.
Имеется однослойная нейросеть с 9 входами и 4 нейронами. Напишите
программу, вычисляющую веса w так, чтобы сеть распознавала 8 объектов,
представленные на рис. 16.4.1.
185
Рис. 16.4.1. Объекты для распознования.
Объекты закодируем так: o[1]={000010111}, o[2]={111101000} и т.д. Пусть им
соответствуют следующие сигналы на выходах нейронов:
y[1,j]={0000}, y[2,j]={1111}, y[3,j]={1001}, y[4,j]={0110},
y[5,j]={1010}, y[6,j]={0101}, y[7,j]={1100}, y[8,j]={0011}.
Рис. 16.4.2. Схема нейросети.
Необходимо последовательно предъявлять нейросети объекты o[1], o[2],:, o[8]
и изменять веса в соответствии с правилом: 1) если вход x[i] и выход y[j]
одновременно возбуждены, то вес связи w[i,j] увеличивается; 2) если вход x[i]
возбужден, а выход y[j] невозбужден, то вес связи w[i,j] уменьшается. Порог
срабатывания для всех нейронов будем считать равным 0. Используется
программа PR-2. В результате расчетов получается матрица весов:
w[i,1]:=(1, 1, 1, -1, -0.5, 0, 0, -1, 0);
w[i,2]:=(-1, 1, 1, 1, -0.5, 2, -2, -1, 0);
w[i,3]:=(1, 1, -1, 1, -1.5, 0, 0, 1, -2);
186
w[i,4]:=(1, -1, 1, 1, 0.5, 0, 0, -1, 0).
uses crt;
const
x: array[1..8,1..9] of
integer=((0,0,0,0,1,0,1,1,1),
{ ПР - 16.4 }
(1,1,1,1,0,1,0,0,0),(1,0,1,0,1,0,1,0,1),
(0,1,0,1,0,1,0,1,0),(1,1,0,0,0,0,1,1,0),
(0,0,1,1,1,1,0,0,1),(0,1,1,0,0,1,0,0,1),
(1,0,0,1,0,0,1,1,0));
y0: array[1..8,1..4] of
integer=((0,0,0,0),(1,1,1,1),(1,0,0,1),
(0,1,1,0),(1,0,1,0),(0,1,0,1),
(1,1,0,0),(0,0,1,1));
var i,j,o,t: integer; Sw : real;
S : array[1..4] of real; y : array[1..4] of
real;
w : array[1..9,1..4] of real;
BEGIN Clrscr;
Repeat
inc(t);
For o:=1 to 8 do
For j:=1 to 4 do
For i:=1 to 9 do
begin
If x[o,i]*y0[o,j]=1 then
w[i,j]:=w[i,j]+0.01;
If (x[o,i]=1)and(y0[o,j]=0) then
w[i,j]:=w[i,j]-0.01;
end;
until (t>50)or(KeyPressed);
For i:=1 to 9 do For j:=1 to 4 do Sw:=Sw+w[i,j];
For i:=1 to 9 do
begin
For j:=1 to 4 do write(' w',i,j,'=',w[i,j]:2:1);
writeln;
end;
{=== ПРОВЕРКА ===}
For o:=1 to 8 do
begin
For j:=1 to 4 do
begin
S[j]:=0;
187
For i:=1 to 9 do S[j]:=S[j]+x[o,i]*w[i,j];
If S[j]>0 then y[j]:=1 else y[j]:=0;
write(' ',{S[j]:1:2,' ',}y[j]:1:0);
end;
writeln(' objekt ',o);
end;
Readkey;
END.
Задача 16.5.
Создайте компьютерную модель трехслойного персептрона, содержащего 3
ассоциативных и 2 реагирующих элементов. Подберите веса связей так, чтобы
персептрон осуществлял классификацию объектов на 4 класса.
Рис. 16.5. Схема трехслойного персептрона.
Под персептроном понимают обучаемую нейросеть, состоящую из датчиков,
ассоциативных и реагирующих элементов с заданной матрицей весовых
коэффициентов. В многослойных персептронах присутствуют дополнительные
слои ассоциативных элементов. В общем случай персептрон оперирует с
цифровыми образами объектов, каждый из которых представим в виде массива
188
нулей и единиц.
Рассмотрим трехслойный персептрон, состоящего из слоя сенсоров или
датчиков Di (i=1,2,...,9), слоя ассоциативных элементов Aj(j=1,2,3), и слоя
реагирующих элементов Rk (k=1,2). Если уровень воздействия на датчик
превышает некоторое пороговое значение h, то на его выходе появляется 1, а
иначе --- 0. Ассоциативный элемент работает как формальный нейрон: на
выходе 1, когда сумма всех весов возбужденных входов превышает порог
срабатывания; в противном случае на выходе 0. Веса входов wi,jпринимают
значения -1, 0 или 1. Реагирующий R-элемент работает так: когда сумма всех
весов возбужденных входов положительна, на выходе 1, а когда отрицательна -- на выходе --- 0. Веса входов vj,k реагирующего элемента могут принимать
произвольные значения. Выход реагирующего элемента имеет два состояния 0
и 1, поэтому персептрон с двумя решающими элементами может
классифицировать объекты на четыре класса (22=4), соответствующие
выходным сигналам 00, 01, 10, 11.
Создать персептрон не просто, зато его можно сравнительно легко
промоделировать на компьютере. Рассмотрим программу ПР-2, моделирующую
работу трехслойного персептрона, изображенного на рисунке. Допустим,
персептрон должен различать четыре объекта, представленные ниже.
Учитывая расположение датчиков Di (i=1,2,...,9), предъявляемые персептрону
объекты кодируются так: O1=(0,1,0,0,1,0,0,1,0), O2=(0,0,0,1,1,1,0,0,0),
O3=(1,0,0,1,0,0,1,1,1), O4=(1,1,1,0,0,1,0,0,1)). Для того, чтобы персептрон
правильно классифицировал объекты, необходимо задать веса связей,
соединяющих датчики с ассоциативными элементами, и ассоциативные
элементы с реагирующими элементами, следующим образом:
Порог срабатывания ассоциативных элементов h равен 0,5.
uses crt;
{ ПР - 16.5 }
const x: array[1..9] of integer=(1,0,0,
1,0,0,
1,1,1);
w: array[1..3,1..9] of real=((0,-1,1,1,0,1,-1,-1,0),
(0,1,1,-1,0,1,-1,-1,0),(1,0,1,-1,0,0,1,-1,1));
v: array[1..2,1..3] of real=((2,2,-2),(-2,2,2));
var m,i,j,k,DV,MV,EC : integer;
S,y : array[1..3] of real;
T,z : array[1..2] of real;
BEGIN
189
Clrscr;
For j:=1 to 3 do
begin
S[j]:=0;
For i:=1 to 9 do
S[j]:=S[j]+w[j,i]*x[i];
If S[j]>0.5 then y[j]:=1 else y[j]:=0;
Writeln('j= ',j,' | S= ',S[j]:2:1,' | y=
',y[j]:1:1);
end;
For k:=1 to 2 do
begin
T[k]:=0;
For j:=1 to 3 do T[k]:=T[k]+v[k,j]*y[j];
If T[k]>0 then z[k]:=1 else z[k]:=0;
Writeln('k= ',k,' | T= ',T[k]:2:1,' | Выход z=
',z[k]:1:0);
end;
Readkey;
END.
Результат работы программы представлен ниже. Из распечатки видно, какие значения
принимают величины Sj, Tk, а также выходы yj и zk в случае, когда персептрону
предъявляются объекты O1, O2, O3, O4. Объекту O1 соответствуют состояния z1=0, z2=0,
объекту O2 --- состояния z1=1, z2=0 и т.д. Таким образом, наша компьютерная модель
персептрона распознает рассмотренные выше объекты. Вы можете дальше
поэкспериментировать: изменить веса связей, предъявить персептрону другие объекты,
промоделировать персептрон с тремя реагирующими элементами.
======
j= 1 |
j= 2 |
j= 3 |
k= 1 |
k= 2 |
======
j= 1 |
j= 2 |
j= 3 |
k= 1 |
k= 2 |
======
j= 1 |
j= 2 |
j= 3 |
k= 1 |
k= 2 |
======
ОБЪЕКТ 1
S= -2.0 | y= 0.0
S= 0.0 | y= 0.0
S= -1.0 | y= 0.0
T= 0.0 | Выход z= 0
T= 0.0 | Выход z= 0
ОБЪЕКТ 2
S= 2.0 | y= 1.0
S= 0.0 | y= 0.0
S= -1.0 | y= 0.0
T= 2.0 | Выход z= 1
T= -2.0 | Выход z= 0
ОБЪЕКТ 3
S= -1.0 | y= 0.0
S= -3.0 | y= 0.0
S= 1.0 | y= 1.0
T= -2.0 | Выход z= 0
T= 2.0 | Выход z= 1
ОБЪЕКТ 4
190
j=
j=
j=
k=
k=
1
2
3
1
2
|
|
|
|
|
S=
S=
S=
T=
T=
1.0
3.0
3.0
2.0
2.0
|
|
|
|
|
y= 1.0
y= 1.0
y= 1.0
Выход z= 1
Выход z= 1
17. МНОЖЕСТВО МАНДЕЛЬБРОТА И
ДРУГИЕ ФРАКТАЛЫ
Задача 17.1.
Напишите программу, которая строит известный фрактал --- множество
Мандельброта.
Множество Мандельброта -- алгебраический фрактал, для построения которого
используется следующее правило. Берется точка комплексной плоскости с
координатами (a,b), соответствующая комплексному числу c=a+bi. К этой точке
n раз применяется преобразование:
Если в результате n преобразований точка удалится на 2 или более единицы от
начала координат, то она не принадлежит множеству Мандельброта, она
окрашивается в синий цвет. Если же расстояние от этой точки до начала
координат при любом числе итераций n (допустим n=200) останется меньше 2,
то точка принадлежит множеству Мандельброта и она окрашивается в красный
цвет. Программа ПР - 17.1 для построния этого фрактала (рис. 17.1) приведена
ниже.
Для получения цветного изображения фрактала, точки, не принадлежащие
множеству Мандельброта, окрашиваются в цвет, зависящий от числа итераций,
после выполнения которых точка удаляется от начала координат на расстояние
больше чем 2.
191
uses crt, dos, graph;
{ ПР - 17.1 }
var x, y, dx, dy: real;
i,j, cvet, flag, Gd, Gm : integer;
Procedure Raschet(a,b: real);
var x,y,r,t: real; n : integer;
begin
x:=0; y:=0; r:=0; n:=0;
Repeat
t:=x; x:=x*x-y*y+a; y:=2*t*y+b;
r:=x*x+y*y; inc(n); cvet:=round(n/3);
until (n>100)or(r>4);
If x*x+y*y<4 then flag:=1 else flag:=0;
end;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\BP\BGI');
setbkcolor(15);
For j:=-250 to 250 do
begin x:=0;
For i:=-500 to 150 do
begin
Raschet(x,y);
If flag=1 then putpixel(450+i,240+j,12)
else putpixel(450+i,240+j,cvet{9});
x:=i*0.005;
end;
y:=j*0.005;
end;
Repeat until KeyPressed;
CloseGraph;
END.
Рис. 17.1. Множество Мандельброта.
192
Задача 17.2.
Напишите программу, строящую простейший фрактал в виде дерева.
Программа должна строить горизонтальный отрезок [AB], от его концов A и B
рисовать два вертикальных отростка [AC] и [BD]. Затем снова строить два
горизонтальных отрезка меньшей длины [EF] и [GH], от концов которых
пойдут два вертикальных отрезка и т.д. Длины горизонтальных отрезков на
каждом шаге уменьшаются в a раз, где a --- случайное число в интервале от 1,5
до 3. Программа ПР - 17.2 представлена ниже.
uses dos, crt, graph;
{ ПР - 17.2 }
const
dt=0.000001;
var x,y : array[1..700] of real;
Gd, Gm, i, j, n,k,kk,yy : integer; a, l : real;
label
Metka, metka1;
BEGIN Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
setbkcolor(8); Randomize;
x[1]:=320; yy:=400; l:=150; n:=1; kk:=9;
Repeat i:=1;
For k:=1 to n do
begin
y[i]:=x[k]+l;
y[i+1]:=x[k]-l; i:=i+2;
end;
n:=n*2; a:=1.5+random(150)/100; l:=l/a;
kk:=kk+1;
If kk>13 then kk:=9; setcolor(kk);
For i:=1 to n do x[i]:=y[i]; yy:=yy-20;
For i:=1 to n do
line(round(x[i]),yy,round(x[i]),yy-20);
For i:=1 to round(n/2) do
line(round(x[2*i]),yy,round(x[2*i-1]),yy);
until n>300;
Repeat until keypressed; CloseGraph;
END.
193
Рис. 17.2. Простейший фрактал.
Задача 17.3.
Напишите программу, строящую фрактал следующим образом: строится
горизонтальный отрезок [AB], затем пририсовываются два вертикальных
отрезка меньшей длины так, чтобы их середины совпадали с концами A и B.
После этого строятся четыре горизонтальных отрезка меньшей длины и т.д.
Используемая ПР - 17.3 представлена ниже. С каждым следующим шагом
длины отрезков уменьшаются в a раз, где a --- случайное число из интервала
[1,5; 1,9]. Поэтому получающийся фрактал называется стохастическим.
Процедура Draw рисует отрезки, а на концах строит окружности.
uses dos, crt, graph;
{ ПР 17.3 }
var x,y,xx,yy : array[1..7000] of integer;
Gd,Gm,i,n,k,kk,l,l1,l0 :integer; a: real;
Procedure Draw;
begin
For i:=1 to k do begin delay(20); kk:=kk+1;
If kk>14 then kk:=2; setcolor(kk);
line(xx[2*i],yy[2*i],xx[2*i-1],yy[2*i-1]);
circle(xx[2*i],yy[2*i],3);
circle(xx[2*i],yy[2*i],2);
circle(xx[2*i-1],yy[2*i-1],3); circle(xx[2*i1],yy[2*i-1],2);
end; end;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
setbkcolor(15);
Randomize; x[1]:=320; y[1]:=240; l0:=230; k:=1;
Repeat l1:=l0;
For i:=1 to k do begin {gorizont}
a:=1.5+random(400)/1000; l:=round(l1/a);
194
xx[2*i]:=x[i]-l; xx[2*i-1]:=x[i]+l;
yy[2*i]:=y[i]; yy[2*i-1]:=y[i];
end; Draw; k:=2*k;
For i:=1 to k do begin x[i]:=xx[i];
y[i]:=yy[i]; end; l1:=l0;
For i:=1 to k do begin {vertikal}
a:=1.5+random(400)/1000; l:=round(l1/a);
yy[2*i]:=y[i]-l; yy[2*i-1]:=y[i]+l;
xx[2*i]:=x[i]; xx[2*i-1]:=x[i]; end;
Draw; k:=2*k;
For i:=1 to k do begin x[i]:=xx[i];
y[i]:=yy[i]; end; l0:=round(l0/2);
until (k>1000)or(keypressed);
Repeat until keypressed; CloseGraph;
END.
Рис. 17.3. Стохастический фрактал.
195
Задача 17.4.
Постройте конторово множество: исходный отрезок разбейте на три части и
удалите середину. Затем повторите эту процедуру с получившимися двумя
отрезками, создав четыре отрезка. Выполнив эту операцию много раз,
получите фрактал.
Предлагаемая программа содержит рекурсивную процедуру, которая делит
отрезок на 3 части, отбрасывает среднюю часть и вызывает саму себя для
повторения этой операции с получившимися двумя отрезками. Результат
работы программы представлен на рис. 17.4.
uses dos, crt, graph;
{ ПР - 17.4
}
var Gd,Gm,a,b,n,l,i,j : integer;
Procedure rec(a,b,l,n:integer);
var x1,x2 :integer;
begin
If n<9 then
begin
l:=round(l/2.1); x1:=a; x2:=b;
For j:=1 to 19 do
begin
line(x1,20*n+j,x1+l-2,20*n+j);
line(x2-l+2,20*n+j,x2,20*n+j);
end;
n:=n+1; rec(x1,x1+l,l,n);
rec(x2-l,x2,l,n);
end;
end;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
l:=620; a:=10; b:=l;
line(a,10,b,10); rec(a,b,l,1);
Repeat until keypressed;
CloseGraph;
END.
196
Рис. 17.4. Канторово множество.
Задача 17.5.
Постройте фрактал по следующему алгоритму: программа выбирает в центре
экрана точку O и строит квадрат ABCD с длиной стороны L. После этого она
строит квадраты вокруг вершин A, B, C, D с длинами сторон L/a и т.д., где a -- случайная величина в интервале [2; 2,5].
Программа ПР - 17.5 содержит рекурсивную процедуру, которая вызывает сама
себя. При каждом вызове счетчик n увеличивается на 1, пересчитывается длина
стороны L (уменьшается в a раз, где a --- случайная величина из интервала [2,
2.5]), изменяется цвет рисуемых квадратов.
uses dos, crt, graph;
{ ПР 17.5 }
var Gd,Gm,x,y,n,l : integer;
Procedure rec(x,y,l,n:integer);
var x0,y0,x1,x2,y1,y2,x3,y3,x4,y4 :integer;
begin
inc(n); setcolor(n mod 6+6);
If n<9 then
begin
l:=round(l/(random(5)/10+2)); x0:=x; y0:=y;
rectangle(x-l,y-l,x+l,y+l);
rectangle(x-l+1,y-l-1,x+l+1,y+l+1);
rec(x0-l,y0-l,l,n); rec(x0-l,y0+l,l,n);
rec(x0+l,y0+l,l,n); rec(x0+l,y0-l,l,n);
end;
end;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
setbkcolor(11); randomize;
l:=250; x:=320; y:=240; rec(x,y,l,1);
Repeat until keypressed; CloseGraph;
END.
197
Рис. 17.5. Фрактал из квадратов.
Задача 17.6.
Постройте фрактал по следующему алгоритму. Плоская поверхность разбита
на клетки, находящиеся в состоянии 0. Если клетка перешла в возбужденное
состояние 1, то вероятность перехода соседних четырех клеток в состояние 1
на следующем шаге становится большой. Если невозбужденная клетка
граничит с двумя, тремя или четырьмя возбужденными клетками, то
вероятность ее перехода в состояние 1 уменьшается.
Пусть на плоской поверхности, разбитой на квадратные клетки, находятся
бактерии. Клетку, внутри которой они находятся, будем считать возбужденной
(a[i,j]=1). Бактерии могут переходить в смежную клетку (например, [i+1,j]),
которая при этом тоже станет возбужденной (была a[i+1,j]=0, стала a[i+1,j]=1).
Допустим, что бактерии из клетки [i,j] живут за счет питательных веществ,
находящихся в соседних четырех клетках [i-1,j], [i+1,j], [i,j-1], [i,j+1]. Тогда
вероятность возбуждения клетки в состоянии 0 тем меньше, чем больше
возбужденных соседей она имеет. Можно также учесть и время, в течение
которого соседние клетки были возбуждены и жили, потребляя питательное
вещество из данной клетки.
Для моделирования этого процесса используется программа ПР - 17.6. В ней
перебираются все клетки и вычисляется число возбужденных соседей,
результаты сохраняются в массиве b[i,j].
198
uses dos, crt, graph;
{ ПР - 17.6 }
const
N=110; M=90;
var a,b,p: array[1..N,1..M]of integer;
Gd,Gm,i,j,S,K,x: integer;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
Randomize; setbkcolor(15); a[60,40]:=1;
Repeat
For i:=2 to N-1 do
For j:=2 to M-1 do
begin
S:=a[i-1,j]+a[i,j-1]+a[i+1,j]+a[i,j+1];
b[i,j]:=b[i,j]+S;
If b[i,j]=0 then p[i,j]:=0;
If b[i,j]<>0 then
p[i,j]:=round(70/b[i,j]/b[i,j]);
If b[i,j]>3 then p[i,j]:=0;
end;
For i:=2 to N-1 do
For j:=2 to M-1 do
begin
If a[i,j]>0 then a[i,j]:=a[i,j]+1;
x:=random(100);
If (a[i,j]=0)and(x0 then
begin
If a[i,j]/6>12 then a[i,j]:=1;
setcolor(round(a[i,j]/6+1));
circle(5+5*i,5+5*j,2);
circle(5+5*i,5+5*j,1);
end;
delay(2000);
until keypressed; CloseGraph;
END.
199
Рис. 17.6. Стохастический фрактал.
18. ДРУГИЕ ЗАДАЧИ ПО ПРОГРАММИРОВАНИЮ
Задача 18.1.
Методом трапеций вычислите площадь круга радиусом 1, определите
значение числа π.
Площадь единичного круга равна учетверенному значению интеграла
Значение интеграла может быть найдено методом трапеций по следующей
формуле:
Используемая программа ПР - 18.1 приведена ниже. При ее запуске на экране
получается следующее значение: 3,1415926164.
uses dos, crt;
const dx=0.00001;
var i : longint; x,y1,y2,S : real;
BEGIN
Repeat
y1:=sqrt(1-x*x); inc(i);
x:=i*dx; y2:=sqrt(1-x*x);
S:=S+(y1+y2)*dx/2;
until i=100000;
writeln(4*S); Readkey;
END.
{ ПР - 18.1 }
200
Задача 18.2.
Напишите программу, переводящe. десятичное число в шестнадцатиричную
систему счисления.
Программа ПР - 18.2 работает так. Десятичное число, которое необходимо
перевести в шестнадцатиричную систему счисления, присваивается
переменной a. В начале цикла значение переменной a присваивается
переменной b, а переменной a присваивается целая часть от деления a на 16.
После этого определяется разность b - 16 * a, соответствующая цифра
записывается в младший разряд. После этого все повторяется снова.
uses crt;
{ ПР 18.2 }
var a,b,c,d:integer;
label m;
BEGIN
clrscr; write('введите десятичное число ');
read(a); c:=20;
Repeat
c:=c-1; b:=a; a:=a div 16;
d:=b-16*a; gotoxy(c,5);
If d=10 then begin write('A'); goto 10; end;
If d=11 then begin write('B'); goto 10; end;
If d=12 then begin write('C'); goto 10; end;
If d=13 then begin write('D'); goto 10; end;
If d=14 then begin write('E'); goto 10; end;
If d=15 then begin write('F'); goto 10; end;
write(d);
m:
until a=0;
ReadKey;
END.
Задача 18.3.
Промоделируйте работу исполнителя, перемещающегося по горизонтальной
поверхности в соответствии с заданной программой.
Используется программа ПР - 18.3. Последовательность команд исполнителя
записана в виде: a:='drd . . . luld'. при этом u - вверх, d - вниз, r -вправо, l - влево.
Программа содержит цикл, в котором вырезается по одному символу, в
результате чего светящаяся точка на экране монитора смещается с некоторым
201
шагом вверх, вниз, вправо или влево.
Uses graph, crt;
{ ПР - 18.3 }
Var k4,k1,k,k2,k3,i,Gd,Gm,p: integer;
a,x: string;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\BP\BGI');
moveto(320,240);
a:='drdrdruuululululululdddddd'; k:=0;
For i:=1 to length(a) do
begin
x:=copy(a,i,1);
If x='r' then begin k1:=k+30; linerel(k1,0) end
else
If x='u' then begin k2:=k+30; linerel(0,k2) end
else
If x='l' then begin k3:=k-30; linerel(k3,0) end
else
If x='d' then begin k4:=k-30; linerel(0,k4)
end;
delay(5000); sound(400); delay(1500); nosound;
end;
Readkey; CloseGraph;
END.
Задача 18.4.
Напишите тестирующую программу, проверяющую умение решать примеры
по арифметике.
Используемая программа ПР - 18.4 содержит цикл, в котором задаются
случайные значения переменных a и b и генерируется пример типа a * b = ?.
Тестируемый вводит ответ n, компьютер сравнивает его с правильным ответом
c = a * b. Определяется число правильных ответом, ставится оценка.
uses crt;
{ ПР - 18.4 }
var s,i,j,a,b,c,n:integer;
BEGIN
clrscr; randomize; s:=0;
For j:=1 to 5 do
begin
a:=random(9); b:=random(9); c:=a*b; writeln;
writeln('Сколько будет
',a,'*',b );
writeln('ответ'); readln(n);
If n=c then
202
begin
write('ВЕРНО') ;s:=s+1;
If n<>c then
begin write('НЕТ'); end;
end;
write('Число правильных ответов=',s);
end;
If s=5 then begin write ('ваша оценка 5');
If s=4 then begin write ('ваша оценка 4');
If s=3 then begin write ('ваша оценка 3');
If s=2 then begin write ('ваша оценка 2');
If (s=1) or (s=0) then
begin write('попробуйте заново');
ReadKey;
END.
end;
end;
end;
end;
end;
Задача 18.5.
Археологи А, Б и В нашли монету. Каждый высказал по 2 предположения: 1)
А сказал: монета греческая, 5 век; 2) Б сказал: монета испанская, 3 век; 3) В
сказал: монета не греческая, 4 век. Каждый из археологов прав только в
одном из двух предположений. Где и когда была выпущена монета?
Обозначим простые высказывания: G=1 - монета греческая, I=1 - монета
испанская, P=1 - пятый век, C=1 - четвертый век, T=1 - третий век. Каждый из
археологов прав только в одном из двух предположений, поэтому
высказывания 1, 2, и 3 приводят к следующим логическим уравнениям:
1) G not(P) + not(G) P = 1,
2) I not(T) + not(I) T = 1,
3) not(G) not(C) + G C = 1.
Монета не может быть изготовлена в двух государствах и двух веках:
GI=0, PC=0, PT=0, CT=0.
Решением этой задачи является программа ПР - 18. В ней автоматически
перебираются все возможные варианты и находится такой, при котором
истинны все 7 уравнений. Число истинных уравнений обозначено через k.
Необходимо запустить программу и найти строчку, для которой k=7.
uses crt;
{ ПР - 18.3 }
var G,P,I,T,C: boolean;
gg,pp,tt,cc,ii,k,l,m,n,o: integer;
BEGIN
clrscr; k:=0;
For gg:=0 to 1 do begin
If gg=0 then g:=false else g:=true;
203
For pp:=0 to 1 do begin
If pp=0 then p:=false else p:=true;
For tt:=0 to 1 do begin
If tt=0 then t:=false else t:=true;
For cc:=0 to 1 do begin
If cc=0 then c:=false else c:=true;
For ii:=0 to 1 do
begin
If ii=0 then i:=false else i:=true;
If ((g)and(not(p))or(not(g)and(p))=true)
then k:=k+1;
If ((i)and(not(t)))or(not(i)and(t))=true
then k:=k+1;
If (not(g)and(not(c)))or((g)and(c))=true
then k:=k+1;
If (g)and(i)=false then k:=k+1;
If (p)and(c)=false then k:=k+1;
If (p)and(t)=false then k:=k+1;
If (c)and(t)=false then k:=k+1;
writeln(g,' ',p,' ',t,' ',c,' ',i,' ',k,'
'); k:=0;
end;
end;
end;
end;
end;
writeln(k); ReadKey;
end.
Задача 18.6.
Имеется совокупность 30 объектов, каждый из которых характеризуется
двумя величинами. Напишите программу, которая осуществляла бы
кластеризацию (автоматическую классификацию) объектов, разделяя их на
классы.
Кластеризация иерархического типа состоит в последовательном объединении
групп объектов, начиная с самых близких и похожих друг на друга. Рассмотрим
множество из n объектов O1 (x1, y1), O2(x2, y2), ..., On (xn, yn), каждый из которых
характеризуется двумя признаками X и Y. В пространстве признаков XOY
каждому объекту соответствует точка. В качестве меры близости двух объектов
Oi и Oj обычно выбирают геометрическое расстояние между этими точками:
204
На начальном этапе считают, что каждый объект образует кластер с массой 1.
Для каждой пары точек определяют меру близости Si,kи, сравнивая их друг с
другом, находят наиболее близко расположенные объекты, которые
объединяются в один кластер с массой 2. Координаты нового кластера
вычисляются как средние взвешенные координат объединенных кластеров.
Затем процесс повторяется. При слиянии двух кластеров Oi и Oj (i меньше j) c
весовыми коэффициентами pi и pj получается кластер Oi, имеющий следующие
координаты и весовой коэффициент соответственно:
В результате N-Ch_kl шагов, на каждом из которых два кластера объединяются
в один, получается разбиение на Ch_kl кластеров. Результат использования
программы ПР - 18.4 для кластеризации 30 двумерных объектов представлен на
рис. 18.4. Если отключить графический режим, закоментировать
соответствующие операторы и раскоментировать другие, то на экран будет
выведен список объектов с указанием класса, к которому он отнесен.
uses crt, dos, graph;
{ ПР 18.6 }
const Max=30; Ch_kl=3; U=15;
Data1: array[1..Max]of
real=(4,3,5,6,5,7,8,4,10,13,9,11,-2,
-6,-7,-9,-8,-11,-7,12,4,7,3,5,6,8,5,7,10,13);
Data2: array[1..Max]of real=(-2,-8,-3,-9,-7,-5,-12,11,-6,-10,
-8,7,9,7,4,6,8,10,6,4,8,7,10,11,6,7,4,11,6,5);
Var x,y,p : array[1..Max] of real;
klass : array[1..Max] of integer;
L: array[1..Max,1..Ch_kl] of real;
i,j,k,m,N,t,Gd,Gm: integer; a,L1: real;
BEGIN
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi'); N:=Max;
For i:=1 to N do
begin
klass[i]:=i; p[i]:=1;
x[i]:=Data1[i]; y[i]:=Data2[i];
end;
Repeat a:=10000;
For i:=1 to N do
For j:=i+1 to N do
205
begin
L1:=sqr(x[i]-x[j])+sqr(y[i]-y[j]);
If L1<a then begin a:=L1; k:=i; m:=j; end;
end; dec(N);
{ writeLn('Объекты ',k,' и ',m,' объединяются
в новый кластер ',k);}
{ line(320+round(x[k]*U),240-round(y[k]*U),
320+round(x[m]*U),240-round(y[m]*U));}
y[k]:=(y[k]*p[k]+y[m]*p[m])/(p[k]+p[m]);
x[k]:=(x[k]*p[k]+x[m]*p[m])/(p[k]+p[m]);
p[k]:=p[k]+p[m];
{ writeLn('Его координаты ', x[k]:4:2,
y[k]:8:2,' вес
',p[k]:2:0);}
For i:=1 to N do If i>=m then
begin
x[i]:=x[i+1]; y[i]:=y[i+1];
p[i]:=p[i+1]; klass[i]:=klass[i+1];
end;
until N=Ch_kl;
For i:=1 to Max do
begin
a:=1000;
For j:=1 to Ch_kl do
begin
L[i,j]:=sqr(Data1[i]-x[j])+sqr(Data2[i]y[j]);
If L[i,j]<a then begin a:=L[i,j];
klass[i]:=j;
end;
end; end;
For i:=1 to Max do write(' |
ob[',i,']=',klass[i]);{}
line(0,240,640,240); line(320,0,320,480);
For i:=1 to Max do circle(320+round(Data1[i]*U),
240round(Data2[i]*U),2);
For i:=1 to N do circle(320+round(x[i]*U),
240round(y[i]*U),3);
For i:=1 to Max do
For j:=1 to Ch_kl do If klass[i]=j then
line(320+round(x[j]*U),240-round(y[j]*U),
320+round(Data1[i]*U),240-round(Data2[i]*U));
Repeat until keypressed; CloseGraph;
END.
206
Рис. 18.4. Результат классификации объектов на 3 группы.
Задача 18.7.
Напряжение изменяется по периодическому закону U=U(t). Напишите
программу, осуществляющую разложение функции U=U(t) в ряд Фурье.
Восстановите функцию и постройте график.
Формулы для разложения периодической функции в ряд Фурье имеют вид:
В предлагаемой программе методом прямоугольников вычисляются
постоянная составляющая U0, косинусоидальные и синусоидальные члены
ряда a[n] и b[n] для двадцати первых гармоник. По результатам строят график
восстановленного сигнала (рис. 18.5).
207
uses dos, crt, graph;
const Ch_garm=20; pi=3.1415926;
var t,dt,w,aa,bb,U0,UV,Period: real;
i,n,Gd, Gm: integer;
a,b: array[1..50]of real;
Function U(t:real):real;
begin w:=2*pi/Period;
U:=abs(10*sin(w*t));
{If t>Period/2 then U:=0 else U:=10*sin(w*t);}
{If t>Period/2 then U:=0 else U:=10;}
{U:=2*t;}
end;
BEGIN
clrscr; dt:=2*pi/1000; Period:=2*pi;
For i:=1 to 1000 do
begin
t:=i*dt; U0:=U0+U(t)*dt;
end;
U0:=U0/Period; writeln(U0);
For n:=1 to Ch_garm do
begin
aa:=0; bb:=0;
For i:=1 to 1000 do
begin
t:=i*dt; aa:=aa+U(t)*cos(n*w*t)*dt;
end;
a[n]:=2*aa/Period;
For i:=1 to 1000 do
begin
t:=i*dt; bb:=bb+U(t)*sin(n*w*t)*dt;
end;
b[n]:=2*bb/Period;
writeln(a[n],' ',b[n]);
end;
readkey;
Gd:=Detect; InitGraph(Gd, Gm, 'c:\bp\bgi');
line(0,300,640,300);
For i:=1 to 5000 do
begin
t:=i*dt; UV:=U0;
For n:=1 to Ch_garm do
begin
UV:=UV+a[n]*cos(n*w*t)+b[n]*sin(n*w*t);
end;
circle(10+round(t*20),300-round(10*UV),1);
end;
Repeat until keypressed; CloseGraph;
208
END.
Рис. 18.5. Разложение в ряд Фурье.
Задача 18.8.
Напишите программу, которая работает так: компьютер случайно загадывает
число от 1 до 256. Вы пытаетесь угадать. Компьютер отвечает "больше" или
"меньше".
209
Download