Compare commits

...

37 Commits

Author SHA1 Message Date
4bfbea8ca1 Cours BD S2 2025-03-10 08:30:42 +01:00
d1a67ae9a7 Update TP/TP3.md 2025-02-12 16:40:13 +01:00
9a33cbb00f Update TP/TP3.md 2025-02-12 16:02:13 +01:00
7163ad13c5 Merge branch 'master' of https://dwarves.iut-fbleau.fr/gitiut/dartoisl/Graphes 2025-01-27 10:29:45 +01:00
a9021d9399 ok 2025-01-27 10:29:28 +01:00
5cd2f05eda Update TP/TP4.md 2025-01-27 10:27:23 +01:00
e8635e8d8f Upload files to "TP/sources" 2025-01-27 10:26:58 +01:00
8875b01c4b Delete TP/prim.png 2025-01-27 10:26:15 +01:00
77a4ac539c Delete TP/parcoursLargeur.png 2025-01-27 10:26:11 +01:00
e70bc20636 Delete TP/dijkstra.png 2025-01-27 10:26:06 +01:00
1bff8b99b8 Delete TP/parcoursProfondeur.png 2025-01-27 10:26:01 +01:00
5c3b3ef198 nettoyage bis 2025-01-27 10:25:47 +01:00
83619225b3 nettoyage 2025-01-27 10:21:26 +01:00
c7325ea499 Update TP/TP1.md 2025-01-27 10:19:29 +01:00
f96f42c1c7 Update README.md 2025-01-27 09:49:18 +01:00
726e90aa1c derniere semaine et exam 23 2024-03-25 14:00:25 +01:00
34b9be32ff semaine 4 2024-03-18 09:50:24 +01:00
c16b5882d4 semaine 3 2024-03-04 08:50:53 +01:00
766b32070d affichage echelonne 2024-02-29 11:06:48 +01:00
d323b41816 exercice 0 2024-02-29 10:56:43 +01:00
7f760a1055 sans les accents 2024-02-29 10:44:39 +01:00
d3226c10f7 readme 2024-02-28 12:13:20 +01:00
64043bfe2d readme 2024-02-28 12:12:36 +01:00
8846df0094 readme 2024-02-28 12:11:38 +01:00
9529927cfb readme 2024-02-28 12:10:38 +01:00
37146c4762 ok 2024-02-28 12:06:52 +01:00
854ff1bf2e ok 2024-02-28 12:05:03 +01:00
9d68101023 td/tp semaines 1-2 2024-02-28 12:00:20 +01:00
5e7fc1594d ok 2024-02-28 11:53:24 +01:00
3014f7a3af TP3++ 2023-03-17 10:08:07 +01:00
0f688ecb48 Merge branch 'master' of https://dwarves.iut-fbleau.fr/gitiut/dartoisl/Graphes 2023-03-17 10:07:47 +01:00
468acdea5f ajout Algos TD3 2023-03-17 10:05:40 +01:00
fec09e83e2 Update 'TP/TP4.md' 2023-03-14 16:33:45 +01:00
e71e0802dd correc mineures 2023-03-14 16:33:14 +01:00
e37dbfc66d Delete 'TP/dijsktra.png' 2023-03-14 16:30:41 +01:00
6b1318634f ok Merge branch 'master' of https://dwarves.iut-fbleau.fr/gitiut/dartoisl/Graphes 2023-03-14 16:28:32 +01:00
38564913cd TP4 2023-03-14 16:28:15 +01:00
18 changed files with 506 additions and 210 deletions

BIN
BDcoursS2p1.pdf Normal file

Binary file not shown.

BIN
BDcoursS2p2.pdf Normal file

Binary file not shown.

BIN
ExamGraphe23.pdf Normal file

Binary file not shown.

View File

@@ -1,17 +1,19 @@
# Graphes (R2.07) # Graphes (R2.07)
## Cours/TD ## Cours/TD
| Semaine | Cours | TD | | Semaine | Cours | TD |
| -------------------- | ------------------------------------------------ | ----------------------- | | -------------------- | ------------------------------------------------ | ----------------------- |
| 1 : 31/01 - 04/02 | [Graphes](./cours/graphes.pdf) | | | 1 | [Pages 1 à 47](graphes.pdf) | [td1](./td/TD1.pdf) |
| 2 : 07/02 - 11/02 | [Graphes](./cours/graphes.pdf) | [td1](./td/TD1.pdf) | | 2 | [Pages 48 à 94](graphes.pdf) | [td2](./td/TD2.pdf) |
| 3 : 14/02 - 18/02 | [Graphes](./cours/graphes.pdf) | [td2](./td/TD2.pdf) | | 3 | [Pages 95 à 150](graphes.pdf) | [td3](./td/TD3.pdf) |
| 4 : 07/03 - 11/03 | [Graphes](./cours/graphes.pdf) | [td3](./td/TD3.pdf) | | 4 | [Pages 151 à 194](graphes.pdf) | [td3](./td/TD3.pdf) |
| 5 : 14/03 - 18/03 | [Graphes](./cours/graphes.pdf) | [td4](./td/TD4.pdf) | | 5 | [Pages 195 à 234](graphes.pdf) | [td4](./td/TD4.pdf) |
| 6 : 21/03 - 25/03 | [Graphes](./cours/graphes.pdf) | [td5](./td/TD5.pdf) | | 6 | [Graphes](graphes.pdf) | [td5](./td/TD5.pdf) |
## TP ## Ressources
- [Lien]( https://wimsauto.universite-paris-saclay.fr/wims/wims.cgi?session=PH47F2DA8D.3&+lang=fr&+module=adm%2Fclass%2Fclasses&+type=authparticipant&+class=4291940&+subclass=yes) - [TD](./td/)
vers le serveur WIMS. - [TP](./TP/)
- [Structure de Départ](./TP/ClassesDeDepart/)
- [Examen 2023](./ExamGraphe23.pdf)

View File

@@ -0,0 +1,126 @@
/**
* Classe definissant des graphes au sens mathematiques
* @author Luc Dartois
* @version 1.0
*/
public class Graphe{
/**
* Le nombre de sommets du graphe, numerotes de 0 a ordre-1
*/
private int ordre;
/**
* Ses aretes donnees sous forme de matrice carre d'adjacence (voir classe MatriceCarre)
*/
private MatriceCarre adj;
/**
* Indique si le graphe est oriente ou non
*/
private boolean oriente;
/**
* Construit un graphe vide
*@param ord indique l'ordre du graphe
*@param o indique s'il est oriente
*/
public Graphe(int ord,boolean o){
this.ordre=ord;
this.adj=new MatriceCarre(ord);
this.oriente=o;
}
/**
* Getter pour l'ordre
*@return L'ordre du graphe
*/
public int getOrdre(){
return this.ordre;
}
/**
* Renvoit vrai s'il y a une arete de i a j
*@param i,j Deux sommets du graphe
*@return Vrai si le graphe possède une arete de i a j
*/
public boolean getArete(int i,int j){
return this.adj.getCoeff(i,j)==1;
}
/**
* Ajoute une arete de i a j
*@param i,j Deux sommets du graphe
*/
public void ajoutArete(int i,int j){
if(i>=this.ordre||j>=this.ordre||i<0||j<0){
throw new IllegalArgumentException("Erreur : Sommet inexistant.");
}
this.adj.setCoeff(i,j,1);
if(!this.oriente){
this.adj.setCoeff(j,i,1);
}
}
/**
* Affiche la liste des voisins de i
*@param i Un sommet du graphe
*/
public void voisinage(int i){
if(!this.oriente){
System.out.print("Voisins de "+i+" : ");
for(int j=0;j<this.ordre;j++){
if(this.adj.getCoeff(i,j)==1){
System.out.print(j+", ");
}
}
System.out.println();
}
else{
System.out.print("Voisins sortants de "+i+" : ");
for(int j=0;j<this.ordre;j++){
if(this.adj.getCoeff(i,j)==1){
System.out.print(j+", ");
}
}
System.out.println();
System.out.print("Voisins entrants de "+i+" : ");
for(int j=0;j<this.ordre;j++){
if(this.adj.getCoeff(j,i)==1){
System.out.print(j+", ");
}
}
System.out.println();
}
}
/**
* Calcule la somme du nombre de voisins de tous les sommets
*@return Un entier representant la somme de tous les voisins.
*/
public int sommeVoisins(){
int s=0;
for(int i=0;i<this.ordre;i++){
for(int j=0;j<this.ordre;j++){
s+=this.adj.getCoeff(i,j);
}
}
return s;
}
public String toString(){
String s="Graphe ";
if(!this.oriente){
s+="non ";
}
s+="oriente de taille : "+this.ordre+".\n";
return s;
}
public boolean equals(Graphe g){
if(this.ordre!=g.ordre)
return false;
if(this.oriente!=g.oriente)
return false;
if(!this.adj.equals(g.adj))
return false;
return true;
}
}

View File

@@ -0,0 +1,75 @@
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/**
* Un objet JGraphe est un JComponent Swing permettant d'afficher dans une fenetre un graphe donne.
* @author Luc Dartois
* @version 1.0
*/
public class JGraphe extends JComponent{
private Graphe g;
/**
* Constructeur
*@param gr Le graphe a afficher
*/
public JGraphe(Graphe gr){
super();
this.g=gr;
Dimension dim=new Dimension(100*this.g.getOrdre(),100*this.g.getOrdre());
this.setSize(dim);
}
/**
* Cree une fenetre carree pour afficher le graphe
* @param taille taille de la fenetre a creer
*/
public void affiche(int taille){
JFrame fenetre=new JFrame();
fenetre.setSize(taille,taille);
fenetre.setLocation(100,100);
fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fenetre.add(this);
fenetre.setVisible(true);
}
/**
* Definit comment le graphe est affiche
*@param pinceau L'outil permettant de dessiner
*/
@Override
public void paintComponent(Graphics pinceau){
int n=this.g.getOrdre();
int taille = this.getWidth();
int r=taille/20;
int origine=taille/2;
int distance=4*origine/5;
int x,y;
int co,si;
int[] pointsX=new int[n];
int[] pointsY=new int[n];
for(int i=0;i<n;i++){
co=(int) Math.round(distance*Math.cos(2*Math.PI*i/n));
si=(int) Math.round(distance*Math.sin(2*Math.PI*i/n));
x=origine+co ;
y=origine+si ;
pinceau.fillOval(x-r/2,y-r/2,r,r);
pinceau.drawString(""+i,x+co*r/distance,y+si*r/distance);
pointsX[i]=x;
pointsY[i]=y;
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(this.g.getArete(i,j)){
pinceau.drawLine(pointsX[i],pointsY[i],pointsX[j],pointsY[j]);
}
}
}
}
}

View File

@@ -0,0 +1,85 @@
/**
* Une classe definissant une matrice carree
* @author Luc Dartois
* @version 1.0
*/
public class MatriceCarre{
private int n; //taille de la matrice
private int[][] m; //La matrice
/**
* Constructeur creant une matrice vide
*@param t La taille de la matrice
*/
public MatriceCarre(int t){
this.n=t;
this.m=new int[t][t];
}
/**
* Constructeur copiant une matrice donnee dans une nouvelle matrice
*@param a La matrice à copier
*/
public MatriceCarre(MatriceCarre a){
this.n=a.n;
this.m=new int[this.n][this.n];
for(int i=0;i<this.n;i++){
for(int j=0;j<this.n;j++){
this.m[i][j]=a.m[i][j];
}
}
}
/**
* Methode permettant de definir le coefficient d'une matrice
*@param i Le coefficient de ligne
*@param j Le coefficient de colonne
*@param val La valeur du coefficient
*/
public void setCoeff(int i,int j,int val){
if(i>=this.n||j>=this.n||i<0||j<0){
throw new IllegalArgumentException("Erreur : Hors limites de la matrice.");
}
this.m[i][j]=val;
}
/**
* Methode permettant de recuperer le coefficient d'une matrice
*@param i Le coefficient de ligne
*@param j Le coefficient de colonne
*@return Le coefficient
*/
public int getCoeff(int i,int j){
if(i>=this.n||j>=this.n||i<0||j<0){
throw new IllegalArgumentException("Erreur : Hors limites de la matrice.");
}
return this.m[i][j];
}
public String toString(){
String s=" ";
for(int j=0;j<this.n;j++){
s+="| "+j;
}
s+="|\n";
for(int i=0;i<this.n;i++){
s+=i+" | ";
for(int j=0;j<this.n;j++){
s+=this.m[i][j]+"| ";
}
s+="\n";
}
return s;
}
public boolean equals(MatriceCarre a){
if(this.n!=a.n)
return false;
for(int i=0;i<this.n;i++){
for(int j=0;j<this.n;j++){
if(this.m[i][j]!=a.m[i][j])
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,56 @@
public class TestGraphe{
public static void main(String[] args) {
//Graphe de la france et ses voisins :
/*
0:France
1:Espagne
2:Portugal
3:Italie
4:Suisse
5:Allemagne
6:Belgique
7:Luxembourg
8:Pays-Bas
*/
Graphe europe=new Graphe(9,false);
europe.ajoutArete(0,1);
europe.ajoutArete(0,3);
europe.ajoutArete(0,4);
europe.ajoutArete(0,5);
europe.ajoutArete(0,6);
europe.ajoutArete(0,7);
europe.ajoutArete(1,2);
europe.ajoutArete(3,4);
europe.ajoutArete(4,5);
europe.ajoutArete(5,6);
europe.ajoutArete(5,7);
europe.ajoutArete(5,8);
europe.ajoutArete(6,7);
europe.ajoutArete(6,8);
System.out.println(europe);
europe.voisinage(0);
int t=europe.sommeVoisins();
System.out.println(t==14*2);
//Exemple de graphe oriente.
Graphe g=new Graphe(5,true);
g.ajoutArete(0,2);
g.ajoutArete(0,4);
g.ajoutArete(1,0);
g.ajoutArete(1,3);
g.ajoutArete(2,3);
g.ajoutArete(3,1);
g.ajoutArete(3,4);
g.ajoutArete(4,0);
g.voisinage(1);
System.out.println(g.sommeVoisins()==8);
JGraphe gr=new JGraphe(europe);
gr.affiche(500);
}
}

View File

@@ -36,6 +36,47 @@ Modifiez la fonction précédente pour en prendre compte.
**Question :** **Question :**
Créez dans le main le graphe des frontières de la France (on ne considérera pas les micro-états). Créez dans le main le graphe des frontières de la France (on ne considérera pas les micro-états).
Aide : Vous pouvez utiliser la fonction suivante pour afficher votre graph. Elle utilise la bibliothèque graphique de l'IUT.
Il faut donc ajouter ``-lgraph`` lors de la compilation.
```
void visuelGraphe(graphe g){
int taille=1000;
int origine=taille/2;
int distance=4*origine/5;
int tailleVert=taille/20;
InitialiserGraphique();
CreerFenetre(10,10,taille,taille);
int i,j;
int x,y;
char* nV=malloc(2);
*nV='0';
*(nV+1)='\0';
int* cX=calloc(g.ordre,sizeof(int));
int* cY=calloc(g.ordre,sizeof(int));
for(i=0;i<g.ordre;i++){
x=(int) origine+distance*cos(2*M_PI*i/g.ordre);
y=(int) origine+distance*sin(2*M_PI*i/g.ordre);
cX[i]=x+tailleVert/2;
cY[i]=y+tailleVert/2;
RemplirArc(x,y,tailleVert,tailleVert,0,360);
EcrireTexte(x,y,nV,2);
(*nV)++;
}
for(i=0;i<g.ordre;i++){
for(j=0;j<g.ordre;j++){
if(g.adj[i][j]!=0){
DessinerSegment(cX[i],cY[i],cX[j],cY[j]);
}
}
}
Touche();
FermerGraphique();
}
```
- - - - - - - - - -
Exercice 2 : Voisinage Exercice 2 : Voisinage
@@ -114,7 +155,7 @@ struct graphe{
int oriente; int oriente;
}; };
``` ```
Où voisins est un table de listes chaînées. Où voisins est un tableau de listes chaînées.
**Question :** **Question :**

View File

@@ -2,23 +2,8 @@ TP Graphes 2 : Chemins et connexité
============ ============
Le TP est prévu pour être fait en utilisant le codage des graphes à l'aide de matrices d'adjacence. Le TP est prévu pour être fait en utilisant le codage des graphes à l'aide de matrices d'adjacence.
Les classes Graphe et MatriceCarre contiennent le résultat du TP1 en code java et servira de base aux TPs suivants.
- - - - - La classe JGraphe contient une classe JComponent permettant d'afficher un graphe avec la méthode `affiche()`. Un exemple d'utilisation est donné dans la classe TestGraphe.java.
Exercice 0 : Affichage
----------
***Question :***
Ecrire une fonction permettant d'afficher une matrice carrée (la taille de la matrice sera donnée en argument) :
```
void afficherMatrice(int **m,int taille);
```
**Question :**
Ecrire une fonction permettant d'afficher la matrice d'adjacence d'un graphe donné en argument :
```
void afficherAdjacence(graphe g);
```
- - - - - - - - - -
Exercice 1 : Chemins de longueur fixe Exercice 1 : Chemins de longueur fixe
@@ -26,32 +11,31 @@ Exercice 1 : Chemins de longueur fixe
La multiplication de matrices carrées se fait grâce à la fonction de prototype : La multiplication de matrices carrées se fait grâce à la fonction de prototype :
``` ```
int** multiplicationMatriceCarre(int **a,int **b,int size); MatriceCarre multiplicationMatriceCarre(MatriceCarre a);
``` ```
Le code de la fonction est donné ci-dessous. Si vous le souhaitez, vous pouvez ignorer le code et faire la fonction vous-même. Le code de la fonction est donné ci-dessous. Si vous le souhaitez, vous pouvez ignorer le code et faire la fonction vous-même.
``` ```
int** multiplicationMatriceCarre(int **a,int **b,int size){ public MatriceCarre multiplication(MatriceCarre a){
int** res=calloc(size,sizeof(int*)); if(this.n!=a.n)
int i,j,k; throw new IllegalArgumentException("multiplication de matrices de tailles différentes");
for(i=0;i<size;i++){ MatriceCarre res=new MatriceCarre(this.n);
res[i]=calloc(size,sizeof(int)); int i,j,k;
} for(i=0;i<this.n;i++){
for(i=0;i<size;i++){ for(j=0;j<this.n;j++){
for(j=0;j<size;j++){ for(k=0;k<this.n;k++){
for(k=0;k<size;k++){ res.m[i][j]+=this.m[i][k]*a.m[k][j];
res[i][j]+=a[i][k]*b[k][j]; }
} }
} }
}
return res; return res;
} }
``` ```
**Question :** **Question :**
En utilisant la multiplication de matrices carrées, créez une fonction renvoyant une matrice contenant les chemins d'une longueur donnée : En utilisant la multiplication de matrices carrées, créez une fonction renvoyant une matrice contenant les chemins d'une longueur donnée :
``` ```
int** nombreDeChemins(graphe g,int longueur); public MatriceCarre nombreDeChemins(int longueur);
``` ```
- - - - - - - - - -
@@ -62,7 +46,7 @@ Un graphe (orienté) est (fortement) connexe si pour toute paire de sommet (x,y)
De plus, s'il existe un chemin de x à y, alors il en existe un de longueur *au plus* n, où n est l'ordre du graphe. De plus, s'il existe un chemin de x à y, alors il en existe un de longueur *au plus* n, où n est l'ordre du graphe.
**Question :** **Question :**
Ecrire la fonction `int estConnexe(graphe g);` renvoyant 1 si le graphe est connexe, et 0 sinon. Ecrire la fonction `public boolean estConnexe();` renvoyant true si le graphe est connexe, et false sinon.
Indice : vous aurez besoin d'une fonction permettant d'additionner des matrices. Indice : vous aurez besoin d'une fonction permettant d'additionner des matrices.
**Question :** **Question :**
@@ -86,9 +70,9 @@ Exercice 4 : Distance et diamètre.
---------- ----------
***Question*** ***Question***
Ecrire une fonction ```int** distances(graphe g);``` renvoyant une matrice dont le coefficient (i,j) contient la distance entre i et j. Ecrire une fonction ```public MatriceCarre distances();``` renvoyant une matrice dont le coefficient (i,j) contient la distance entre i et j.
Indice : Les sommets à distance 1 sont ceux qui sont adjacent (valeur 1 dans la matrice d'adjacence). Indice : Les sommets à distance 1 sont ceux qui sont adjacent (valeur 1 dans la matrice d'adjacence).
De façon générale, un sommet x est à distance l d'un sommet y si il existe un chemin de longueur l mais aucun chemin de longueur l-1. De façon générale, un sommet x est à distance l d'un sommet y si il existe un chemin de longueur l mais aucun chemin de longueur l-1.
***Question*** ***Question***
Ecrire une fonction ```int diametre(graphe g)``` retournant le diamètre du graphe passé en paramètre. Ecrire une fonction ```public int diametre()``` retournant le diamètre d'un graphe.

103
TP/TP3.md
View File

@@ -8,58 +8,30 @@ Pour plus de clarté, vous pouvez utiliser un nouveau fichier, en copiant les st
Exercice 1 : Parcours en largeur Exercice 1 : Parcours en largeur
---------- ----------
Pour cet exercice, vous aurez besoin de file FIFO, dont voici la structure et les primitives : Pour cet exercice, vous aurez besoin de file FIFO (First In, First Out).
Vous pouvez par exemple utiliser la classe [`LinkedList`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/LinkedList.html), instanciée pour les entiers avec `LinkedList<Integer>`, et chargée avec `import java.util.*;`.
Pour utiliser une LinkedList en tant que file FIFO, vous pouvez utiliser les méthodes :
``` ```
struct file{ public boolean isEmpty() : Returns true if this collection contains no elements.
int data; Integer remove() : Retrieves and removes the head (first element) of this list.
struct file* succ; boolean offer(int i) : Adds the specified element i as the tail (last element) of this list.
};
typedef struct file fifo;
void enqueue(fifo **fi,int v){
fifo *nf=malloc(sizeof(fifo));
nf->data=v;
nf->succ=*fi;
(*fi)=nf;
}
int dequeue(fifo **fi){
fifo *lect=*fi;
if(lect->succ==NULL){
int res=lect->data;
*fi=NULL;
return res;
}
while(lect->succ->succ!=NULL){
lect=lect->succ;
}
int res=lect->succ->data;
fifo *temp=lect->succ;
lect->succ=NULL;
free(temp);
return res;
}
int empty(fifo *fi){
return fi==NULL;
}
``` ```
On rappelle que pour une variable `fifo *fi`, on empile 3 en faisant `enqueue(&fi,3)` et on défile (et on stocke dans une variable x) en faisant `x=dequeue(&fi)`.
**Question :** **Question :**
Ecrire une fonction qui, étant donnés un graphe g et un sommet v de ce graphe, renvoie sous forme de file FIFO l'ensemble des voisins de v dans g : Ecrire une fonction qui, étant donnés un graphe g et un sommet i de ce graphe, renvoie sous forme de file FIFO l'ensemble des voisins de i dans g :
``` ```
fifo* fileVoisins(graphe g,int v); public LinkedList<Integer> getVoisins(int i);
``` ```
![Parcours en Largeur](sources/parcoursLargeur.png)
**Question :** **Question :**
Ecrire une fonction effectuant le parcours en largeur d'un graphe g à partir d'un sommet v. Ecrire une fonction effectuant le parcours en largeur d'un graphe g à partir d'un sommet v.
On pourra se contenter d'afficher sur la sortie standard la numérotation ainsi que les distances obtenues, plutôt que de les renvoyer : On pourra se contenter d'afficher sur la sortie standard la numérotation ainsi que les distances obtenues, plutôt que de les renvoyer :
``` ```
void parcoursLargeur(graphe g,int v); public void parcoursLargeur(int v)
``` ```
**Question :** **Question :**
@@ -71,51 +43,25 @@ Tester sur un graphe (au hasard celui des frontières). Cela correspond-t-il à
Exercice 2 : Parcours en profondeur Exercice 2 : Parcours en profondeur
---------- ----------
Pour implémenter le parcours en profondeur d'un graphe, nous aurons besoin d'une pile, dont voici la structure et les primitives : Pour implémenter le parcours en profondeur d'un graphe, nous aurons besoin d'une pile.
La classe `LinkedList` permet également de simuler des piles, avec les méthodes :
``` ```
struct pile{ public boolean isEmpty() : Returns true if this collection contains no elements.
int head; Integer pop() : Pops an element from the stack represented by this list.
struct pile* suite; void push(int i) : Pushes an element onto the stack represented by this list.
};
typedef struct pile pile;
int emptyPile(pile *p){
return p==NULL;
}
void push(pile **p,int v){
pile* newpile=malloc(sizeof(pile));
newpile->head=v;
newpile->suite=*p;
*p=newpile;
}
int pop(pile **p){
int resultat=(*p)->head;
pile* temp=*p;
*p=(*p)->suite;
free(temp);
return resultat;
}
int first(pile *p){
return p->head;
}
``` ```
On rappelle que pour une variable `pile *fi`, on push 3 en faisant `push(&fi,3)` et on dépile (et on stocke dans une variable x) en faisant `x=pop(&fi)`.
La primitive `x=first(fi)` permet de récupérer le sommet de la pile sans dépiler.
**Question :** **Question :**
Ecrire une fonction effectuant le parcours en profondeur d'un graphe g à partir d'un sommet v. Ecrire une fonction effectuant le parcours en profondeur d'un graphe g à partir d'un sommet v.
On pourra se contenter d'afficher sur la sortie standard la numérotation de premier passage plutôt que de les renvoyer : On pourra se contenter d'afficher sur la sortie standard la numérotation de premier passage plutôt que de les renvoyer :
``` ```
void parcoursProfondeur(graphe g,int v); public void parcoursProfondeur(int i);
``` ```
![Parcours en Profondeur](sources/parcoursProfondeur.png)
**Question :** **Question :**
Tester sur un graphe (au hasard celui des frontières). Cela correspond-t-il à une exécution manuelle de l'algorithme ? Tester sur un graphe (au hasard celui des frontières). Cela correspond-t-il à une exécution manuelle de l'algorithme ?
@@ -133,19 +79,18 @@ Les premières questions visent à donner des fonctions aidant à l'implémentat
**Question : Liste des sommets selon leur degré** **Question : Liste des sommets selon leur degré**
-Créer une fonction `int* tableauDegre(graphe g);` renvoyant un tableau où la case i contient le degré du sommet i. -Créer une fonction `private int[] tableauDegre();` renvoyant un tableau où la case i contient le degré du sommet i.
-Créer une fonction `int indiceMax(int *tab,int taille);` renvoyant l'indice de la plus grande valeur du tableau tab de longueur taille. -Créer une fonction `private int indiceMax(int[] tab);` renvoyant l'indice de la plus grande valeur du tableau tab.
-En utilisant les deux premières fonctions, créer une fonction `fifo* listeDegre(graphe g);` renvoyant une liste des sommets classés selon leur degré. -En utilisant les deux premières fonctions, créer une fonction `private LinkedList<Integer> listeDegre()` renvoyant une liste des sommets classés selon leur degré.
**Question** **Question**
Pour simplifier le code de Welsh-Powell, écrire une fonction ![Algorithme de Welsh-Powell](sources/WelshPowell.png)
`int voisinCouleur(graphe g,int v,int c,int *color)` renvoyant 1 si le sommet v a un voisin de la couleur c dans le tableau color, et 0 sinon.
**Question** **Question**
Enfin, implémentez l'algorithme de Welsh-Powell. Enfin, implémentez l'algorithme de Welsh-Powell.
Indice : Vous aurez besoin de la liste des sommets triés selon leur degré, mais également d'un lecteur sur cette liste, i.e. un pointeur vers le début de la liste pouvant la parcourir autrement que par des dequeues. Indice : Vous aurez besoin de la liste des sommets triés selon leur degré. On peut retirer un élément i donné de la liste l avec `l.remove((Integer) i)`.

67
TP/TP4.md Normal file
View File

@@ -0,0 +1,67 @@
TP Graphes 4 : Plus Court Chemin et Arbre Recouvrant Minimal
============
Le TP est prévu pour être fait en utilisant le codage des graphes à l'aide de matrices d'adjacence.
Pour plus de clarté, vous pouvez utiliser une nouvelle classe, en copiant les structures et fonctions nécessaires depuis les TPs précédants.
- - - - -
Exercice 0 : Graphes valués
----------
Nous avons enrichi nos graphes avec une valuation des arêtes.
**Question :**
Comment intégrer cela à notre structure de données ?
Quel fonction(s) faut-il modifier pour prendre en compte cet enrichissement ?
**Question :**
Créez une nouvelle classe GraphesValues.java contenant la structure et les primitives nécessaires à la manipulation des graphes valués.
- - - - -
Exercice 1 : Algorithme de Dijkstra
----------
L'algorithme de Dijkstra renvoie deux données : la fonction d donnant la distance minimale entre la source et un sommet, et la fonction père donnant la direction à prendre pour atteindre cette distance minimale.
**Question :**
Une fonction des sommets vers un entier (ou un autre sommet) sera représentée par un tableau où la case i contient la valeur de la fonction pour i.
Nous souhaitons cependant renvoyer deux fonctions. Comment modéliser cela ?
**Question :**
Implémentez l'algorithme de Dijsktra, que je redonne ci-dessous :
![Algorithme de Dijkstra](sources/dijkstra.png)
**Question :**
Testez votre algorithme en reprenant le graphes des frontières avec des valuation de votre choix.
Vérifier à la main que l'algorithme effectue les bons calculs.
- - - - -
Exercice 2 : Algorithme de Prim
----------
Pour simplifier l'implémentation, on se contentera d'afficher sur la sortie standard les arêtes sélectionnées. On renverra tout de même la valuation totale de l'arbre couvrant.
![Algorithme de Prim](sources/prim.png)
**Question :**
Implémentez l'algorithme de Prim. Il n'y a pas besoin de modéliser l'ensemble T puisque l'on va l'afficher sur la sortie standard tout au long de l'algorithme.
**Question :**
Testez et vérifiez votre implémentation sur un exemple, au hasard le graphe des frontières.

View File

@@ -1,85 +0,0 @@
#include<graph.h>
#include <math.h>
void visuelGraphe(graphe g){
int taille=1000;
int origine=taille/2;
int distance=4*origine/5;
int tailleVert=taille/20;
InitialiserGraphique();
CreerFenetre(10,10,taille,taille);
int i,j;
int x,y;
char* nV=malloc(2);
*nV='0';
*(nV+1)='\0';
int* cX=calloc(g.ordre,sizeof(int));
int* cY=calloc(g.ordre,sizeof(int));
for(i=0;i<g.ordre;i++){
x=(int) origine+distance*cos(2*M_PI*i/g.ordre);
y=(int) origine+distance*sin(2*M_PI*i/g.ordre);
cX[i]=x+tailleVert/2;
cY[i]=y+tailleVert/2;
RemplirArc(x,y,tailleVert,tailleVert,0,360);
EcrireTexte(x,y,nV,2);
(*nV)++;
}
//Version si le graphe est une matrice d'adjacence
for(i=0;i<g.ordre;i++){
for(j=0;j<g.ordre;j++){
if(g.adj[i][j]!=0){
DessinerSegment(cX[i],cY[i],cX[j],cY[j]);
}
}
}
//Version à utiliser si le graph est un tableau de listes chaînées
/*
maillon* read;
for(i=0;i<g.ordre;i++){
read=g.voisins[i];
while(read!=NULL){
DessinerSegment(cX[i],cY[i],cX[read->valeur],cY[read->valeur]);
read=read->suivant;
}
}
*/
Touche();
FermerGraphique();
}
//Aides matrices
//Creation matrice carrée vide :
int** creerMatriceId(int taille){
int** res=calloc(taille,sizeof(int*));
for(int i=0;i<taille;i++){
res[i]=calloc(taille,sizeof(int));
for(int j=0;j<taille;j++){
res[i][j]=(i==j)?1:0;
}
}
return res;
}
//Creation copie d'une matrice carree :
int** recopierMatrice(int **m,int taille){
int** creerMatriceId(int taille){
int** res=calloc(taille,sizeof(int*));
for(int i=0;i<taille;i++){
res[i]=calloc(taille,sizeof(int));
for(int j=0;j<taille;j++){
res[i][j]=m[i][j];
}
}
return res;
}
}

BIN
TP/sources/WelshPowell.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

BIN
TP/sources/dijkstra.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
TP/sources/prim.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB