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



#include "recherche.h"
#include "lignes.h"
#include "lignes_gen.h"
#include "arrets.h"
#include "horaire.h"
#include "vector.h"
#include "ensemble.h"
#include "corresp.h"
#include "date.h"
#include "treillis.h"
#include "output.h"
#include <string.h>



/* Recherche l'itineraire permettant d'aller de l'arret IndDepart, a l'arret
   IndArrivee avant limite connaissant la BD des arrets, la BD des lignes
   et le nombre max de correspondance que l'on tolere */
void Recherche(CBDArrets * pBDA, CBDLignes * pBDL, CommunicationStruct * S)
{
    // D'abord trouver les arrets depart et arrivee */
    CArrets * ADep = S->ADep;
    CArrets * AArr = S->AArr;
    CVector Etape; // tableau des ensembles de correspondances
//  CVector S->Itineraires; // tableau des itineraires
    // Ensemble intermediaire pour parcourir le graphe
    CEnsemble * Li,* Lj,* Lt; // j = i+1
    CEnsemble LignesSensUnique;
    //  bool DepartSensUnique = false; // A priori, le départ n'est pas un 
    // arret desservi en sens unique
    int i,j,k;


    /******************************************************
Principe : A chaque etape Li contient l'ensemble des 
arrets qu'on peut atteindre (en i correspondance).
-- Initialement, Li contient les correspondances constituees
de l'arret de depart et des lignes presentes a cet arret --

Ensuite, Pour chaque arret deja atteint, on calcule toutes
les lignes accessibles dans Lk, on extrait ensuite celles qui sont
nouvelles et on les met dans Lj qui devient Li pour l'iteration 
suivante 
     ***********************************************************/

    // #define DEBUG



    Li = new CEnsemble;
#ifdef DEBUG
    sprintf(outbuf,"Extraction lignes presentes \n");
    FlushBuffer();
#endif
    ADep->ExtraitPresentes(Li,pBDL);
    S->ArretDepSensUnique = false;

    // On recherche si l'arret de depart est desservi
    // en sens unique.
    for (j=0;j<Li->GetNbElem();j++)
    {
        CCorresp * L = (CCorresp *)Li->ElemAt(j);
        if (L->ligne->IsUnique(ADep))
        {
            LignesSensUnique.ajoute((CObjet *) L);
            S->ArretDepSensUnique = true;
#ifdef DEBUG
            sprintf(outbuf,"ATTENTION : Sur la ligne %s, l'arret \n\t%s est desservi en sens unique \n",
                    L->ligne->mName,ADep->mNom);
            FlushBuffer();
#endif
        }
    }

    Etape.add((CObjet *)Li);

#ifdef DEBUG
    sprintf(outbuf,"Extraction OK\n");
    FlushBuffer();
#endif
    // On itere sur le nombre maximum de correspondances
    // autorisées.
    for (i=0;i<S->MaxNbCorresp;i++)
    {
#ifdef DEBUG
        sprintf(outbuf,"Correspondance %i \n",i);
        FlushBuffer();
#endif
        Lj = new CEnsemble;
#ifdef DEBUG
        sprintf(outbuf,"#Li : %i \n",Li->GetNbElem());
        FlushBuffer();
#endif
        /* Pour tous les elem de Li */
        for (j=0;j<Li->GetNbElem();j++)
        {
            CCorresp * L = (CCorresp *)Li->ElemAt(j);
            /********************************************** 
              Si l'arret d'arrivee appartient a la
              ligne etudiee, on est arrivee, on ajoute
              l'itineraires constitue de la liste chainee
              des correspondance empruntees jusqu'alors
              a l'ensemble des itineraires connus et 
              on s'arrete la 
             ***********************************************/

            if (L->ligne->IsKnown(AArr))
            {
                S->Itineraires.add(L->ExtraitTreillis(ADep,AArr,S->Limite));
                if (L->ligne->IsUnique(AArr))
                {
#ifdef DEBUG
                    sprintf(outbuf,"Arrivée : Sur la ligne %s, l'arret %s est unique \n",
                            L->ligne->mName,AArr->mNom);
                    FlushBuffer();
#endif
                    CCorresp corr(*L);
                    corr.precedent = L;
                    S->Itineraires.add(corr.ExtraitTreillis(ADep,AArr,S->Limite));
                }
            }
            else
            {
                Lt = new CEnsemble;
#ifdef DEBUG
                sprintf(outbuf,":(\n");
                FlushBuffer();
#endif
                // Sinon on extrait les lignes 
                // accessibles dans Lt
                L->ExtraitAccessibles(Lt,pBDL);
#ifdef DEBUG
                sprintf(outbuf,"%s :| %i \n",L->ligne->mName,Lt->GetNbElem());
                FlushBuffer();
#endif
                /***************************************
                  Pour toutes les lignes accessibles :
                  si on ne les a pas utilises sur cet
                  itineraires, on construit une 
                  nouvelle correspondance
                 ***************************************/
                for (k=0;k<Lt->GetNbElem();k++)
                {
#ifdef DEBUG
                    sprintf(outbuf,"element %i\n",k);
                    FlushBuffer();
#endif
                    CCorresp * corresp=(CCorresp *)Lt->ElemAt(k);
#ifdef DEBUG
                    sprintf(outbuf,"A-t-on deja utilise cette ligne ? [%s] \n",corresp->ligne->mName);
                    FlushBuffer();
#endif
                    if (!L->Contains(corresp->ligne))
                    {
#ifdef DEBUG
                        sprintf(outbuf,"Baah non !\n");
                        FlushBuffer();
#endif
                        Lj->ajoute((CObjet *)corresp);
                    }
                    else  
                    {
#ifdef DEBUG
                        sprintf(outbuf,"Baah oui !\n");
                        FlushBuffer();
#endif
                        delete corresp;
                    }
                }
                delete Lt;
            }
        }
        Etape.add((CObjet *)Lj);
        Li = Lj;
    }

    S->NbItinTrouves = S->Itineraires.GetNbElem();
#ifdef DEBUG
    sprintf(outbuf,"Recherche itineraires effectuee.\n");
    FlushBuffer();
    sprintf(outbuf,"--> %i itineraires trouves\n",S->Itineraires.GetNbElem());
    FlushBuffer();
    sprintf(outbuf,"Mise a jour des horaires de correspondance.\n");
    FlushBuffer();
#endif
    /************************************************
      Quand on a tous les itineraires,
      on met a jours les horaires et on supprime
      l'itineraire quand il y a un pb 
     ************************************************/
    int NbSupprimes = 0;
    for (i=S->Itineraires.GetNbElem()-1;i>=0;i--)
    {
        CTreillis * iti = (CTreillis *) S->Itineraires.ElemAt(i);
        /* on supprime les itineraires sans horaires possibles */
#ifdef DEBUG
        sprintf(outbuf,"Traitement d'un itineraire \n");
        FlushBuffer();
#endif
        if (!(iti->MaJHoraires(S->TpsCorresp)))
        {
            NbSupprimes += 1;
            S->Itineraires.suppr(i);
        }
    }
    S->NbItinRejetes = NbSupprimes;

#ifdef DEBUG
    sprintf(outbuf,"--> Nombre d'itinéraires impossibles : %i\n",NbSupprimes);
    FlushBuffer(); 
#endif


    // Menage...
//  for (i=0;i<S->Itineraires.GetNbElem();i++)
//      delete (CTreillis *) S->Itineraires.ElemAt(i);
    for (i=0;i<S->MaxNbCorresp;i++)
    {
        Li = (CEnsemble *)(Etape.ElemAt(i));
        for (j=0;j<Li->GetNbElem();j++)
            delete ((CCorresp *)Li->ElemAt(j));
        delete Li;
    }

}