Fonction de reperage d'agglomerat + petits changements

This commit is contained in:
Yann Caumartin
2016-12-03 23:25:56 +01:00
parent 56b18ba616
commit e6f91be6b5
2 changed files with 115 additions and 7 deletions

@ -16,6 +16,7 @@ ErrEnum initAgglo(Agglomerat* a,Point* pts, uint32_t taille)
a->moy.lon=0;
for (uint32_t i=0; i<taille;i++)
{
pts[i].type=AGGLOMERAT;
a->agglo[i]=&pts[i];
a->moy.lat+=pts[i].pos.lat;
a->moy.lon+=pts[i].pos.lon;
@ -35,8 +36,9 @@ void libereAgglo(Agglomerat *const a)
Agglomerat fusionAgglo(Agglomerat const* const a1, Agglomerat const* const a2)
{
/*Pour que les agglomérats soient dans l'ordre chronologique*/
if (a1->agglo[0]->date > a2->agglo[0]->date)
return fusionAgglo(a2,a1);
return fusionAgglo(a2,a1);
Agglomerat retour;
@ -49,10 +51,14 @@ Agglomerat fusionAgglo(Agglomerat const* const a1, Agglomerat const* const a2)
return (Agglomerat){ {0, 0}, NULL, 0};
}
/*Définition des valeurs du nouvel agglomérat*/
retour.nbPts=a1->nbPts+a2->nbPts;
retour.moy.lat=(a1->moy.lat+a2->moy.lat)/2;
retour.moy.lon=(a1->moy.lon+a2->moy.lon)/2;
/*Concaténation des points dans le nouvel agglomérat*/
for(uint32_t i=0; i<a1->nbPts;i++)
{
retour.agglo[i]=a1->agglo[i];
@ -72,3 +78,93 @@ uint32_t ecartTemps(Agglomerat const* const a1, Agglomerat const* const a2)
return a2->agglo[0]->date - a1->agglo[a1->nbPts -1]->date;
}
ErrEnum repereAgglo(Point* points, uint32_t tailleP, Agglomerat** agglos, uint32_t* tailleA)
{
uint32_t periode=points[1].date - points[0].date;
uint32_t debut,fin,t;
*tailleA=0;
Agglomerat** agglosTmp=calloc(tailleP/2, sizeof(Agglomerat*));
if (agglosTmp==NULL)
{
fprintf(stderr, "%s\n", strerror(errno));
return ALLOCATION_FAILURE;
}
Agglomerat* tmp=NULL;
for(uint32_t i=1; i<tailleP; i++)
{
/*debut et fin représentent les index entre lesquels sont compris les
points du potentiel futur agglomérat*/
debut=i-1;
fin=i;
while(fin<tailleP &&
distance(&(points[fin].pos),&(points[fin-1].pos)) / periode <= VMIN*MARGE)
/*Tant que la personne n'est pas en dessous d'une certaine vitesse
(et qu'on est pas à la fin du tableau) */
{
fin++;
}
if ((fin-debut)*periode>=DUREEMINI)
/*Si les points couvrent plus que la durée minimum d'un agglomérat
on crée un agglomérat à partir de ces points*/
{
t=*tailleA;
if ((agglosTmp[t]=calloc(1, sizeof(Agglomerat)))==NULL)
{
fprintf(stderr, "%s\n", strerror(errno));
return ALLOCATION_FAILURE;
}
if(initAgglo(agglosTmp[t], points + debut,fin-debut)==ALLOCATION_FAILURE)
{
return ALLOCATION_FAILURE;
}
if(t!=0 && (ecartTemps(agglosTmp[t-1],agglosTmp[t])<DIFTMINI
|| distance(&agglosTmp[t]->moy, &agglosTmp[t-1]->moy)<DISTMINI))
/*Si l'agglomérat construit est proche en distance ou en temps de l'agglomérat
précédent on les fusionne*/
{
if ((tmp=calloc(1,sizeof(Agglomerat)))==NULL)
{
fprintf(stderr, "%s\n", strerror(errno));
return ALLOCATION_FAILURE;
}
*tmp=fusionAgglo(agglosTmp[t-1],agglosTmp[t]);
libereAgglo(agglosTmp[t-1]);
libereAgglo(agglosTmp[t]);
free(agglosTmp[t-1]);
free(agglosTmp[t]);
agglosTmp[t]=NULL;
agglosTmp[t-1]=tmp;
tmp=NULL;
}
else
{
(*tailleA)++;
}
}
i=fin;
}
if ((*agglos=calloc(*tailleA, sizeof(Agglomerat)))==NULL)
{
fprintf(stderr, "%s\n", strerror(errno));
return ALLOCATION_FAILURE;
}
for(uint32_t i=0; i<*tailleA; i++)
{
agglos[0][i]=*agglosTmp[i];
free(agglosTmp[i]);
}
free(agglosTmp);
return SUCCESS;
}

@ -28,7 +28,7 @@ d'écarter les cas où la personne ralentit pour une raison quelconque*/
*
* @return Retourne une valeur d'erreur définie dans 'strucutres.h'
*/
ErrEnum initAgglo(Agglomerat*,Point* ,uint32_t);
ErrEnum initAgglo(Agglomerat* a,Point* pts, uint32_t taille);
/**
* @brief Libère la mémoire prise par le tableau de pointeurs sur points de
@ -36,9 +36,9 @@ ErrEnum initAgglo(Agglomerat*,Point* ,uint32_t);
*
* @param a L'agglomérat où on libère la mémoire
*
* @return Procédure
* @return Valeur d'erreur ou de succes définies dans structures.h
*/
void libereAgglo(Agglomerat *const);
void libereAgglo(Agglomerat *const a);
/**
* @brief Fusionne deux agglomérats
@ -52,7 +52,7 @@ void libereAgglo(Agglomerat *const);
* @return Résultat de la fusion des deux agglomérat. La structure est remplie de 0
* en cas d'échec.
*/
Agglomerat fusionAgglo(Agglomerat const* const, Agglomerat const* const);
Agglomerat fusionAgglo(Agglomerat const* const a1, Agglomerat const* const a2);
/**
* @brief Retourne l'écart de temps entre les deux agglomérats
@ -65,5 +65,17 @@ Agglomerat fusionAgglo(Agglomerat const* const, Agglomerat const* const);
*
* @return L'écart de temps entre les deux agglomérats
*/
uint32_t ecartTemps(Agglomerat const* const, Agglomerat const* const);
ErrEnum repereAgglo(Point*, uint32_t, Agglomerat**, uint32_t*);
uint32_t ecartTemps(Agglomerat const* const a1, Agglomerat const* const a2);
/*
* @brief Repère les agglomérats à partir d'un tableau de points
*
* @param points Tableau de points servant au repérage des agglomérats
* @param tailleP Taille du tableau de points
* @param agglos Adresse du tableau qui contiendra les agglomérats repérés
* @param tailleA Adresse de la variable qui contiendra la taille du tableau d'agglomérats
*
* @return Valeur d'erreur ou de succes définies dans structures.h
*/
ErrEnum repereAgglo(Point* points, uint32_t tailleP, Agglomerat** agglos, uint32_t* tailleA);