При задании произвольных значений входных данных пользователь должен учитывать, что если задать стоимость единицы пути либо дину дуги, не существующей дороги, то программа выдаст предупреждение о неправильном вводе начальных данных.
Файл 11. txt содержит следующие значения:
Матрица пропускной способности:
Вектор вероятности:
Время задержки транспорта:
Матрица стоимости пути единицы пути:
Матрица длины дороги:
Коэффициенты важности:
Количество прогонов: 10
Если необходимо создать текстовый файл с новыми данными, то нужно прописать необходимые значения и нажать на кнопку “Запись в файл". Эти значения записываются txt-файл и при дальнейшей работе с ними нужно нажать на кнопку “Чтение из файла". На рисунке 2.4 представлен пример заполнения входных значений. Когда все значения заполнены, нажимаем на кнопку “Вычислить". При этом появляется форма, указанная на рисунке 2.5
Рисунок 2.4- Пример ввода данных.
Таким образом, на форме представлены следующие результаты работы программы: матрица размером 2х10, в первом столбце которой представлены значения максимальных потоков на каждом прогоне, во втором - значения обобщенных показателей “выгоды"; среднее значение показателей выгоды и максимальных потоков, полученных на каждом прогоне; матрица усредненного потока.
Рисунок 2.5- Полученный результат
Для просмотра полученной матрицы пропускных способностей необходимо нажать на кнопку “Жми сюда”. Появляется форма, которая указана на рисунке 2.6
Таким образом при выполнении программы с начальными данными, расположенными в текстовом файле 11. txt мы получим следующие результаты:
Матрица усредненного потока всей сети:
Среднее значение выгоды: 0,82
Среднее значение потока: 7
Новая пропускная способность:
Полученная новая матрица пропускных способностей, будет обеспечивать максимальный поток транзитных маршрутов в железнодорожной сети в направлении из начального пункта в конечный для данной сети дорог.
Рисунок 2.6- Рекомендуемая пропускная способность
В ходе реализации курсовой работы были выполнены все поставленные задачи и разработана имитационная модель транспортной сети с учетом одного входа и одного выхода в сети.
Таким образом, были решены следующие частные задачи:
актуальность использования имитационной модели для исследования потоков транспортной сети;
составление списков входных и выходных параметров имитационной модели железнодорожной транспортной сети;
разработка и реализация алгоритма имитационной модели;
решение тестовых задач с помощью имитационной.
Таким образом, был разобран материал по данной курсовой работе и выявлена актуальность разработки имитационной модели транспортной сети и выполнено программное обеспечение, реализующее работу модели железнодорожной сети. Данная модель разработана для случая одного входа и одного выход в сеть и нуждается в дополнительной модификации программы, что будет выполнено в следующей курсовой работе.
1. Максимей И.В. Имитационное моделирование на ЭВМ. - М.: Радио и связь, 1988. - 232 с.
2. Технология системного моделирования / Под общ. ред. С.В. Емельянова. - М.: Машиностроение; Берлин: Техник, 1988. - 520 с.
3. Задачи и модели ИСО. Ч.3. Технология имитации на ЭВМ и принятие решений: Уч. пособие / И.В. Максимей, В.Д. Левчук, С.П. Жогаль, В.Н. Подобедов. - Гомель: БелГУТ, 1999. - 150 с.
4. Левчук В.Д. Базовая схема формализации системы моделирования MICIC4 // Проблемы программирования. - 2005. - № 1. - С.85-96.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls, ExtCtrls, jpeg;
type
TForm1 = class (TForm)
GroupBox1: TGroupBox;
Panel1: TPanel;
Panel2: TPanel;
VertexPrompt: TLabel;
VertexCount: TEdit;
Button1: TButton;
Button2: TButton;
Capofedge: TStringGrid;
GroupBox3: TGroupBox;
StringGrid1: TStringGrid;
GroupBox4: TGroupBox;
StringGrid2: TStringGrid;
Edit1: TEdit;
Button3: TButton;
Memo1: TMemo;
Button4: TButton;
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
Label1: TLabel;
StringGrid3: TStringGrid;
GroupBox5: TGroupBox;
Label2: TLabel;
Edit2: TEdit;
StringGrid4: TStringGrid;
StringGrid5: TStringGrid;
Label3: TLabel;
Label4: TLabel;
Edit3: TEdit;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
Edit4: TEdit;
Label8: TLabel;
Edit5: TEdit;
Label9: TLabel;
Panel3: TPanel;
Image1: TImage;
Label10: TLabel;
Label11: TLabel;
Label12: TLabel;
Edit6: TEdit;
Label13: TLabel;
Edit7: TEdit;
Label14: TLabel;
Label15: TLabel;
Label16: TLabel;
Button5: TButton;
Label17: TLabel;
procedure Button2Click (Sender: TObject);
procedure Button1Click (Sender: TObject);
procedure VertexCountChange (Sender: TObject);
procedure Button3Click (Sender: TObject);
procedure Button4Click (Sender: TObject);
procedure Edit2Change (Sender: TObject);
procedure Button5Click (Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
Const
N1=100;
l=MAXINT;
var
Form1: TForm1;
n: integer;
kol2,op,rr,nn,mi,tool,kon: integer;
j1,l6,w, i,z,j,ko,h1,h2,sum,ss,maxpotok,j3,k3,kk,potok,o,ll,kol1,pp,p1,j2,kol,t: integer;
c: array [1. N1,1. N1] of integer;
c1: array [1. N1,1. N1] of real;
c2: array [1. N1,1. N1] of real;
tt: array [1. .50,1. .50] of real;
fij: array [1. .50,1. .50] of real;
yij: array [1. .50,1. .50] of real;
y1i: array [1. .50,1. .50] of real;
xij: array [1. .10,1. .50] of real;
fij1: array [1.20,1.20] of real;
ttt: array [1.20,1.20] of real;
dij: array [1.20] of real;
Fi: array [1.20] of real;
lhh: array [1.20,1.20] of real;
hij: array [1.20] of real;
hi: array [1.20] of integer;
potokvr: array [1.20] of integer;
d11,d22,d33,z1,l5,mm,ten,w1,t1,kol3,lop,bpp,loop,ten1,bred1,bred2: real;
lh: array [1. N1,1. N1] of integer;
qh: array [1. N1,1. N1] of integer;
f: array [1. N1,1. N1] of integer;
const
size = N1 + 2;
type
queue = record
a: array [0. size-1] of integer;
head, tail: integer;
end;
var
p: array [1. N1] of integer; // номер предыдущей вершины
v: array [1. N1] of boolean; // посещенность
q: queue;
implementation
{$R *. dfm}
procedure init_queue (var q: queue); // инициализировать очередь
begin
with q do
begin
tail: = 0;
head: = 0;
end;
end;
function is_queue_empty (const q: queue): boolean; // Проверка пустоты
begin
is_queue_empty: = q. tail = q. head;
end;
procedure push (var q: queue; x: integer); // Положить элемент в очередь
begin
with q do
begin
a [tail]: = x;
tail: = (tail + 1) mod size;
end;
end;
function pop (var q: queue): integer; // Достать из очереди
begin
with q do
begin
pop: = a [head] ;
head: = (head + 1) mod size;
end;
end;
// Метод Форда-Фалкерсона
function mff (xo, xn: integer): boolean;
var
i, j: integer;
begin
fillchar (v, sizeof (v), false); { обнуляем массив посещений }
init_queue (q); { инициализируем очередь }
push (q, xo); { заталкиваем в очередь исток }
v [xo]: = true; { посетили исток }
p [xo]: = - 1; { у истока нет предка }
while not is_queue_empty (q) do { пока очередь не пуста }
begin
i: = pop (q); { достаем вершину из очереди }
for j: = 1 to n do { перебираем все вершины }
if not v [j] and { вершина не посещена }
(c [i, j] -f [i, j] > 0) then { ребро i->j ненасыщенное }
begin
v [j]: = true; { посетили вершину j }
push (q, j); { положили веришину j в очередь }
p [j]: = i; { i предок j }
end;
end;
mff: = v [xn] ; { дошли ли до стока }
end;
{ min: минимум из двух вещественных чисел }
function min (a, b: integer): integer;
begin
if a > b then min: = b else min: = a;
end;
// максимальное значение потока }
procedure maxpotok1 (xo, xn: integer);
var
k: integer;
d,d1,potok: integer;
begin
kk: =0;
repeat
begin
if c [1,j3] <>0 then
begin
kk: =kk+1;
j3: =j3+1;
end
else j3: =j3+1;
end;
until j3>n;
fillchar (f, sizeof (f), 0); // обнуляем gjnjr
potok: = 0;
while mff (xo, xn) do // Пока существует путь от xo в xn}
begin
d: = l;
d1: = l; // ребро в этом пути с минимальной
k: = xn; // пропускной способностью
while k <> xo do
begin
d: = min (d,c [p [k], k] -f [p [k], k]);
d1: = min (d1,c [p [k], k] -f [p [k], k]);
k: = p [k] ;
end;
k: = xn; // идем по найденому пути от xo к xn
while k <> xo do
begin
f [p [k], k]: = f [p [k], k] + d; // увеличиваем по прямым ребрам
f [k, p [k]]: = f [k, p [k]] - d; // уменьшаем по обратным ребрам
k: = p [k] ;
end;
j3: =1;
potok: = potok + d1;
// увеличиваем поток
if k3<>kk then k3: =k3+1 else
begin
i: =1; j2: =1;
for j1: =1+t to n+t do
begin
for j: =1 to n do
begin
tt [j1,j2]: =f [i,j] ;
if j2<=n then j2: =j2+1;
if j2>n then j2: =1;
end;
if i<n then i: =i+1; end;
t: =t+n;
potokvr [z]: =potok;
z: =z+1;
// строим lhh
kol2: =0;
for i: =1 to n do
for j: =1 to n do
kol2: =kol2+lh [i,j] ;
for i: =1 to n do
for j: =1 to n do
lhh [i,j]: =lh [i,j] /kol2;
// построили матрицу lhh
// дополнительная часть программы
{razigrivaem}
p1: =1;
for i: =1 to n do
begin
sum: =0;
ko: =0; t1: =0;
for j: =1 to n do
if f [i,j] >0 then
begin
w1: =Random;
for w: =1 to ll do
begin
if w1<hij [w] +t1 then begin
ss: =f [i,j] *hi [w] ;
sum: =sum+ss;
ko: =ko+f [i,j] ;
break;
end
else t1: =hij [w] +t1;
end;
end; if ko=0 then ko: =1;
dij [p1]: =sum/ko; p1: =p1+1;
end;
for i: =1 to n do
for j: =1 to n do
begin
yij [i,j]: =d11*lhh [i,j] ;
fij1 [i,j]: =0;
end;
{umnozit matr na vek}
i: =0;
while op<=n do
begin
rr: =1;
i: =i+1;
while rr<=n do
begin
mm: =0;
for j: =1 to n do mm: =mm+qh [i,j] *lh [j,rr] ;
ttt [op,rr]: =mm; rr: =rr+1;
end;
op: =op+1;
end;
lop: =0;
for i: =1 to n do
for j: =1 to n do
lop: =lop+ttt [i,j] ;
for i: =1 to n do
for j: =1 to n do
ttt [i,j]: =d33* (ttt [i,j] /lop);
for i: =1 to n do
for j: =1 to n do
if f [i,j] >0 then begin
fij1 [i,j]: =lh [i,j] /f [i,j] +dij [i] ;
kol3: =kol3+fij1 [i,j] ;
end;
for i: =1 to n do
for j: =1 to n do
begin
fij1 [i,j]: = (fij1 [i,j] /kol3) *d22;
end;
{vischitivaem vse fij*}
for i: =1 to n do
for j: =1 to n do
begin
fij [i,j]: =ttt [i,j] +fij1 [i,j] +yij [i,j] ;
end;
{nahodim F=sumfij*}
lop: =0;
for i: =1 to n do
for j: =1 to n do
lop: =lop+fij [i,j] ;
Fi [mi]: =lop;
mi: =mi+1;
// конец дополнительной части
end; end;
maxpotok: =potok; // возвращаем максимальный поток