Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

лабы / Lab_11 / petry

.doc
Скачиваний:
21
Добавлен:
16.04.2013
Размер:
133.63 Кб
Скачать

winmain.cpp

#include <windows.h>

#include "library.h"

#include "petry.h"

////////////////////////////////////////////////////////////////////////////////////////////////////

CLogFile Log;

////////////////////////////////////////////////////////////////////////////////////////////////////

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

{

CNet Petry;

Log.Setup("log.txt");

Log.Reset();

if(Petry.LoadFromFile("input.txt"))

{

Petry.Run();

Petry.SaveEC("output.txt");

}

return 0;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

library.h

#ifndef LIBRARY

#define LIBRARY

////////////////////////////////////////////////////////////////////////////////////////////////////

#include <stdio.h>

////////////////////////////////////////////////////////////////////////////////////////////////////

class CList //циклический двунаправленный список

{

public:

CList(void);

~CList();

int GetCount(void); //получить длину списка

void Clear(void); //очистить список

void Free(void); //освободить память из-под элементов и очистить список

void Add(void); //добавить элемент после текущего и сделать его текущим

void Delete(void); //удалить текущий элемент и сделать текущим следующий за ним

void* GetData(void); //получить текущее значение

void SetData(void*); //установить текущее значение

void GoBegin(void); //сделать текущим первый элемент

void GoNext(void); //сделать текущим следующий элемент

void GoPrev(void); //сделать текущим предыдущий элемент

struct ListItem //элемент списка

{

void* Data; //данные

ListItem* Next; //указатель на следующий элемент

ListItem* Prev; //указатель на предыдущий элемент

};

private:

int Count; //количество элементов в списке

ListItem* Begin; //первый элемент списка

ListItem* Cur; //текущий элемент списка

};

////////////////////////////////////////////////////////////////////////////////////////////////////

class CLogFile //файл протокола

{

public:

CLogFile(void);

void Setup(char*); //установить имя файла

void Reset(void); //сброс содержимого протокола

void Print(char*, ...); //форматированная запись в протокол (см. printf)

private:

char FileName[256]; //имя файла протокола

};

////////////////////////////////////////////////////////////////////////////////////////////////////

class CSyntaxer //синтаксический анализатор текстовой информации

{

public:

CSyntaxer(void);

~CSyntaxer();

int Open(char*); //открыть файл для анализа

void Close(void); //закрыть файл

int GetWord(char*); //получить слово из файла

int GetNumber(int*); //получить целое число из файла

private:

int SkipComment(void); //пропустить комментарий

int SkipSpaces(void); //пропустить незначащие символы (пробел, табуляция и т.п.)

private:

FILE* file;

};

////////////////////////////////////////////////////////////////////////////////////////////////////

#endif

petry.h

#ifndef PETRY

#define PETRY

////////////////////////////////////////////////////////////////////////////////////////////////////

#include "library.h"

////////////////////////////////////////////////////////////////////////////////////////////////////

struct SItem //состояние

{

int ID; //идентификатор

int M; //количество меток в состоянии

CList TS; //список входящих связей

CList ST; //список выходящих связей

};

////////////////////////////////////////////////////////////////////////////////////////////////////

struct TItem //переход

{

int ID; //идентификатор

bool A; //флаг активности

int D; //время активности

CList ST; //список входящих связей

CList TS; //список выходящих связей

};

////////////////////////////////////////////////////////////////////////////////////////////////////

struct STItem //ST связь

{

int N; //количество захватываемых меток

SItem* S; //состояние-источник

TItem* T; //переход-приемник

};

////////////////////////////////////////////////////////////////////////////////////////////////////

struct TSItem //TS связь

{

int N; //количество отдаваемых меток

TItem* T; //переход-источник

SItem* S; //состояние-приемник

};

////////////////////////////////////////////////////////////////////////////////////////////////////

struct SPItem //описание внешнего воздействия

{

SItem* S; //объект воздействия

int P; //момент воздействия

int M; //количество добавляемых меток

};

////////////////////////////////////////////////////////////////////////////////////////////////////

struct TPItem //описание активного перехода

{

TItem* T; //переход

int P; //момент конца активности

};

////////////////////////////////////////////////////////////////////////////////////////////////////

struct ECItem //элемент календаря событий

{

TItem* T; //переход

int P1; //момент начала активности

int P2; //момент конца активности

};

////////////////////////////////////////////////////////////////////////////////////////////////////

class CNet //сеть Петри

{

public:

~CNet();

int LoadFromFile(char*); //загрузить информацию о сети из файла

int Run(void); //начать работу сети

void Clear(void); //очистить сеть

int SaveEC(char*); //сохранить календарь событий в файле

private:

int LoadS(void); //загрузить S из файла

int LoadT(void); //загрузить T из файла

int LoadST(void); //загрузить ST из файла

int LoadTS(void); //загрузить TS из файла

int LoadSP(void); //загрузить SP из файла

int LoadTP(void); //загрузить TP из файла

int SetupS(void); //настроить списки связей для S

int SetupT(void); //настроить списки связей для T

int Prepare(void); //подготовить EC к началу работы сети

int Finish(void); //завершить выполнение переходов

int External(void); //выполнить внешние воздействия

int Start(void); //начать выполнение переходов

private:

CList S; //список состояний

CList T; //список переходов

CList ST; //список ST связей

CList TS; //список TS связей

CList SP; //протокол внешних воздействий

CList TP; //протокол активных переходов

CList EC; //календарь событий

CSyntaxer Stx; //необходим для загрузки файлов

int Time; //текущее время

};

////////////////////////////////////////////////////////////////////////////////////////////////////

#endif

library.cpp

#include "library.h"

#include <stdio.h>

#include <string.h>

#include <stdarg.h>

////////////////////////////////////////////////////////////////////////////////////////////////////

CList::CList(void)

{

Count = 0;

Begin = 0;

Cur = 0;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

CList::~CList()

{

Clear();

}

////////////////////////////////////////////////////////////////////////////////////////////////////

void CList::Clear(void)

{

while(Cur)

Delete();

}

////////////////////////////////////////////////////////////////////////////////////////////////////

void CList::Free(void)

{

void* p;

while(Cur)

{

p = GetData();

if(p)

delete p;

Delete();

}

}

////////////////////////////////////////////////////////////////////////////////////////////////////

void CList::Delete(void)

{

ListItem* n;

ListItem* p;

//если список пустой

if(!Cur)

return;

//если в списке один элемент

if(Cur->Next == Cur)

{

delete Cur;

Begin = 0;

Cur = 0;

}

//если в списке более одного элемента

else

{

n = Cur->Next;

p = Cur->Prev;

delete Cur;

p->Next = n;

n->Prev = p;

Cur = n;

}

--Count;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CList::GetCount(void)

{

return Count;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

void CList::Add(void)

{

ListItem* t;

ListItem* n;

//создать элемент

t = new ListItem;

if(!t)

return;

t->Data = 0;

//если список пустой

if(!Cur)

{

t->Next = t;

t->Prev = t;

Begin = t;

}

//если список непустой

else

{

n = Cur->Next;

t->Next = n;

t->Prev = Cur;

Cur->Next = t;

n->Prev = t;

}

Cur = t;

++Count;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

void CList::GoBegin(void)

{

Cur = Begin;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

void CList::GoNext(void)

{

if(Cur)

Cur = Cur->Next;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

void CList::GoPrev(void)

{

if(Cur)

Cur = Cur->Prev;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

void* CList::GetData(void)

{

if(!Cur)

return 0;

return Cur->Data;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

void CList::SetData(void* p)

{

if(!Cur)

return;

Cur->Data = p;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

CLogFile::CLogFile(void)

{

FileName[0] = 0;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

void CLogFile::Setup(char* fn)

{

strcpy(FileName, fn);

}

////////////////////////////////////////////////////////////////////////////////////////////////////

void CLogFile::Reset(void)

{

FILE* f;

f = fopen(FileName, "w");

if(f)

fclose(f);

}

////////////////////////////////////////////////////////////////////////////////////////////////////

void CLogFile::Print(char* str, ...)

{

FILE* f;

va_list v;

if(!str)

return;

f = fopen(FileName, "a");

if(!f)

return;

//запись в протокол

va_start(v, str);

vfprintf(f, str, v);

va_end(v);

fclose(f);

}

////////////////////////////////////////////////////////////////////////////////////////////////////

CSyntaxer::CSyntaxer(void)

{

file = 0;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

CSyntaxer::~CSyntaxer()

{

Close();

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CSyntaxer::Open(char* fn)

{

Close();

file = fopen(fn, "rb");

if(!file)

return 0;

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

void CSyntaxer::Close(void)

{

if(file)

{

fclose(file);

file = 0;

}

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CSyntaxer::SkipComment(void)

{

int c;

if(!file)

return 0;

while(1)

{

c = getc(file);

if(c == -1 || c == '\n')

break;

}

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CSyntaxer::SkipSpaces(void)

{

int c;

if(!file)

return 0;

while(1)

{

c = getc(file);

if(c == -1)

break;

if(c == ' ' || c == '\t' || c == '\n' || c == '\r')

continue;

if(c == ';')

{

if(!SkipComment())

return 0;

continue;

}

fseek(file, ftell(file) - 1, 0);

break;

}

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CSyntaxer::GetWord(char* str)

{

int c;

int i;

*str = 0;

if(!file)

return 0;

//чтение слова

if(!SkipSpaces())

return 0;

i = 0;

while(1)

{

c = getc(file);

if(c == -1 || c == ' ' || c == '\t' || c == '\r' || c == '\n')

{

if(!i)

return 0;

break;

}

if(c == ';')

{

if(!i)

return 0;

fseek(file, ftell(file) - 1, 0);

break;

}

if(c >= 'A' && c <= 'Z')

{

str[i] = c;

++i;

continue;

}

if(c >= 'a' && c <= 'z')

{

str[i] = c;

++i;

continue;

}

return 0;

}

str[i] = 0;

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CSyntaxer::GetNumber(int* num)

{

int c;

bool minus;

bool empty;

*num = 0;

if(!file)

return 0;

//чтение числа

if(!SkipSpaces())

return 0;

minus = false;

empty = true;

while(1)

{

c = getc(file);

if(c == -1 || c == ' ' || c == '\t' || c == '\r' || c == '\n')

{

if(empty)

return 0;

break;

}

if(c == ';')

{

if(empty)

return 0;

fseek(file, ftell(file) - 1, 0);

break;

}

if(c == '-')

{

if(minus)

return 0;

minus = true;

continue;

}

if(c >= '0' && c <= '9')

{

*num = int(*num * 10 + (c - '0'));

empty = false;

continue;

}

return 0;

}

if(minus)

*num *= -1;

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

petry.cpp

#include "petry.h"

#include <string.h>

////////////////////////////////////////////////////////////////////////////////////////////////////

extern CLogFile Log;

////////////////////////////////////////////////////////////////////////////////////////////////////

CNet::~CNet()

{

Clear();

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CNet::LoadS(void)

{

int x, i;

SItem* p;

//чтение параметров S

Log.Print(" S: ");

if(!Stx.GetNumber(&x))

{

Log.Print("ID=???");

return 0;

}

Log.Print("ID=%d\n", x);

//проверка дублирования ID'а

for(i = 0; i < S.GetCount(); ++i)

{

p = (SItem*)S.GetData();

if(p->ID == x)

{

Log.Print(" Элемент S с таким ID уже есть\n");

return 0;

}

S.GoNext();

}

p = 0;

//вставка нового S в список

p = new SItem;

if(!p)

{

Log.Print(" Не хватает памяти\n");

return 0;

}

S.Add();

S.SetData((void*)p);

//задание параметров S

p->ID = x;

p->M = 0;

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CNet::LoadT(void)

{

int x, y, i;

TItem* p;

//чтение параметров T

Log.Print(" T: ");

if(!Stx.GetNumber(&x))

{

Log.Print("ID=???");

return 0;

}

Log.Print("ID=%d ", x);

if(!Stx.GetNumber(&y))

{

Log.Print("D=???");

return 0;

}

Log.Print("D=%d\n", y);

//проверка дублирования ID'а

for(i = 0; i < T.GetCount(); ++i)

{

p = (TItem*)T.GetData();

if(p->ID == x)

{

Log.Print(" Элемент T с таким ID уже есть\n");

return 0;

}

T.GoNext();

}

p = 0;

//вставка нового T в список

p = new TItem;

if(!p)

{

Log.Print(" Не хватает памяти\n");

return 0;

}

T.Add();

T.SetData((void*)p);

//задание параметров T

p->ID = x;

p->D = y;

p->A = false;

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CNet::LoadST(void)

{

int x, y, z, i;

SItem* ps;

TItem* pt;

STItem* pst;

//чтение параметров ST

Log.Print(" ST: ");

if(!Stx.GetNumber(&x))

{

Log.Print("S=???");

return 0;

}

Log.Print("S=%d ", x);

if(!Stx.GetNumber(&y))

{

Log.Print("T=???");

return 0;

}

Log.Print("T=%d ", y);

if(!Stx.GetNumber(&z))

{

Log.Print("N=???");

return 0;

}

Log.Print("N=%d\n", z);

//проверка существования ID'а S

for(i = 0; i < S.GetCount(); ++i)

{

ps = (SItem*)S.GetData();

if(ps->ID == x)

{

i = -1;

break;

}

S.GoNext();

}

if(i > -1)

{

Log.Print(" Нет элемента S с таким ID\n");

return 0;

}

//проверка существования ID'а T

for(i = 0; i < T.GetCount(); ++i)

{

pt = (TItem*)T.GetData();

if(pt->ID == y)

{

i = -1;

break;

}

T.GoNext();

}

if(i > -1)

{

Log.Print(" Нет элемента T с таким ID\n");

return 0;

}

//поиск такой же связи

for(i = 0; i < ST.GetCount(); ++i)

{

pst = (STItem*)ST.GetData();

if(pst->S == ps && pst->T == pt)

{

Log.Print(" Такая связь уже существует\n");

return 0;

}

ST.GoNext();

}

pst = 0;

//вставка нового ST в список

pst = new STItem;

if(!pst)

{

Log.Print(" Не хватает памяти\n");

return 0;

}

ST.Add();

ST.SetData((void*)pst);

//задание параметров ST

pst->N = z;

pst->S = ps;

pst->T = pt;

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CNet::LoadTS(void)

{

int x, y, z, i;

SItem* ps;

TItem* pt;

TSItem* pts;

//чтение параметров TS

Log.Print(" TS: ");

if(!Stx.GetNumber(&x))

{

Log.Print("T=???");

return 0;

}

Log.Print("T=%d ", x);

if(!Stx.GetNumber(&y))

{

Log.Print("S=???");

return 0;

}

Log.Print("S=%d ", y);

if(!Stx.GetNumber(&z))

{

Log.Print("N=???");

return 0;

}

Log.Print("N=%d\n", z);

//проверка существования ID'а T

for(i = 0; i < T.GetCount(); ++i)

{

pt = (TItem*)T.GetData();

if(pt->ID == x)

{

i = -1;

break;

}

T.GoNext();

}

if(i > -1)

{

Log.Print(" Нет элемента T с таким ID\n");

return 0;

}

//проверка существования ID'а S

for(i = 0; i < S.GetCount(); ++i)

{

ps = (SItem*)S.GetData();

if(ps->ID == y)

{

i = -1;

break;

}

S.GoNext();

}

if(i > -1)

{

Log.Print(" Нет элемента S с таким ID\n");

return 0;

}

//поиск такой же связи

for(i = 0; i < TS.GetCount(); ++i)

{

pts = (TSItem*)TS.GetData();

if(pts->S == ps && pts->T == pt)

{

Log.Print(" Такая связь уже существует\n");

return 0;

}

TS.GoNext();

}

pts = 0;

//вставка нового TS в список

pts = new TSItem;

if(!pts)

{

Log.Print(" Не хватает памяти\n");

return 0;

}

TS.Add();

TS.SetData((void*)pts);

//задание параметров TS

pts->N = z;

pts->T = pt;

pts->S = ps;

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CNet::LoadSP(void)

{

int x, y, z, i;

SItem* ps;

SPItem* psp;

//чтение параметров SP

Log.Print(" SP: ");

if(!Stx.GetNumber(&x))

{

Log.Print("S=???");

return 0;

}

Log.Print("S=%d ", x);

if(!Stx.GetNumber(&y))

{

Log.Print("P=???");

return 0;

}

Log.Print("P=%d ", y);

if(!Stx.GetNumber(&z))

{

Log.Print("M=???");

return 0;

}

Log.Print("M=%d\n", z);

//проверка существования ID'а S

for(i = 0; i < S.GetCount(); ++i)

{

ps = (SItem*)S.GetData();

if(ps->ID == x)

{

i = -1;

break;

}

S.GoNext();

}

if(i > -1)

{

Log.Print(" Нет элемента S с таким ID\n");

return 0;

}

//вставка нового SP в список

psp = new SPItem;

if(!psp)

{

Log.Print(" Не хватает памяти\n");

return 0;

}

SP.Add();

SP.SetData((void*)psp);

//задание параметров SP

psp->S = ps;

psp->P = y;

psp->M = z;

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CNet::LoadTP(void)

{

int x, y, i;

TItem* pt;

TPItem* ptp;

//чтение параметров TP

Log.Print(" TP: ");

if(!Stx.GetNumber(&x))

{

Log.Print("T=???");

return 0;

}

Log.Print("T=%d ", x);

if(!Stx.GetNumber(&y))

{

Log.Print("P=???");

return 0;

}

Log.Print("P=%d\n", y);

//проверка существования ID'а T

for(i = 0; i < T.GetCount(); ++i)

{

pt = (TItem*)T.GetData();

if(pt->ID == x)

{

i = -1;

break;

}

T.GoNext();

}

if(i > -1)

{

Log.Print(" Нет элемента T с таким ID\n");

return 0;

}

//вставка нового TP в список

ptp = new TPItem;

if(!ptp)

{

Log.Print(" Не хватает памяти\n");

return 0;

}

TP.Add();

TP.SetData((void*)ptp);

//задание параметров TP

ptp->T = pt;

ptp->P = y;

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CNet::SetupS(void)

{

int i, j;

SItem* ps;

STItem* pst;

TSItem* pts;

Log.Print(" Настройка списка связей для элементов S...\n");

//пройти по всем элементам S

for(i = 0; i < S.GetCount(); ++i)

{

ps = (SItem*)S.GetData();

//пройти по всем элементам ST

for(j = 0; j < ST.GetCount(); ++j)

{

pst = (STItem*)ST.GetData();

if(pst->S == ps)

{

//добавить pst в список выходящих связей

ps->ST.Add();

ps->ST.SetData((void*)pst);

}

ST.GoNext();

}

//пройти по всем элементам TS

for(j = 0; j < TS.GetCount(); ++j)

{

pts = (TSItem*)TS.GetData();

if(pts->S == ps)

{

//добавить pts в список входящих связей

ps->TS.Add();

ps->TS.SetData((void*)pts);

}

TS.GoNext();

}

S.GoNext();

}

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CNet::SetupT(void)

{

int i, j;

TItem* pt;

STItem* pst;

TSItem* pts;

Log.Print(" Настройка списка связей для элементов T...\n");

//пройти по всем элементам T

for(i = 0; i < T.GetCount(); ++i)

{

pt = (TItem*)T.GetData();

//пройти по всем элементам ST

for(j = 0; j < ST.GetCount(); ++j)

{

pst = (STItem*)ST.GetData();

if(pst->T == pt)

{

//добавить pst в список входящих связей

pt->ST.Add();

pt->ST.SetData((void*)pst);

}

ST.GoNext();

}

//пройти по всем элементам TS

for(j = 0; j < TS.GetCount(); ++j)

{

pts = (TSItem*)TS.GetData();

if(pts->T == pt)

{

//добавить pts в список выходящих связей

pt->TS.Add();

pt->TS.SetData((void*)pts);

}

TS.GoNext();

}

T.GoNext();

}

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CNet::SaveEC(char* fn)

{

int i;

ECItem* pec;

CLogFile Out;

Log.Print("Сохранение календаря событий в файле %s...\n", fn);

Out.Setup(fn);

Out.Reset();

Out.Print("Tid\tSTm\tETm\n");

Out.Print("------- ------- -------\n");

EC.GoBegin();

for(i = 0; i < EC.GetCount(); ++i)

{

pec = (ECItem*)EC.GetData();

Out.Print("%d\t%d\t%d\n", pec->T->ID, pec->P1, pec->P2);

EC.GoNext();

}

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CNet::LoadFromFile(char* fn)

{

char str[20];

Log.Print("Загрузка сети из файла %s...\n", fn);

if(!Stx.Open(fn))

{

Log.Print(" Не удалось открыть файл\n");

return 0;

}

//цикл чтения файла

Log.Print(" Протокол чтения файла:\n");

while(1)

{

if(!Stx.GetWord(str))

break;

//найдено описание S

if(!strcmp(str, "S"))

{

if(!LoadS())

return 0;

continue;

}

//найдено описание T

if(!strcmp(str, "T"))

{

if(!LoadT())

return 0;

continue;

}

//найдено описание ST

if(!strcmp(str, "ST"))

{

if(!LoadST())

return 0;

continue;

}

//найдено описание TS

if(!strcmp(str, "TS"))

{

if(!LoadTS())

return 0;

continue;

}

//найдено описание SP

if(!strcmp(str, "SP"))

{

if(!LoadSP())

return 0;

continue;

}

//найдено описание TP

if(!strcmp(str, "TP"))

{

if(!LoadTP())

return 0;

continue;

}

//найдено незнакомое слово

Log.Print(" Незнакомая команда: %s\n", str);

return 0;

}

//настроить списки связей для S и T

if(!SetupS())

return 0;

if(!SetupT())

return 0;

Log.Print(" Загрузка сети успешно завершена\n");

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

void CNet::Clear(void)

{

Log.Print("Очистка сети...\n");

S.Free();

T.Free();

ST.Free();

TS.Free();

SP.Free();

TP.Free();

EC.Free();

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CNet::Prepare(void)

{

int i;

TPItem* ptp;

ECItem* pec;

Log.Print(" Подготовка календаря событий...\n");

//проход по всем TP

for(i = 0; i < TP.GetCount(); ++i)

{

pec = new ECItem;

if(!pec)

{

Log.Print(" Не хватает памяти\n");

return 0;

}

ptp = (TPItem*)TP.GetData();

pec->P1 = -1;

pec->P2 = ptp->P;

pec->T = ptp->T;

pec->T->A = true;

EC.Add();

EC.SetData((void*)pec);

Log.Print(" EC: T=%d P1=%d P2=%d\n", pec->T->ID, pec->P1, pec->P2);

TP.GoNext();

}

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CNet::Finish(void)

{

int i, j;

ECItem* pec;

TSItem* pts;

//поиск завершающихся T в EC

for(i = 0; i < EC.GetCount(); ++i)

{

pec = (ECItem*)EC.GetData();

if(pec->P2 == Time)

{

Log.Print(" Time=%-5d T%d завершен: ", Time, pec->T->ID);

pec->T->A = false;

//проход по всем выходящим связям pec->T

for(j = 0; j < pec->T->TS.GetCount(); ++j)

{

pts = (TSItem*)pec->T->TS.GetData();

pts->S->M += pts->N;

Log.Print("S%d=%d ", pts->S->ID, pts->S->M);

pec->T->TS.GoNext();

}

Log.Print("\n");

}

EC.GoNext();

}

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CNet::External(void)

{

int i;

SPItem* psp;

//поиск внешних воздействий

for(i = 0; i < SP.GetCount(); ++i)

{

psp = (SPItem*)SP.GetData();

if(psp->P == Time)

{

psp->S->M += psp->M;

Log.Print(" Time=%-5d S%d=%d\n", Time, psp->S->ID, psp->S->M);

}

SP.GoNext();

}

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CNet::Start(void)

{

int i, j;

TItem* pt;

STItem* pst;

ECItem* pec;

bool flag;

//проход по всем T

for(i = 0; i < T.GetCount(); ++i)

{

pt = (TItem*)T.GetData();

if(pt->A)

{

T.GoNext();

continue;

}

//проверка достаточности меток

flag = true;

for(j = 0; j < pt->ST.GetCount(); ++j)

{

pst = (STItem*)pt->ST.GetData();

if(pst->S->M < pst->N)

{

flag = false;

break;

}

pt->ST.GoNext();

}

//активизация перехода

if(flag)

{

Log.Print(" Time=%-5d T%d активен: ", Time, pt->ID);

pt->A = true;

//забрать метки из S

for(j = 0; j < pt->ST.GetCount(); ++j)

{

pst = (STItem*)pt->ST.GetData();

pst->S->M -= pst->N;

Log.Print("S%d=%d ", pst->S->ID, pst->S->M);

pt->ST.GoNext();

}

Log.Print("\n");

//добавить запись в EC

pec = new ECItem;

if(!pec)

{

Log.Print(" Не хватает памяти\n");

return 0;

}

pec->P1 = Time;

pec->P2 = Time + pt->D;

pec->T = pt;

EC.Add();

EC.SetData((void*)pec);

}

T.GoNext();

}

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

int CNet::Run(void)

{

Log.Print("Работа сети...\n");

if(!Prepare())

return 0;

Time = 0;

S.GoBegin();

T.GoBegin();

ST.GoBegin();

TS.GoBegin();

SP.GoBegin();

TP.GoBegin();

while(Time < 100) //условие окончания работы сети ???

{

if(!Finish())

return 0;

if(!External())

return 0;

if(!Start())

return 0;

++Time;

}

return 1;

}

////////////////////////////////////////////////////////////////////////////////////////////////////

input.txt

;---------------------------------------

;S id

;------ -------

S 1

S 2

S 3

S 4

;---------------------------------------

;T id d

;------ ------- -------

T 1 10

T 2 10

;---------------------------------------

;ST sid tid m

;------ ------- ------- -------

ST 1 1 1

ST 2 1 2

ST 3 2 2

;---------------------------------------

;TS tid sid m

;------ ------- ------- -------

TS 1 1 1

TS 1 3 1

TS 2 3 1

TS 2 4 1

;---------------------------------------

;SP sid p m

;------ ------- ------- -------

SP 1 0 1

SP 2 0 4

;---------------------------------------

;TP tid p

;------ ------- -------

output.txt

Tid STm ETm

------- ------- -------

1 0 10

1 10 20

Соседние файлы в папке Lab_11