/******************************************
*
* 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;
}