Page d'accueil Description du projet
/******************************************
 *
 *   Cedric Pradalier   2001
 *   mail : http://cedric.pradalier.free.fr/mail.html
 *
 *****************************************/



#include "output.h"
#include "treillis.h"

/* Constructeur
   L'horaire d'arrivee courant est initialise a l'horaire limite
   d'arrivee.
   Durant la construction du treillis, Depart contiendra
   toujours la premiere ligne (so far) utilisee pour pouvoir
   faire les intersections.
*/
CTreillis::CTreillis(CLignes * Larr,CArrets * arrivee,CHoraire Limite)
{
    Depart = new CEtage();
    Depart->ligne = Larr;
    Arrivee = new CEtage();
    Depart->NextEtage = Arrivee;
    Arrivee->PrecEtage = Depart;
    CNoeud * newNoeud = new CNoeud(arrivee);
    newNoeud->horaire = Limite;
    Arrivee->etage.add((CObjet *)newNoeud);
    Arrivee->ligne = Larr;
}



/*Met en place l'arret de depart.
  Apres cette fonction, on ne peut(doit) plus
  rajouter de lignes au treillis
*/
void CTreillis::SetDepart(CArrets * depart)
{
    Depart->etage.add((CObjet *)new CNoeud(depart));
}
    
    



void CTreillis::PushLigne(CLignes * ligne1)
{
//  sprintf(outbuf,"Avant insertion : \n");FlushBuffer();
//  PrintMax();
    CEtage * etage = new CEtage();
    CEnsemble * arrets = new CEnsemble();
    CLignes * ligne2 = Depart->ligne;
    etage->ligne = Depart->ligne;
    Depart->ligne = ligne1;
    /* chainage bidirectionnel */
    Depart->NextEtage->PrecEtage = etage;
    etage->SetNext(Depart->NextEtage);
    etage->SetPrecedent(Depart);
    Depart->SetNext(etage);
    for(int s=0;s<2;s++)
        for(int i=0;i<ligne1->GetNbArret((SensTrajet)s);i++)
        {
            CArrets * arret = ligne1->GetArretAt((SensTrajet) s, i);
            // Les arrets accessibles uniquements en sens unique ne sont 
            // pas pris en compte. A voir si c'est nécessaire. 
            // Il ne peut pas etre intéressant de prendre 2 fois une ligne
            // pour atteindre un tel arret.
            // if (!ligne1->IsUnique(arret) && !ligne2->IsUnique(arret))
            if (ligne2->IsKnown(arret) &&
                (arrets->contains((CObjet*) arret) == -1))
            {
                etage->etage.add((CObjet *)new CNoeud(arret));
                arrets->add((CObjet *) arret);
            }
        }
//  sprintf(outbuf,"Apres insertion : \n");FlushBuffer();
//  PrintMax();
    etage->etage.TrimToSize();
    delete arrets;
}


bool CTreillis::CEtage::MaJHoraires(CHoraire TpsCorresp)
{
    int i,j;
    int NbInvalides;
//  sprintf(outbuf,"MaJHoraires : Etage [%s]\n",ligne->mName);FlushBuffer();
    if (PrecEtage==NULL)
        return false;
//  sprintf(outbuf,"Avant : \n");FlushBuffer();
//  PrecEtage->PrintMax();
    NbInvalides = 0;
    for (i=0;i<etage.GetNbElem();i++)
    {
        for (j=0;j<PrecEtage->etage.GetNbElem();j++)
        {
            CHoraire H;
            CHoraire Limite = ((CNoeud *)etage[i])->horaire - TpsCorresp;
            CNoeud * Depart = ((CNoeud *)(PrecEtage->etage[j]));
            CNoeud * Arrivee = ((CNoeud *)(etage[i]));
//          sprintf(outbuf,"Recherche d'un horaire \n Depart ");FlushBuffer();
//          Depart->Print();
//          sprintf(outbuf,"Arrivee ");FlushBuffer();
//          Arrivee->Print();
//          sprintf(outbuf,"\n");FlushBuffer();
//          Limite.Print();sprintf(outbuf,"\n");FlushBuffer();
        // Si la limite n'est pas valide, meme pas la peine de
        // continuer
        if (Limite.IsValide())
        {
            H = PrecEtage->ligne->Passage(Depart->arret,Arrivee->arret,Limite);
            
            // Un horaire est utilisable s'il est dans le bon intervalle
            if (H.IsValide() && 
                (((H > Depart->horaire) && (Arrivee->horaire > H)) 
                // Ou si on n'a rien d'autre pour l'instant
                || !Depart->horaire.IsValide() ))
                     
            {
//              sprintf(outbuf,"Un horaire VALIDE : ");FlushBuffer();
//              H.Print();
//              sprintf(outbuf," -- ");FlushBuffer();Depart->horaire.Print();
//              sprintf(outbuf,"\n");FlushBuffer();
                Depart->horaire = H;
                Depart->destination = i;
                Arrivee->origine = j;
                Depart->arriveeDest = Limite;
            }
            else
            {
                NbInvalides += 1;
//              sprintf(outbuf,"Un horaire invalide : ");FlushBuffer();
//              H.Print();
//              sprintf(outbuf," -- ");FlushBuffer();Depart->horaire.Print();
//              sprintf(outbuf,"\n");FlushBuffer();
            }
        }
        else
            NbInvalides += 1;
        }
    }
//  sprintf(outbuf,"Nombre d'horaires invalide : %i/%i \n",
//          NbInvalides,
//          PrecEtage->etage.GetNbElem() * etage.GetNbElem());FlushBuffer();
    if (NbInvalides == 
        PrecEtage->etage.GetNbElem() * etage.GetNbElem())
    {
//      sprintf(outbuf,"Rejet de l'itineraire\n");FlushBuffer();
        return false;
    }
//  sprintf(outbuf,"Apres\n");FlushBuffer();
//  PrecEtage->PrintMax();
    return true;
}


bool CTreillis::MaJHoraires(CHoraire TpsCorresp)
{
    CEtage * Iterator = Arrivee->PrecEtage;
//  sprintf(outbuf,"MaJ : Treillis\n");FlushBuffer();
//  PrintMax();
    if (!Arrivee->MaJHoraires(CHoraire(0)))
        return false;
    while (Iterator != NULL)
    {
        if (Iterator->PrecEtage == NULL)
        {
//          sprintf(outbuf,"----------------------\nFin MaJ : Treillis\n");FlushBuffer();
//          PrintMax();
            return true;
        }
        if (!Iterator->MaJHoraires(TpsCorresp))
            return false;
        Iterator = Iterator->PrecEtage;
    }
    return true;
}

void CTreillis::CNoeud::Print()
{
    sprintf(outbuf,"- %s -\n",arret->mNom);FlushBuffer();
    horaire.Print();
}

void CTreillis::PrintMax()
{
    CEtage * Iterator = Depart;
    sprintf(outbuf,"Treillis : \n");FlushBuffer();
    while (Iterator != NULL)
    {
        Iterator->PrintMax();
        sprintf(outbuf,"---------------------------------------\n");FlushBuffer();
        
        Iterator = Iterator->NextEtage;
    }
}
    
void CTreillis::CEtage::PrintMax()
{
    CNoeud * noeud;
    sprintf(outbuf,"Ligne prise : %s\n",ligne->mName);FlushBuffer();
    for(int i=0;i<etage.GetNbElem();i++)
    {
        noeud = ((CNoeud *)(etage[i]));
        noeud->PrintMax();
    }
    sprintf(outbuf,"\n");FlushBuffer();
}
        

void CTreillis::CNoeud::PrintMax()
{
    sprintf(outbuf,"(Id:%i,Ds:%i,",arret->mId,destination);FlushBuffer();
    horaire.Print();
    sprintf(outbuf,")");FlushBuffer();
}

CHoraire CTreillis::Duree()
{
    CNoeud * dep = (CNoeud*)(Depart->etage[0]);
    CNoeud * arr = (CNoeud*)(Arrivee->etage[0]);
    if (arr->origine != -1)
    {
        CNoeud * parr = (CNoeud*)(Arrivee->PrecEtage->etage[arr->origine]);
        return parr->arriveeDest - dep->horaire;
    }
    else
        return HNULL;
}

        
void CTreillis::Print()
{
    CEtage * Iterator = Depart;
    CNoeud * noeud;
    CNoeud * noeudPrec;
    int IndiceCourant;
    noeud = ((CNoeud *)(Iterator->etage[0]));
    noeudPrec = noeud;
    sprintf(outbuf,"Duree : ");FlushBuffer();Duree().Print();
    sprintf(outbuf," - Depart : %s ",noeud->arret->mNom);FlushBuffer();
    noeud->horaire.Print();
    sprintf(outbuf," [%s] \n",Iterator->ligne->mName);FlushBuffer();
    IndiceCourant = noeud->destination;
    Iterator = Iterator->NextEtage;
    while (Iterator->NextEtage != NULL) 
    {
        noeudPrec = noeud;
        noeud = (CNoeud *)(Iterator->etage[IndiceCourant]);
        sprintf(outbuf,"Correspondance : %s - Arrivee ",noeud->arret->mNom);FlushBuffer();
        noeudPrec->arriveeDest.Print();
        sprintf(outbuf,"\n --> Depart : ");FlushBuffer();
        IndiceCourant = noeud->destination;
        noeud->horaire.Print();
        sprintf(outbuf," [%s]\n" ,Iterator->ligne->mName);FlushBuffer();
        Iterator = Iterator->NextEtage;
    }
    noeudPrec = noeud;
    noeud = ((CNoeud *)(Iterator->etage[0]));
    sprintf(outbuf,"Arrivee %s : ",noeud->arret->mNom);FlushBuffer();
    noeudPrec->arriveeDest.Print();
    sprintf(outbuf,"\n");FlushBuffer();
}

int CTreillis::Value()
{
    CHoraire H = Duree();
    return 100*H.heure + H.minute;
}