Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > C/C++: Общие вопросы > Значения выводятся по 2 раза


Автор: compaq 11.04.06, 10:12
Доброго времени суток.
Есть дискретно событийная модель в ней есть основной
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    const int SIZES = 5;
    float ST[SIZES] = {0,32767,32767,32767,32767};

и вспомогательный массив событий
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    const int SIS = 3;
    float SZ[SIS]={0,0,0};
    const int SIQ = 3;
    float SQ[SIQ]={0,0,0};

Есть функция, которая ищет минимальное значение времени и приравнивает основное время с минимальным временем находящемся в массиве, а потом индекс массива передаёт свитчу для того, что бы он вызвал функцию обработки, какова либо события.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void timing()
    {
       int A;
       float* p = std::min_element(ST, ST+SIZES);
       float min_index = p-ST;
       A = StrToInt(min_index);
       Tt = ST[A];
       noms = A;
    }

Есть 2 взаимосвязанных класса Разгрузчик и Транспортёр
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class Transporter;
    class Razgruzhik  /*  Класс Обслуживания   */
    {
    public:
        float T;     /*  время поступления, мин  */
        float Massa; /*  масса зерна, тонн  */
        float SUM;   /*  накапливаем статистику пребывания в системе  */
        float summass;/*  Масса принятого зерна  */
        float massat;/*  масса зерна, имеющегося в бункере */
        int kA;      /*  количество поступивших грузовиков  */
        int Ng;      /*  Номер грузовика  */
        int sost;    /*состояние Разгрузчика равно 0, если Разгрузчика простаивает из-за отсутствия транзактов в очереди;равно 1,  если Разгрузчика
                                           обслуживает транзакт */
                                  
    void FobrRazgruzhik(int i, Transporter& Tr, float proisv, float bunker);// функция обработки
    }Razgr1, Razgr2, Razgr3;
     
    void Razgruzhik::FobrRazgruzhik(int i, Transporter& Tr, float proisv, float bunker )// функция обработки
    {
    //Massa = 0;
          if (sost==1 || sost==2 ) /*если разгрузчик был занятобслуживанием или закончил обслуживание, но не смог высыпать в бункер все зерно по причине его заполненности  */
          {  
          
            if (Massa + Tr.massat <= bunker) //если в бункере достаточно места для зерна из грузовика, то
              {
                SUM += (Tt - T); // накапливаем статистику пребывания в системе
                Tr.massat += Massa;//высыпаем зерно
                //ShowMessage(Massa);
                if (Tr.sost==0)//если транспортер простаивает, включаем его в список событий
                ST[4] = SQ[i] = Tt; /*  вызиваем транспортёрк   */
                kA++; // подсчитываем количество прошедших грузовиков
                  if(! Och3.Ng.empty()) // если есть грузовики в очереди, то
                      {  
                        Ng = Och3.Ng.front();
                        Massa = Och3.Massa.front();
                        T = Och3.T.front();
                        /*  Удаление транзакта   */
                        Och3.Ng.pop();
                        Och3.Massa.pop();
                        Och3.T.pop();
                        ST[3] = SZ[i]= Tt + Massa / proisv;//прогнозируем время освобождения разгрузчика
                        sost = 1;//занимаем разгрузчик
                      }
                   else
                      {
                        ST[3] = 32767;//иначе исключаем разгрузчик из списка событий
                        sost = 0;
                      }
                }
                   else
                      {
                        ST[3] = 32767;//если не улалось высыпать зерно, то тоже исключаем разгрузчик из списка событий по этой причине:
                        sost = 2;
                      }
              }
              else //а сюда мы попадем,если разгрузчик был в состоянии 0:
             // ShowMessage("g");
                  if(! Och3.Ng.empty()) // если есть грузовики в очереди, то
                      {  
                        Ng = Och3.Ng.front();
                        Massa = Och3.Massa.front();
                        T = Och3.T.front();
                        /*  Удаление транзакта   */
                        Och3.Ng.pop();
                        Och3.Massa.pop();
                        Och3.T.pop();
                        ST[3] = SZ[i]= Tt+Massa/proisv;//прогнозируем время освобождения разгрузчика
                        sost = 1;//занимаем разгрузчик
                      }
                   else
                      {
                        ST[3] = 32767; //иначе исключаем разгрузчик из списка событий
                        sost = 0;
                      }
    }

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class Transporter  /*  Класс Транспортёр   */
    {
    public:
    int sost;
    float summass;/*  Масса принятого зерна  */
    float massat;/*  масса зерна, имеющегося в бункере */
    void ObrTransp(int i, Razgruzhik& rasgr, int dm, float proisv, float bunker)
    {
        
        if (massat > 0) /*  если в бункере есть зерно  */
            {
            
                if (massat>=dm) /*  если масса зарна в бункере больше кванта */
                    {
                        ST[4] = SQ[i] = (Tt + dm) / proisv; /* прогнозируем время окончания перетаскивания кванта зерна транспотером */
                        massat -= dm; /* выбираем квант зерна */
                        summass += dm; /*  накапливаем массу принятого зерна  */
                        sost = 1;
                    }
                else
                    {
                        ST[4] = SQ[i] = (Tt + massat) / proisv; /* прогнозируем время окончания перетаскивания остатков  зерна транспотером */
                        summass += massat; /*  накапливаем массу принятого зерна */
                        massat = 0;
                        sost = 1;
                    }
                        if (rasgr.sost==2 && massat + rasgr.Massa <= bunker) /* если разгрузчикпростаивает из-за того, что не смог
                        //высыпать зерно, то мы его включаем в список событий: */
                        ST[3] = Tt;
                        //ShowMessage("ff");
            }
        else //сюда попадем, если зерна в бункере нет
            {
                ST[4] = 32767; /*  Исключаем Транспортёр из списка событий  */
                sost = 0;
            }
    }
    }Transp1, Transp2, Transp3;

Вопрос как можно сделать так что бы определённый разгрузчик вызывал только определённый транспортёр ну как на рисунке.
user posted image
Пробовал так
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    ST[4] = SQ[i] = Tt;

Но так помогает только для того что бы из разгрузчика запустить определённый транспортер а если попробовать из транспорта вызвать разгрузчик то сбивается вся логика.
А ещё вот сами вспомогательные функции которые выбирают какой из аппаратов запускать. Для Разгрузчика
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void ti()
    {
        int A;
        float* p = std::min_element(SZ, SZ+SIS);
        float min_index = p-SZ; //индекс минимального элемента в массиве a
        A = StrToInt(min_index);
        Tt = SZ[A];        
        if(Tt >= SZ[A]) /* Если очередь не является пустой то   */
            {
              switch(A)
                  {
                    case 0:
                            Razgr1.FobrRazgruzhik(0,Transp1,ProizvRazg,Bunker1);// функция обработки
                            break;
                    case 1:
                            Razgr2.FobrRazgruzhik(1,Transp2,ProizvRazg,Bunker2);
                            break;
                    case 2:
                            Razgr3.FobrRazgruzhik(2,Transp3,ProizvRazg,Bunker3);// функция обработки
                            break;
                  }
            }
        else
            {
                ST[3]=32767;
            }
    }

и для Транспортера.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void t()
    {
        int A;
        float* p = std::min_element(SQ, SQ+SIQ);
        float min_index = p-SQ;
        A = StrToInt(min_index);
        Tt = SQ[A];
        if(Tt >= SQ[A])
            {
              switch(A)
                  {
                    case 0:
                            Transp1.ObrTransp(0,Razgr1,Kvant,ProizvTrans,Bunker1);// функция обработки
                            break;
                    case 1:
                            Transp2.ObrTransp(1,Razgr2,Kvant,ProizvTrans,Bunker2);
                            break;
                    case 2:
                            Transp3.ObrTransp(2,Razgr3,Kvant,ProizvTrans,Bunker3);
                    break;
                  }
            }
        else
            {
                ST[3]=32767;
            }
    }

P.S. В аттаче весь код программы. 14 KB
1.cpp

Автор: compaq 11.04.06, 18:05
Ну в обшем у меня значения выводятся 2 я даже не пойму с чего бы это не кто не подскажет куда копать а то я всё перепробовал не чего не выходит.
Думал что транспортёр вызивает разгрузчик и затирает первоначальные параметры ST[3] = Tt; но это по ходу не от этого.
user posted image

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)