Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курсовые по ОАУ / Методы сетевого планирования и управления. Оптимизация проекта по стоимости.doc
Скачиваний:
295
Добавлен:
15.06.2014
Размер:
9.18 Mб
Скачать

Приложение а. Связи между различными вариантами классификации систем сетевого планирования и управления

Рис А1 Классификация систем сетевого планирования и управления

Приложение б. Текст программы

unit net_planning_file;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

Grids, ComCtrls, Tabnotbk, StdCtrls;

type

TForm1 = class(TForm)

TabbedNotebook1: TTabbedNotebook;

Label1: TLabel;

Edit1: TEdit;

Button1: TButton;

Label2: TLabel;

Edit2: TEdit;

StringGrid1: TStringGrid;

Button2: TButton;

StringGrid2: TStringGrid;

Button3: TButton;

ComboBox1: TComboBox;

Memo1: TMemo;

ComboBox2: TComboBox;

Label3: TLabel;

Label4: TLabel;

Label5: TLabel;

Label6: TLabel;

Label7: TLabel;

Edit3: TEdit;

Label8: TLabel;

Edit4: TEdit;

Label9: TLabel;

Edit5: TEdit;

Edit6: TEdit;

Label10: TLabel;

Label11: TLabel;

Button4: TButton;

StringGrid3: TStringGrid;

Button5: TButton;

StringGrid4: TStringGrid;

Edit7: TEdit;

Label12: TLabel;

StringGrid5: TStringGrid;

Label13: TLabel;

Label14: TLabel;

Button6: TButton;

Label15: TLabel;

Label16: TLabel;

Label17: TLabel;

Label18: TLabel;

Label19: TLabel;

Label21: TLabel;

Label22: TLabel;

Label23: TLabel;

Label20: TLabel;

procedure FormCreate(Sender: TObject);

procedure Button1Click(Sender: TObject);

procedure Button2Click(Sender: TObject);

procedure Button3Click(Sender: TObject);

procedure Button4Click(Sender: TObject);

procedure Button5Click(Sender: TObject);

procedure StringGrid3SelectCell(Sender: TObject; ACol, ARow: Integer;

var CanSelect: Boolean);

procedure Button6Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

const infinity=1000000000000000000000000000000.0; //бесконечность

type

TEvent=record // событие

name:string; // имя

number:integer; // номер

early_date:extended; // ранний срок свершения

vu_label:boolean; // принадлежит {u} или {v}

end;

TWork=record // работа

name:string; // имя

number:integer; // номер

initial_event:integer; // начальное событие

final_event:integer; // конечное событие

initial_event_name:string; // имя начального события

final_event_name:string; // имя конечного события

cost_a:extended; // a[i,j]

cost_b:extended; // b[i,j]

cost:extended; // c[i,j]

d_big:extended; // D[i,j]

d_little:extended; // d[i,j]

t:extended; // продолжительность t[i,j]

existance:boolean; // существует работа между i и j

work_is_cut:boolean; // попадает ли работа в сечение

end;

TPrevious=record

epsilon:array[0..100,0..100] of integer;

atta:array[0..100] of integer;

teta0:extended;

end;

works_t=array[0..100,0..100] of TWork;

event_t=array[0..100] of TEvent;

work_t=array[1..100] of TWork;

tableT=array[0..100,0..100] of extended; // значение элемента таблицы

table_fullT=array[0..100,0..100] of boolean; // заполнен ли элемент таблицы

T_teta_array=array[0..100,0..100] of extended;

var

Form1: TForm1;

report:TextFile;

works,answer_works,previous_work:Works_t;

event,answer_event,previous_event:event_t;

work,answer_work:Work_t;

previous:TPrevious;

n_event:integer; //количество событий

n_work:integer; //количество работ

work_count:integer;

table:tableT;

table_full:table_fullT;

the_end:boolean; // равен "истина", если

//получен граф с минимально возможным Ткр

cost:extended; //общая стоимость проекта

critical_path:extended; // Тд

critical_path_min:extended; // минимально возможный Ткр

work_to_change:integer;

implementation

{$R *.DFM}

function check_integer(s:string):boolean;

// проверяет, возможно ли перевести строку s в

// целое число из отрезка [2;100]

var tf:boolean ;

i:integer;

const numbers:set of char=['0','1','2','3','4','5','6','7','8','9'];

begin

tf:=true;

if length(s)<>0 then

begin

for i:=1 to length(s) do

if not(s[i] in numbers) then tf:=false;

end

else tf:=false;

if (tf=true) and ((StrToInt(s)<2)or(StrToInt(s)>100))then tf:=false;

check_integer:=tf;

end;

function check_extended(s:string):boolean;

// проверяет, возможно ли перевести строку s в

// действительное неотрицательное число

var tf:boolean ;

i:integer;

count_comma:integer;

const numbers:set of char=['0','1','2','3','4','5','6','7','8','9','.'];

begin

count_comma:=0;

tf:=true;

if length(s)<>0 then

for i:=1 to length(s) do

begin

if not(s[i] in numbers) then

tf:=false;

if s[i]='.' then

count_comma:=count_comma+1;

end

else tf:=false;

if s[1]='.' then tf:=false;

if count_comma>1 then tf:=false;

check_extended:=tf;

end;

function check_names(n_row:integer;grid_label:integer):boolean;

// проверяет, что в списках событий и работ

// нет объектов с одинаковыми именами

var i,j:integer;

tf:boolean;

begin

tf:=true;

for i:=1 to n_row do

for j:=1 to n_row do

begin

if grid_label=1 then

if (form1.StringGrid1.Cells[1,i]=form1.StringGrid1.Cells[1,j])

and (i<>j)then

tf:=false;

if grid_label=2 then

if (form1.StringGrid2.Cells[1,i]=form1.StringGrid2.Cells[1,j])

and (i<>j)then

tf:=false;

end;

check_names:=tf;

end;

function check_matrix_existence(var error_cycle,

error_connected:boolean):boolean;

//проверяет, что граф является сетью и что в сети нет циклов

Type error_vector=array[0..100] of boolean;

var error_connected_i,error_connected_j:error_vector;

i,j:integer;

global_error:boolean;

begin

error_cycle:=false;

error_connected:=false;

for i:=0 to n_event do

begin

error_connected_i[i]:=true;

error_connected_j[i]:=true;

end;

error_connected_i[n_event]:=false;

error_connected_j[0]:=false;

for i:=0 to n_event do

for j:=0 to n_event do

begin

if (works[i,j].existance=true)and (j<=i) then

error_cycle:=true;

if (works[i,j].existance=true)and (i<>n_event) then

error_connected_i[i]:=false;

if (works[i,j].existance=true)and (j<>0) then

error_connected_j[j]:=false;

end;

for i:=0 to n_event do

if (error_connected_i[i]=true) or (error_connected_j[i]=true)then

error_connected:=true;

if (error_cycle=true) or (error_connected=true) then

global_error:=true

else global_error:=false;

check_matrix_existence:=global_error;

end;

function check_combobox(combobox_number:integer):boolean;

// проверяет, что событие, выбранное в качестве начального или

// конечного для работы, существует

var i:integer;

string_existence:boolean;

begin

string_existence:=false;

for i:=0 to n_event do

begin

if combobox_number=1 then

if form1.ComboBox1.Text=event[i].name then string_existence:=true;

if combobox_number=2 then

if form1.ComboBox2.Text=event[i].name then string_existence:=true;

end;

check_combobox:=string_existence;

end;

procedure make_string_longer(long:integer;var short_string:string);

//добавление пробелов к строке short_string до длины long

begin

if length(short_string)<long then

repeat

short_string:=short_string+' ';

until length(short_string)>=long

end;

procedure page_0_visible(tf:boolean);

//видимость/невидимость страницы "размер"

begin

Form1.edit1.Visible:=tf;

Form1.edit2.Visible:=tf;

Form1.label1.Visible:=tf;

Form1.label2.Visible:=tf;

Form1.Button1.Visible:=tf;

end;

procedure page_1_visible(tf:boolean);

//видимость/невидимость страницы "события"

begin

Form1.StringGrid1.Visible:=tf;

Form1.Button2.Visible:=tf;

end;

procedure page_2_visible(tf:boolean);

//видимость/невидимость страницы "работы"

begin

Form1.StringGrid2.Visible:=tf;

Form1.Button3.Visible:=tf;

end;

procedure page_3_visible(tf:boolean);

//видимость/невидимость страницы "данные о работах"

begin

form1.label3.Visible:=tf;

form1.label4.Visible:=tf;

form1.label5.Visible:=tf;

form1.label6.Visible:=tf;

form1.label7.Visible:=tf;

form1.label8.Visible:=tf;

form1.label9.Visible:=tf;

form1.label10.Visible:=tf;

form1.label11.Visible:=tf;

form1.edit3.Visible:=tf;

form1.edit4.Visible:=tf;

form1.edit5.Visible:=tf;

form1.edit6.Visible:=tf;

form1.combobox1.Visible:=tf;

form1.combobox2.Visible:=tf;

form1.memo1.Visible:=tf;

end;

procedure page_4_visible(tf:boolean);

//видимость/невидимость страницы "просмотр данных"

begin

form1.label12.Visible:=tf;

form1.edit7.Visible:=tf;

Form1.StringGrid3.Visible:=tf;

Form1.Button5.Visible:=tf;

Form1.Label17.Visible:=tf;

Form1.Label18.Visible:=tf;

Form1.Label19.Visible:=tf;

Form1.Label21.Visible:=tf;

Form1.Label22.Visible:=tf;

Form1.Label23.Visible:=tf;

end;

procedure page_5_visible(tf:boolean);

//видимость/невидимость страницы "результат"

begin

Form1.StringGrid4.Visible:=tf;

Form1.StringGrid5.Visible:=tf;

Form1.Label13.Visible:=tf;

Form1.Label14.Visible:=tf;

Form1.Label15.Visible:=tf;

Form1.Label16.Visible:=tf;

end;

procedure page_3_clearing;

//начальные значения на страницу "данные о работах"

begin

form1.Memo1.clear;

form1.edit3.Text:='1';

form1.edit4.Text:='20';

form1.edit5.Text:='1';

form1.edit6.Text:='2';

form1.combobox1.text:='';

form1.combobox2.text:='';

end;

procedure work_add(n:integer);

//добавление данных о работе со страницы "данные о работах"

var i,k,m:integer;

begin

work[n].existance:=true;

work[n].initial_event_name:=form1.ComboBox1.text;

work[n].final_event_name:=form1.ComboBox2.Text;

for i:=0 to n_event do

begin

if work[n].initial_event_name=event[i].name then

begin

work[n].initial_event:=event[i].number;

k:=work[n].initial_event;

end;

end;

for i:=0 to n_event do

begin

if work[n].final_event_name=event[i].name then

begin

work[n].final_event:=event[i].number;

m:=work[n].final_event

end;

end;

works[k,m].name:=work[n].name;

works[k,m].existance:=true;

works[k,m].initial_event:=k;

works[k,m].final_event:=m;

works[k,m].initial_event_name:=work[n].initial_event_name;

works[k,m].final_event_name:=work[n].final_event_name;

works[k,m].cost_a:=StrToFloat(form1.edit3.text);

works[k,m].cost_b:=StrToFloat(form1.edit4.text);

works[k,m].d_big:=StrToFloat(form1.edit6.text);

works[k,m].d_little:=StrToFloat(form1.edit5.text);

work[n].cost_a:=StrToFloat(form1.edit3.text);

work[n].cost_b:=StrToFloat(form1.edit4.text);

work[n].d_big:=StrToFloat(form1.edit6.text);

work[n].d_little:=StrToFloat(form1.edit5.text);

end;

procedure from_works_to_work;

//переход от матрицы работ оптимального плана к списку работ

var i,j,k:integer;

begin

for k:=1 to n_work do

for i:=0 to n_event do

for j:=0 to n_event do

begin

if work[k].name=answer_works[i,j].name then

begin

work[k].t:=answer_works[i,j].t;

work[k].cost:=answer_works[i,j].cost;

end;

end;

end;

procedure page_4_view;

//вывод исходных данных

var i:integer;

begin

page_4_visible(true);

form1.StringGrid3.RowCount:=n_work+1;

form1.StringGrid3.cells[0,0]:='номер';

form1.StringGrid3.cells[1,0]:='название';

form1.StringGrid3.cells[2,0]:='(i,j)';

form1.StringGrid3.cells[3,0]:='a[i,j]';

form1.StringGrid3.cells[4,0]:='b[i,j]';

form1.StringGrid3.cells[5,0]:='d[i,j]';

form1.StringGrid3.cells[6,0]:='D[i,j]';

for i:=1 to n_work do

begin

form1.StringGrid3.cells[0,i]:=IntToStr(work[i].number);

form1.StringGrid3.cells[1,i]:=work[i].name;

form1.StringGrid3.cells[2,i]:='('+intToStr(work[i].initial_event)+','

+intToStr(work[i].final_event)+')';

form1.StringGrid3.cells[3,i]:=FloatToStrF(work[i].cost_a,fffixed,5,2);

form1.StringGrid3.cells[4,i]:=FloatToStrF(work[i].cost_b,fffixed,5,2);

form1.StringGrid3.cells[5,i]:=FloatToStrF(work[i].d_little,fffixed,5,2);

form1.StringGrid3.cells[6,i]:=FloatToStrF(work[i].d_big,fffixed,5,2);

end;

end;

procedure output_results;

//вывод результатов

var i:integer;

s,s_name,s_numbers,s_time,s_cost:string;

begin

form1.StringGrid4.RowCount:=n_work+1;

form1.StringGrid4.cells[0,0]:='номер';

form1.StringGrid4.cells[1,0]:='название';

form1.StringGrid4.cells[2,0]:='(i,j)';

form1.StringGrid4.cells[3,0]:='t[i,j]';

form1.StringGrid4.cells[4,0]:='c[i,j]';

for i:=1 to n_work do

begin

form1.StringGrid4.cells[0,i]:=IntToStr(work[i].number);

form1.StringGrid4.cells[1,i]:=work[i].name;

form1.StringGrid4.cells[2,i]:='('+intToStr(work[i].initial_event)+','

+intToStr(work[i].final_event)+')';

form1.StringGrid4.cells[3,i]:=FloatToStrF(work[i].t,fffixed,7,4);

form1.StringGrid4.cells[4,i]:=FloatToStrF(work[i].cost,fffixed,10,4);

end;

form1.StringGrid5.RowCount:=n_event+2;

form1.StringGrid5.cells[0,0]:='номер';

form1.StringGrid5.cells[1,0]:='название';

form1.StringGrid5.cells[2,0]:='T[j]';

for i:=1 to n_event+1 do

begin

form1.StringGrid5.cells[0,i]:=IntToStr(answer_event[i-1].number);

form1.StringGrid5.cells[1,i]:=answer_event[i-1].name;

form1.StringGrid5.cells[2,i]:=

FloatToStrF(answer_event[i-1].early_date,fffixed,7,4);

end;

form1.label14.Caption:=FloatToStrF(cost,fffixed,10,4);

writeln(report,'****************************'); //вывод в файл

writeln(report,'****************************');

writeln(report,'ОТВЕТ');

writeln(report,'работы');

writeln(report,'| имя ||время ||стоимость|');

for i:=1 to n_work do

begin

s:='';

s_name:='|'+work[i].name;

make_string_longer(15,s_name);

s:=s+s_name;

s_numbers:='('+IntToStr(work[i].initial_event)+','+

IntToStr(work[i].final_event)+')';

make_string_longer(9,s_numbers);

s:=s+s_numbers+'||';

s_time:=FloatToStrF(work[i].t,fffixed,5,2);

make_string_longer(10,s_time);

s:=s+s_time+'||';

s_cost:=FloatToStrF(work[i].cost,fffixed,5,2);

make_string_longer(9,s_cost);

s:=s+s_cost+'|';

writeln(report,s);

end;

writeln(report,'ранние сроки свершения событий:');

for i:=0 to n_event do

begin

s:=IntToStr(i)+'-->'+

FloatToStrF(answer_event[i].early_date,fffixed,5,2);

writeln(report,s);

end;

writeln(report,'стоимость=',FloatToStrF(cost,fffixed,5,2));

end;

procedure add_to_file_tabble;

//вывод в файл таблицы поиска максимального потока

var i,j:integer;

s:array[0..100,0..100] of string;

long_s,s0,s1:string;

begin

s0:=' ';

for i:=0 to n_event do

begin

s1:=IntToStr(i);

make_string_longer(10,s1);

s0:=s0+s1;

end;

writeln(report,s0);

for i:=0 to n_event do

for j:=0 to n_event do

begin

if table_full[i,j]=true then

begin

if table[i,j]<infinity/100 then

begin

s[i,j]:='|'+FloatToStrF(table[i,j],fffixed,7,2);

make_string_longer(9,s[i,j]);

s[i,j]:=s[i,j]+'|';

end

else s[i,j]:='|'+'infinity'+'|';

end

else s[i,j]:='|'+'________'+'|';

end;

for i:=0 to n_event do

begin

long_s:=intToStr(i)+' ';

for j:=0 to n_event do

long_s:=long_s+s[i,j];

writeln(report,long_s);

end;

end;

procedure add_to_file_works;

//вывод в файл текущего оптимального плана

var i,j:integer;

s,s1:string;

s_work:array[0..100,0..100] of string;

begin

for i:=0 to n_event do

for j:=0 to n_event do

begin

s_work[i,j]:='|'+FloatToStrF(works[i,j].t,fffixed,7,2);

make_string_longer(9,s_work[i,j]);

s_work[i,j]:=s_work[i,j]+'|';

end;

writeln(report,'длительность работ:');

s:=' ';

for i:=0 to n_event do

begin

s1:=IntToStr(i);

make_string_longer(10,s1);

s:=s+s1;

end;

writeln(report,s);

for i:=0 to n_event do

begin

s:=IntToStr(i);

make_string_longer(3,s);

for j:=0 to n_event do

s:=s+s_work[i,j];

writeln(report,s);

end;

writeln(report,'ранние сроки свершения событий:');

for i:=0 to n_event do

begin

s:=intToStr(i)+'-->'+FloatToStrF(event[i].early_date,fffixed,8,2);

writeln(report,s);

end;

end;

procedure table_padding;

//распределение работ по множествам E1,E2,Q1,Q2,Q3,Q4

var i,j:integer;

s:array[0..100,0..100] of string;

EQ:string;

begin

for i:=0 to n_event do

for j:=i to n_event do

if works[i,j].existance=true then

begin

if (event[j].early_date-event[i].early_date-works[i,j].t=0)

and (works[i,j].t=works[i,j].d_big)

and (works[i,j].t>works[i,j].d_little) then

//E1&Q1

begin

if works[i,j].work_is_cut=false then

begin

table[i,j]:=works[i,j].cost_a;

table[j,i]:=0;

table_full[i,j]:=true;

table_full[j,i]:=true;

s[i,j]:='|E1&Q1|';

s[j,i]:='|_____|';

end;

if works[i,j].work_is_cut=true then

begin

if (event[i].vu_label=false)and(event[j].vu_label=true) then

begin

table[i,j]:=works[i,j].cost_a;

table[j,i]:=0;

table_full[i,j]:=true;

table_full[j,i]:=true;

s[i,j]:='|E1&Q1|';

s[j,i]:='|_____|';

end;

if (event[i].vu_label=true)and(event[j].vu_label=false) then

begin

table[j,i]:=works[i,j].cost_a;

table[i,j]:=0;

table_full[i,j]:=true;

table_full[j,i]:=true;

s[i,j]:='|E1&Q1|';

s[j,i]:='|_____|';

end;

end;

end;

if (event[j].early_date-event[i].early_date-works[i,j].t=0)

and (works[i,j].t=works[i,j].d_big)

and (works[i,j].t=works[i,j].d_little) then

begin

//E1&Q2

table[i,j]:=infinity;

table[j,i]:=0;

table_full[i,j]:=true;

table_full[j,i]:=true;

s[i,j]:='|E1&Q2|';

s[j,i]:='|_____|';

end;

if (event[j].early_date-event[i].early_date-works[i,j].t=0)

and (works[i,j].t<works[i,j].d_big)

and (works[i,j].t=works[i,j].d_little) then

begin

//E1&Q3

table[i,j]:=infinity;

table[j,i]:=0;

table_full[i,j]:=true;

table_full[j,i]:=true;

s[i,j]:='|E1&Q3|';

s[j,i]:='|_____|';

end;

if (event[j].early_date-event[i].early_date-works[i,j].t=0)

and (works[i,j].t<works[i,j].d_big)

and (works[i,j].t>works[i,j].d_little) then

begin

//E1&Q4

table[i,j]:=0;

table[j,i]:=0;

table_full[i,j]:=true;

table_full[j,i]:=true;

s[i,j]:='|E1&Q4|';

s[j,i]:='|_____|';

end;

if (event[j].early_date-event[i].early_date-works[i,j].t>0)

and (works[i,j].t=works[i,j].d_big)

and (works[i,j].t>=works[i,j].d_little) then

begin

//E2

table_full[i,j]:=false;

table_full[j,i]:=false;

s[i,j]:='|__E2_|';

s[j,i]:='|_____|';

end;

end

else

begin

table_full[i,j]:=false;

s[i,j]:='|_____|';

s[j,i]:='|_____|';

end;

writeln(report,'*********************************');

// вывод в файл

for i:=0 to n_event do

write(report,i:7);

writeln(report,'');

for i:=0 to n_event do

begin

EQ:=IntToStr(i);

make_string_longer(3,EQ);

for j:=0 to n_event do

EQ:=EQ+s[i,j];

writeln(report,EQ);

end;

end;

procedure cross_table;

//поиск максимального потока

var i,j:integer;

way_label:array[0..100,0..100] of boolean;

way_label_new:array[0..100,0..100] of boolean;

col_label:array[0..100] of integer;

col_is_pointed:array[0..100] of boolean;

row_is_pointed:array[0..100] of boolean;

plus:array[0..100,0..100] of boolean;

no_way:boolean;

cell_is_pointed:array[0..100,0..100] of boolean;

min:extended;

summa_cost_a:extended;

i_min:integer;

s,s1,col_label_string:string;

plus_minus:array[0..100,0..100]of string;

n:integer;

begin

for i:=0 to n_event do

for j:=0 to n_event do

if works[i,j].existance=true then

works[i,j].work_is_cut:=false;

event[0].vu_label:=false;

no_way:=false;

min:=0;

while (no_way=false)and(min<infinity) do

begin

for i:=0 to n_event do

begin

col_is_pointed[i]:=false;

row_is_pointed[i]:=false;

event[i].vu_label:=true; {in v}

end;

event[0].vu_label:=false;

for i:=0 to n_event do

for j:=0 to n_event do

begin

way_label[i,j]:=false;

cell_is_pointed[i,j]:=false;

way_label_new[i,j]:=false;

end;

row_is_pointed[0]:=true;

for i:=0 to n_event do //поиск путей из 0 в n

for j:=0 to n_event do

if table_full[i,j]=true then

begin

if (table[i,j]>0) and

(col_is_pointed[j]=false)and

(row_is_pointed[i]=true) then

begin

col_label[j]:=i;

col_is_pointed[j]:=true;

row_is_pointed[j]:=true;

way_label[i,j]:=true;

event[j].vu_label:=false; {in u}

end;

end;

if col_is_pointed[n_event]=true then

no_way:=false;

if col_is_pointed[n_event]=false then

no_way:=true;

if (no_way=false) then

begin

for i:=0 to n_event do

if way_label[i,n_event]=true then

begin

cell_is_pointed[i,n_event]:=true;

i_min:=i;

end;

for i:=0 to n_event do

for j:=0 to n_event do

plus_minus[i,j]:='| |';

for j:=n_event downto 1 do //возвращение из n в 0

for i:=n_event downto 0 do

if (way_label[i,j]=true) and (cell_is_pointed[i,j]=true) then

begin

plus[col_label[j],j]:=false;

plus_minus[col_label[j],j]:='| - |';

plus[j,col_label[j]]:=true;

plus_minus[j,col_label[j]]:='| + |';

way_label_new[col_label[j],j]:=true;

way_label_new[j,col_label[j]]:=true;

cell_is_pointed[col_label[col_label[j]],col_label[j]]:=true;

end ;

writeln(report,''); //вывод в файл

add_to_file_tabble;

s:=' ';

for i:=0 to n_event do

begin

s1:=IntToStr(i);

make_string_longer(5,s1);

s:=s+s1;

end;

writeln(report,s);

for i:=0 to n_event do

begin

s:=IntToStr(i);

make_string_longer(3,s);

for j:=0 to n_event do

s:=s+plus_minus[i,j];

writeln(report,s);

end;

min:=table[i_min,n_event]; //поиск пропускной

//способности и пересчет таблицы

for i:=n_event downto 0 do

for j:=n_event downto 0 do

if (plus[i,j]=false) and(table_full[i,j]=true)and

(way_label_new[i,j]=true) then

if table[i,j]<min then

min:=table[i,j];

writeln(report,'h=',FloatToStrF(min,fffixed,7,2));

if min<(infinity) then

begin

for i:=n_event downto 0 do

for j:=n_event downto 0 do

if way_label_new[i,j]=true then

begin

if plus[i,j]=true then

table[i,j]:=table[i,j]+min;

if plus[i,j]=false then

table[i,j]:=table[i,j]-min;

end;

end

else the_end:=true;

end

else add_to_file_tabble;

end;

for i:=0 to n_event do //отмечаются работы, попавшие в сечение

for j:=0 to n_event do

if (works[i,j].existance=true)

and((event[i].vu_label=false)and(event[j].vu_label=true)

or (event[j].vu_label=false)and(event[i].vu_label=true)) then

works[i,j].work_is_cut:=true;

end;

procedure teta_array_clear(var teta_array:T_teta_array);

var i,j:integer;

begin

for i:=0 to n_event do

for j:=0 to n_event do

teta_array[i,j]:=0;

end;

procedure teta_count(teta_array:T_teta_array;

var teta_x:extended);

var i,j:integer;

begin

for i:=0 to n_event do

for j:=0 to n_event do

if (works[i,j].existance=true)and (teta_array[i,j]>0)

and(teta_array[i,j]<teta_x)then

teta_x:=teta_array[i,j];

end;

procedure count_cost;

//расчет стоимости плана

var i,j:integer;

begin

cost:=0;

for i:=0 to n_event do

for j:=0 to n_event do

if works[i,j].existance=true then

begin

works[i,j].cost:=-works[i,j].t*works[i,j].cost_a+works[i,j].cost_b;

cost:=cost+works[i,j].cost;

end;

end;

procedure recount_limit;

//решение двойственной задачи

var i,j:integer;

s,s1:string;

epsilon:array[0..100,0..100] of integer;

atta:array[0..100] of integer;

teta:array[1..3]of extended;

sigma:array[0..100,0..100] of extended;

teta_array:T_teta_array;

teta0:extended;

begin

if the_end=false then

begin

//нахождение переменных двойственной задачи

for i:=0 to n_event do

if event[i].vu_label=true then atta[i]:=1

else atta[i]:=0;

writeln(report,'распределение по множествам {u} и {v}:');

for i:=0 to n_event do

begin

if atta[i]=0 then

s:=IntToStr(i)+'-->'+'u';

if atta[i]=1 then

s:=IntToStr(i)+'-->'+'v';

writeln(report,s);

end;

for i:=0 to n_event do

for j:=0 to n_event do

epsilon[i,j]:=0;

for i:=0 to n_event do

for j:=0 to n_event do

if works[i,j].work_is_cut=true then

begin

if (event[j].early_date-event[i].early_date-works[i,j].t=0)

and (works[i,j].t>works[i,j].d_little)

and (works[i,j].t=works[i,j].d_big)

and (atta[i]=0)and(atta[j]=1)then

//E1&Q1

epsilon[i,j]:=1;

if (event[j].early_date-event[i].early_date-works[i,j].t=0)

and (works[i,j].t>works[i,j].d_little)

and (works[i,j].t<works[i,j].d_big)

and (atta[i]=0)and(atta[j]=1)then

//E1&Q4

epsilon[i,j]:=1;

if (event[j].early_date-event[i].early_date-works[i,j].t=0)

and (works[i,j].t=works[i,j].d_little)

and (works[i,j].t<works[i,j].d_big)

and (atta[i]=1)and(atta[j]=0)then

//E1&Q3

epsilon[i,j]:=-1;

if (event[j].early_date-event[i].early_date-works[i,j].t=0)

and (works[i,j].t>works[i,j].d_little)

and (works[i,j].t<works[i,j].d_big)

and (atta[i]=1)and(atta[j]=0)then

//E1&Q4

epsilon[i,j]:=-1;

end;

writeln(report,'epsilon=');

s:=' ';

for i:=0 to n_event do

begin

s1:=IntToStr(i);

make_string_longer(4,s1);

s:=s+s1;

end;

writeln(report,s);

for i:=0 to n_event do

begin

s:=IntToStr(i);

make_string_longer(3,s);

for j:=0 to n_event do

begin

if epsilon[i,j]=-1 then s:=s+'|-1|';

if epsilon[i,j]=1 then s:=s+'|+1|';

if epsilon[i,j]=0 then s:=s+'|__|';

end;

writeln(report,s);

end;

for i:=1 to 3 do

teta[i]:=0;

for i:=0 to n_event do

for j:=0 to n_event do

if works[i,j].existance=true then

sigma[i,j]:=epsilon[i,j]+atta[i]-atta[j];

teta_array_clear(teta_array);

for i:=0 to n_event do

for j:=0 to n_event do

if (works[i,j].existance=true)and(sigma[i,j]<0) then

begin

teta_array[i,j]:=

(event[j].early_date-event[i].early_date-works[i,j].t)/(-sigma[i,j]);

teta[1]:=teta_array[i,j];

end;

teta_count(teta_array,teta[1]);

teta_array_clear(teta_array);

for i:=0 to n_event do

for j:=0 to n_event do

if (works[i,j].existance=true)and (epsilon[i,j]<>0)then

begin

teta_array[i,j]:=(works[i,j].t-works[i,j].d_big)/epsilon[i,j];

teta[2]:=teta_array[i,j];

end;

teta_count(teta_array,teta[2]);

teta_array_clear(teta_array);

for i:=0 to n_event do

for j:=0 to n_event do

if (works[i,j].existance=true)and (epsilon[i,j]<>0)then

begin

teta_array[i,j]:=(works[i,j].t-works[i,j].d_little)/epsilon[i,j];

teta[3]:=teta_array[i,j];

end;

teta_count(teta_array,teta[3]);

writeln(report,'teta1=',FloatToStrF(teta[1],fffixed,6,2));

writeln(report,'teta2=',FloatToStrF(teta[2],fffixed,6,2));

writeln(report,'teta3=',FloatToStrF(teta[3],fffixed,6,2));

for i:=1 to 3 do

if (teta[i]>0)then teta0:=teta[i];

for i:=1 to 3 do

if (teta[i]>0) and (teta[i]<teta0)then teta0:=teta[i];

if teta0<=0 then the_end:=true

else the_end:=false;

writeln(report,'teta0=',FloatToStrF(teta0,fffixed,6,2));

for i:=0 to n_event do //расчет нового оптимального плана,

for j:=0 to n_event do //сравнение нового Ткр с предыдущим и с Тд

begin

previous_work[i,j]:=works[i,j];

previous.epsilon[i,j]:=epsilon[i,j];

works[i,j].t:=works[i,j].t-teta0*epsilon[i,j];

end;

for i:=0 to n_event do

begin

previous_event[i]:=event[i];

previous.atta[i]:=atta[i];

event[i].early_date:=event[i].early_date-teta0*atta[i];

end;

add_to_file_works;

count_cost;

if (critical_path<=previous_event[n_event].early_date)and

(critical_path>event[n_event].early_date)then

begin

add_to_file_works;

previous.teta0:=0;

if previous.atta[n_event]=1 then

previous.teta0:=previous_event[n_event].early_date-critical_path;

writeln(report,'teta=',FloatToStrF(previous.teta0,fffixed,6,2));

for i:=0 to n_event do

answer_event[i]:=previous_event[i];

for i:=0 to n_event do

answer_event[i].early_date:=previous_event[i].early_date-

(previous.teta0*previous.atta[i]);

for i:=0 to n_event do

for j:=0 to n_event do

answer_works[i,j]:=previous_work[i,j];

for i:=0 to n_event do

for j:=0 to n_event do

answer_works[i,j].t:=previous_work[i,j].t-

(previous.teta0*previous.epsilon[i,j]);

cost:=0;

for i:=0 to n_event do

for j:=0 to n_event do

if answer_works[i,j].existance=true then

begin

answer_works[i,j].cost:=-answer_works[i,j].t*answer_works[i,j].cost_a+

answer_works[i,j].cost_b;

cost:=cost+answer_works[i,j].cost;

end;

the_end:=true;

end;

end;

if (the_end=true) and

(critical_path=critical_path_min)then

begin

for i:=0 to n_event do

for j:=0 to n_event do

answer_works[i,j]:=works[i,j];

for i:=0 to n_event do

answer_event[i]:=event[i];

writeln(report,'teta: нет');

end;

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

TabbedNotebook1.PageIndex:=0;

page_0_visible(true);

edit1.text:='5';

edit2.text:='5';

page_1_visible(false);

page_2_visible(false);

button4.Visible:=false;

page_3_visible(false);

page_4_visible(false);

page_5_visible(false);

form1.Button6.Visible:=false;

end;

procedure TForm1.Button1Click(Sender: TObject);

//ввод количества событий и работ

var i:integer;

begin

if (check_integer(edit1.Text)=true) and (check_integer(edit2.Text)=true) then

begin

n_work:=StrToInt(edit2.Text);

n_event:=StrToInt(edit1.Text);

page_1_visible(true);

StringGrid2.RowCount:=n_work+1;

for i:=1 to n_Work do

begin

StringGrid2.cells[0,i]:=IntToStr(i);

StringGrid2.cells[1,i]:='работа'+IntToStr(i);

end;

StringGrid2.cells[1,0]:='название';

StringGrid2.cells[0,0]:='номер';

StringGrid1.RowCount:=n_event+2;

for i:=1 to n_event+1 do

begin

StringGrid1.cells[0,i]:=IntToStr(i-1);

StringGrid1.cells[1,i]:='событие'+IntToStr(i-1);

end;

StringGrid1.cells[1,0]:='название';

StringGrid1.cells[0,0]:='номер';

end

else showMessage('неверно введена размерность');

end;

procedure TForm1.Button2Click(Sender: TObject);

//ввод названий событий

var i,j:integer;

begin

combobox1.Clear;

combobox2.Clear;

if check_names(n_event+1,1)=true then

begin

for i:=0 to n_event do

begin

event[i].name:=StringGrid1.cells[1,i+1];

event[i].number:=StrToInt(StringGrid1.cells[0,i+1]);

comboBox1.items.Insert(i,event[i].name);

comboBox2.items.Insert(i,event[i].name);

end;

for i:=0 to n_event do

for j:=0 to n_event do

works[i,j].existance:=false;

page_0_visible(false);

page_2_visible(true);

// TabbedNotebook1.PageIndex:=2;

end

else showMessage('имена не должны повторяться!');

end;

procedure TForm1.Button3Click(Sender: TObject);

//ввод названий работ

var i:integer;

begin

if check_names(n_work,2)=true then

begin

for i:=1 to n_Work do

begin

work[i].name:=StringGrid2.cells[1,i];

work[i].number:=StrToInt(StringGrid2.cells[0,i]);

end;

button4.Visible:=true;

work_count:=1;

page_3_clearing;

memo1.lines.add(work[work_count].name);

page_1_visible(false);

page_3_visible(true);

TabbedNotebook1.PageIndex:=3;

page_2_visible(false);

end

else showMessage('имена не должны повторяться!');

end;

function twins(work_number:integer):boolean;

//поиск событий i и j, связанных более чем одной работой

var i:integer;

tf:boolean;

name1,name2:string;

string_number_i,string_number_j:integer;

begin

tf:=true;

string_number_i:=Form1.ComboBox1.ItemIndex;

string_number_j:=Form1.ComboBox2.ItemIndex;

name1:=form1.ComboBox1.items[string_number_i];

name2:=form1.ComboBox2.items[string_number_j];

if work_number>1 then

begin

for i:=1 to work_number do

if (name1=work[i].initial_event_name)and

(name2=work[i].final_event_name)then

tf:=false;

end;

twins:=tf;

end;

procedure TForm1.Button4Click(Sender: TObject);

// кнопка "добавить"

begin

if(work_count<=n_work)and(work_count>0)

and (check_extended(edit3.Text)=true) and (check_extended(edit4.Text)=true)

and (check_extended(edit5.Text)=true)

and (check_extended(edit6.Text)=true)

and (twins(work_count)=true) then

begin

if (check_combobox(1)=true) and(check_combobox(2)=true) then

begin

if strToFloat(edit5.text)<=strToFloat(edit6.text)then

begin

work_add(work_count);

page_3_clearing;

work_count:=1+work_count;

memo1.lines.add(work[work_count].name);

end

else showMessage('D[i,j] не может быть меньше d[i,j]');

end

else showMessage('такого события нет');

end

else

begin

if twins(work_count)=false then

showMessage('между этими событиями уже есть работа')

else

showMessage('ошибка при вводе числа');

end;

if work_count>n_work then

begin

button4.Visible:=false;

page_2_visible(false);

page_3_visible(false);

page_4_view;

end;

end;

procedure count_max_min(max_min:integer;var border:extended);

//расчет Tj

var i,j:integer;

lambda:array[0..100] of extended;

begin

for i:=0 to n_event do

for j:=0 to n_event do

begin

if (works[i,j].existance=true) and (max_min=1) then

works[i,j].t:=works[i,j].d_big;

if (works[i,j].existance=true) and (max_min=0) then

works[i,j].t:=works[i,j].d_little;

end;

event[0].early_date:=0;

for j:=1 to n_event do

begin

event[j].early_date:=0;

for i:=0 to j do

begin

if (works[i,j].existance=true)and (max_min=1)then

lambda[i]:=event[i].early_date+works[i,j].d_big;

if (works[i,j].existance=true)and (max_min=0)then

lambda[i]:=event[i].early_date+works[i,j].d_little;

end;

for i:=0 to j do

begin

if (works[i,j].existance=true) and

(lambda[i]>event[j].early_date) then

event[j].early_date:=lambda[i];

end;

end;

count_cost;

border:=event[n_event].early_date;

if max_min=1 then

begin

form1.Label21.Caption:=FloatToStrF(border,fffixed,12,2);

form1.Label22.Caption:=FloatToStrF(cost,fffixed,12,2);

end;

if max_min=0 then

begin

form1.Label23.Caption:=FloatToStrF(border,fffixed,12,2);

end;

end;

procedure TForm1.Button5Click(Sender: TObject);

//кнопка "расчет"

var i,j:integer;

error_cycle, error_connected:boolean;

s_name,s_events,s_a,s_b,s_d_big,s_d_little,message_string:string;

border_min,border_max:extended;

begin

if (check_extended(edit7.Text)=true) and

(check_matrix_existence(error_cycle,error_connected)=false) then

begin

critical_path:=StrToFloat(edit7.Text);

the_end:=false;

count_max_min(0,border_min);

count_max_min(1,border_max);

critical_path_min:=border_min;

if (critical_path>=border_min) and (critical_path<=border_max) then

begin

AssignFile(report,'net_report.txt');

Rewrite(report);

Writeln(report,'исходные данные:');

Writeln(report,'количество событий: ',n_event:4);

Writeln(report,'количество работ: ',n_work:6);

Writeln(report,'критический путь: ',critical_path:10:3);

Writeln(report,'');

Writeln(report,'данные о событиях:');

for i:=0 to n_event do

Writeln(report,IntToStr(event[i].number)+'_'+event[i].name);

Writeln(report,'');

Writeln(report,'данные о работах:');

Writeln(report,' имя: d[i,j]'+

' D[i,j] a[i,j] b[i,j] ');

for i:=1 to n_work do

begin

s_name:=work[i].name;

make_string_longer(15,s_name);

s_events:='('+IntToStr(work[i].initial_event)+','+

IntToStr(work[i].final_event)+')';

make_string_longer(9,s_events);

s_d_little:=FloatToStrF(work[i].d_little,fffixed,7,3);

make_string_longer(12,s_d_little);

s_d_big:=FloatToStrF(work[i].d_big,fffixed,7,3);

make_string_longer(12,s_d_big);

s_a:=FloatToStrF(work[i].cost_a,fffixed,7,3);

make_string_longer(12,s_a);

s_b:=FloatToStrF(work[i].cost_b,fffixed,7,3);

make_string_longer(12,s_b);

Writeln(report,'|'+s_events+'|'+s_name+'|'+

s_d_little+'|'+s_d_big+'|'+s_a+'|'+s_b);

end;

add_to_file_works;

while the_end=false do

begin

table_padding;

cross_table;

recount_limit;

end;

from_works_to_work;

page_5_visible(true);

output_results;

TabbedNotebook1.PageIndex:=5;

CloseFile(report);

end

else showMessage('для такого Ткр задача не может быть решена')

end

else

begin

if check_extended(edit7.Text)=false then

message_string:='ошибка при вводе числа';

if error_cycle=true then

message_string:='в сети есть циклы';

if error_connected=true then

message_string:='граф не является сетью';

showMessage(message_string);

end;

end;

procedure TForm1.StringGrid3SelectCell(Sender: TObject; ACol,

ARow: Integer; var CanSelect: Boolean);

//выбор работы, данные о которой необходимо изменить

begin

if (ARow<>0) and (ACol=1) then

begin

work_to_change:=ARow;

form1.Button6.Visible:=true;

page_3_visible(true);

form1.ComboBox1.Text:=work[work_to_change].initial_event_name;

form1.ComboBox2.Text:=work[work_to_change].final_event_name;

form1.Edit3.Text:=FloatToStr(work[work_to_change].cost_a);

form1.Edit4.Text:=FloatToStr(work[work_to_change].cost_b);

form1.Edit6.Text:=FloatToStr(work[work_to_change].d_big);

form1.Edit5.Text:=FloatToStr(work[work_to_change].d_little);

TabbedNotebook1.PageIndex:=3;

memo1.lines.add(work[ARow].name);

work[work_to_change].existance:=false;

works[work[work_to_change].initial_event,

work[work_to_change].final_event].existance:=false;

end;

end;

procedure TForm1.Button6Click(Sender: TObject);

//кнопка "изменить"

begin

if (check_combobox(1)=true) and(check_combobox(2)=true) then

begin

work_add(work_to_change);

page_4_view;

TabbedNotebook1.PageIndex:=4;

Page_3_visible(false);

button6.Visible:=false;

end

else showMessage('такого события нет');

end;

end.

Соседние файлы в папке Курсовые по ОАУ