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

лабы / Lab_11 / petry

.cpp
Скачиваний:
19
Добавлен:
16.04.2013
Размер:
19.59 Кб
Скачать
#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;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
Соседние файлы в папке Lab_11