Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
Projet labyrinthe
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Yassine BAHOU
Projet labyrinthe
Commits
ec65e0f8
Commit
ec65e0f8
authored
3 years ago
by
Wadie EL AMRANI
Browse files
Options
Downloads
Patches
Plain Diff
Téléverser un nouveau fichier
parent
8828bcb7
Branches
Wadie
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
fisher-Yates/laby.c
+308
-0
308 additions, 0 deletions
fisher-Yates/laby.c
with
308 additions
and
0 deletions
fisher-Yates/laby.c
0 → 100644
+
308
−
0
View file @
ec65e0f8
#include
<stdlib.h>
#include
<stdio.h>
#include
<time.h>
#include
"laby.h"
/* ----------------------------------------------------------------------------------------------
Trouver la classe d’un élément se fait en temps constant, mais fusionner deux classes prend
un temps O(n), puisqu’il faut parcourir tout le tableau pour repérer les éléments dont il faut
changer la classe. Une deuxième solution, que nous détaillons maintenant, consiste à choisir un
représentant dans chaque classe. Fusionner deux classes revient alors à changer de représentant
pour les éléments de la classe fusionnée. Il apparaı̂t avantageux de représenter la partition par
une forêt. Chaque classe de la partition constitue un arbre de cette forêt. La racine de l’arbre
est le représentant de sa classe.
*/
/* ----------------------------------------------------------------------------------------------
DANS L IMPLEMENTATION ARBROESCENTE , ON UTILISE LA HAUTEUR QUI SERA PRINCIPALEMENT UTILISE DANS LA FUSION */
partition_t
initialisation
(
int
taille
)
{
partition_t
partition
;
partition
.
taille
=
taille
;
partition
.
pere
=
malloc
(
taille
*
sizeof
(
int
));
partition
.
hauteur
=
malloc
(
taille
*
sizeof
(
int
));
for
(
int
i
=
0
;
i
<
partition
.
taille
;
i
++
)
{
partition
.
pere
[
i
]
=
i
;
partition
.
hauteur
[
i
]
=
1
;
// LA HAUTEUR EST 1 INITIALEMENT
}
return
partition
;
}
/* ----------------------------------------------------------------------------------------------
AFFICHAGE DES ELEMENTS DE L ENSEMBLE AVEC LEUR PERE ASSOCIE */
void
Affichage_partition
(
partition_t
partition
)
{
printf
(
"Les elements :"
);
for
(
int
i
=
0
;
i
<
partition
.
taille
;
i
++
)
printf
(
"%d "
,
i
);
printf
(
"
\n
"
);
printf
(
"Leur peres :"
);
for
(
int
i
=
0
;
i
<
partition
.
taille
;
i
++
)
printf
(
"%d "
,
partition
.
pere
[
i
]);
printf
(
"
\n
-----------------------"
);
printf
(
"
\n
"
);
}
/* ----------------------------------------------------------------------------------------------
Chercher le représentant de la classe contenant un élément donné X revient à trouver la racine de
l’arbre contenant un noeud donné. Ceci se fait par la méthode suivante : */
int
trouveracine
(
partition_t
partition
,
int
x
)
{
while
(
x
!=
partition
.
pere
[
x
])
x
=
partition
.
pere
[
x
];
return
x
;
}
/* ----------------------------------------------------------------------------------------------
Chacune des deux méthodes est de complexité O(h), où h
est la hauteur l’arbre (la plus grande des hauteurs des deux arbres). En fait, on peut améliorer
l’efficacité de l’algorithme par la règle suivante
Lors de l’union de deux arbres, la racine de l’arbre de moindre taille devient fils de la
racine de l’arbre de plus grande taille. */
void
fusion
(
partition_t
*
partition
,
int
x
,
int
y
)
{
int
r
=
trouveracine
(
*
partition
,
x
);
// on cherche la racine de x et de y
int
s
=
trouveracine
(
*
partition
,
y
);
if
((
*
partition
).
hauteur
[
r
]
>
(
*
partition
).
hauteur
[
s
]
&&
r
!=
s
)
{
(
*
partition
).
pere
[
s
]
=
r
;
(
*
partition
).
hauteur
[
s
]
=
0
;
}
else
if
((
*
partition
).
hauteur
[
r
]
<
(
*
partition
).
hauteur
[
s
]
&&
r
!=
s
)
{
(
*
partition
).
pere
[
r
]
=
s
;
(
*
partition
).
hauteur
[
r
]
=
0
;
}
else
if
(
(
*
partition
).
hauteur
[
r
]
==
(
*
partition
).
hauteur
[
s
]
&&
r
!=
s
)
{
(
*
partition
).
pere
[
s
]
=
r
;
(
*
partition
).
hauteur
[
s
]
=
0
;
(
*
partition
).
hauteur
[
r
]
=
(
*
partition
).
hauteur
[
r
]
+
1
;
}
}
int
*
lister_composantes
(
partition_t
partition
,
int
pere
)
{
int
*
liste_composantes
=
malloc
(
sizeof
(
int
));
//int *tableau=malloc(partition.taille*sizeof(int));
int
k
=
1
;
for
(
int
i
=
0
;
i
<
partition
.
taille
;
i
++
)
{
if
(
partition
.
pere
[
i
]
==
pere
)
{
liste_composantes
[
k
]
=
i
;
k
++
;
liste_composantes
=
(
int
*
)
realloc
(
liste_composantes
,
k
*
sizeof
(
int
));
}
}
liste_composantes
[
0
]
=
k
;
return
liste_composantes
;
}
int
existe
(
int
*
liste
,
int
taille
,
int
element
)
{
int
code
=
0
;
for
(
int
i
=
0
;
i
<
taille
;
i
++
)
{
if
(
liste
[
i
]
==
element
)
code
=
1
;
}
return
code
;
}
int
nombre_racine
(
partition_t
partition
)
{
int
nombrepere
;
int
*
listepere
=
malloc
(
partition
.
taille
*
sizeof
(
int
));
for
(
int
i
=
0
;
i
<
partition
.
taille
;
i
++
)
{
if
(
!
existe
(
listepere
,
i
,
partition
.
pere
[
i
]))
nombrepere
++
;
listepere
[
i
]
=
partition
.
pere
[
i
];
}
free
(
listepere
);
return
nombrepere
;
}
graphe_t
initialisationgraphe
(
int
taille
)
{
graphe_t
graphe
;
graphe
.
nombrenoeud
=
taille
;
graphe
.
arrete
=
malloc
(
taille
*
sizeof
(
arrete_t
));
for
(
int
k
=
0
;
k
<
graphe
.
nombrenoeud
;
k
++
)
{
(
graphe
.
arrete
[
k
]).
i
=
k
;
(
graphe
.
arrete
[
k
]).
j
=
k
;
}
return
graphe
;
}
void
affichergraphe
(
graphe_t
graphe
)
{
printf
(
"votre graphe est constitue par la liste des arretes suivante :
\n
\n
"
);
for
(
int
k
=
0
;
k
<
graphe
.
nombrearrete
;
k
++
)
{
printf
(
"(%d ,%d) |"
,
graphe
.
arrete
[
k
].
i
,
graphe
.
arrete
[
k
].
j
);
}
printf
(
"
\n
-----------------
\n
"
);
}
partition_t
partitiondegraphe
(
graphe_t
graphe
)
{
partition_t
partition
=
initialisation
(
graphe
.
nombrenoeud
);
for
(
int
k
=
0
;
k
<
(
partition
.
taille
);
k
++
)
{
if
(
trouveracine
(
partition
,
graphe
.
arrete
[
k
].
i
)
!=
trouveracine
(
partition
,
graphe
.
arrete
[
k
].
j
)
)
// s'il ne sont pas dans la meme classe
fusion
(
&
partition
,
graphe
.
arrete
[
k
].
i
,
graphe
.
arrete
[
k
].
j
);
}
return
partition
;
}
void
lister_partition
(
partition_t
partition
)
{
printf
(
"
\n
Dans votre partition, les classes sont les suivant : "
)
;
int
i
;
for
(
i
=
0
;
i
<
partition
.
taille
;
i
++
)
{
if
(
partition
.
pere
[
i
]
==
i
)
// Les étiquettes de classes correspondent aux racines.
printf
(
"%d "
,
i
);
}
printf
(
"
\n
"
);
}
void
lister_classe
(
partition_t
partition
,
int
racine
)
// Etiquette de classe.
{
int
classe
;
printf
(
"la classe %d est l'ensemble :"
,
racine
);
printf
(
"{"
);
for
(
int
i
=
0
;
i
<
partition
.
taille
;
i
++
)
{
classe
=
trouveracine
(
partition
,
partition
.
pere
[
i
]);
if
(
classe
==
racine
)
printf
(
" %d "
,
i
);
}
printf
(
"}"
);
}
void
echanger
(
int
*
i
,
int
*
j
)
{
int
tmp
=*
i
;
*
i
=*
j
;
*
j
=
tmp
;
}
graphe_t
Ficher_yate
(
graphe_t
graphe
)
{
graphe_t
ficher
;
int
h
;
for
(
int
l
=
graphe
.
nombrearrete
-
1
;
l
>
0
;
l
--
)
{
h
=
rand
()
%
l
;
echanger
(
&
graphe
.
arrete
[
l
].
i
,
&
graphe
.
arrete
[
h
].
i
);
echanger
(
&
graphe
.
arrete
[
l
].
j
,
&
graphe
.
arrete
[
h
].
j
);
}
ficher
=
graphe
;
return
ficher
;
}
graphe_t
kruskal
(
graphe_t
graphe
)
{
graphe
=
Ficher_yate
(
graphe
);
partition_t
partition
=
initialisation
(
graphe
.
nombrenoeud
);
// 1- creation d une partition dont les elements sont les noeuds du graphe
graphe_t
A
=
initialisationgraphe
(
graphe
.
nombrenoeud
);
// creation d'une liste d'arretes vide
A
.
nombrearrete
=
0
;
for
(
int
k
=
0
;
k
<
graphe
.
nombrearrete
;
k
++
)
{
if
(
trouveracine
(
partition
,
graphe
.
arrete
[
k
].
i
)
!=
trouveracine
(
partition
,
graphe
.
arrete
[
k
].
j
))
{
fusion
(
&
partition
,
graphe
.
arrete
[
k
].
i
,
graphe
.
arrete
[
k
].
j
);
A
.
nombrearrete
++
;
A
.
arrete
[
A
.
nombrearrete
-
1
].
i
=
graphe
.
arrete
[
k
].
i
;
A
.
arrete
[
A
.
nombrearrete
-
1
].
j
=
graphe
.
arrete
[
k
].
j
;
}
}
return
A
;
}
graphe_t
generation_aleatoire
(
int
nombrenoeud
)
{
graphe_t
graphe_aleatoire
=
initialisationgraphe
(
nombrenoeud
);
int
n
=
rand
()
%
2
*
nombrenoeud
;
// le nombre d'arrete est aleatoire aussi
graphe_aleatoire
.
nombrearrete
=
n
;
int
k
;
for
(
int
l
=
0
;
l
<
n
;
l
++
)
{
k
=
rand
()
%
nombrenoeud
;
graphe_aleatoire
.
arrete
[
l
].
i
=
k
;
k
=
rand
()
%
nombrenoeud
;
graphe_aleatoire
.
arrete
[
l
].
j
=
k
;
}
return
graphe_aleatoire
;
}
int
main
()
{
graphe_t
graphe
=
generation_aleatoire
(
10
);
affichergraphe
(
graphe
);
partition_t
partition1
=
partitiondegraphe
(
graphe
);
graphe_t
A
=
kruskal
(
graphe
);
affichergraphe
(
A
);
// graphe_t graphe;
// graphe=initialisationgraphe(5);
// graphe.nombrearrete=5;
// (graphe.arrete[0]).i=0;
// (graphe.arrete[0]).j=1;
// (graphe.arrete[1]).i=1;
// (graphe.arrete[1]).j=2;
// (graphe.arrete[2]).i=3;
// (graphe.arrete[2]).j=3;
// (graphe.arrete[3]).i=3;
// (graphe.arrete[3]).j=4;
// (graphe.arrete[4]).i=5;
// (graphe.arrete[4]).j=5;
// affichergraphe(graphe);
// partition_t partition1;
// partition_t partition2;
// graphe_t A;
// A=kruskal(graphe);
// affichergraphe(A);
// partition1=partitiondegraphe(A);
// Affichage_partition(partition1);
// lister_partition(partition1);
// lister_classe(partition1,0);
// lister_classe(partition1,3);
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment