Skip to content
Snippets Groups Projects
Commit b1b60910 authored by orestis.malaspin's avatar orestis.malaspin
Browse files

first commit

parents
No related branches found
No related tags found
No related merge requests found
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML")
document.getElementsByTagName("head")[0].appendChild(fileref)
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="124.34627mm"
height="77.693764mm"
viewBox="0 0 124.34627 77.693764"
version="1.1"
id="svg8"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="graph.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.49497475"
inkscape:cx="145.76891"
inkscape:cy="342.59882"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="960"
inkscape:window-height="1015"
inkscape:window-x="960"
inkscape:window-y="37"
inkscape:window-maximized="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-7.6285619,-44.787069)">
<g
id="g893">
<circle
r="9.7102251"
cy="59.063984"
cx="42.900295"
id="path815"
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" />
<text
id="text819"
y="62.842236"
x="40.550797"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="stroke-width:0.26458332"
y="62.842236"
x="40.550797"
id="tspan817"
sodipodi:role="line">1</tspan></text>
</g>
<g
id="g888"
transform="translate(-0.75595238,-3.5393753)">
<text
id="text823"
y="66.434525"
x="92.604164"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="stroke-width:0.26458332"
y="66.434525"
x="92.604164"
id="tspan821"
sodipodi:role="line">2</tspan></text>
<circle
r="9.7102261"
cy="62.603359"
cx="95.609833"
id="path815-3"
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" />
</g>
<g
id="g873"
transform="translate(-154.52666,51.651803)">
<text
id="text831"
y="63.788689"
x="169.33333"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="stroke-width:0.26458332"
y="63.788689"
x="169.33333"
id="tspan829"
sodipodi:role="line">4</tspan></text>
<circle
r="9.7102261"
cy="59.989273"
cx="172.36545"
id="path815-7"
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" />
</g>
<g
id="g883"
transform="translate(-42.439825,6.2205896)">
<text
id="text835"
y="109.14583"
x="109.23512"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="stroke-width:0.26458332"
y="109.14583"
x="109.23512"
id="tspan833"
sodipodi:role="line">5</tspan></text>
<circle
r="9.7102261"
cy="105.42049"
cx="112.29371"
id="path815-5"
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" />
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 52.718598,59.063984 H 84.846573"
id="path895"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 28.011559,111.64108 H 60.139541"
id="path895-3"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 18.058476,101.66258 39.000132,67.69174"
id="path895-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<g
id="g878"
transform="translate(-17.270157,52.008618)">
<text
id="text827"
y="63.410713"
x="136.07143"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="stroke-width:0.26458332"
y="63.410713"
x="136.07143"
id="tspan825"
sodipodi:role="line">3</tspan></text>
<circle
r="9.7102261"
cy="59.632462"
cx="139.03476"
id="path815-6"
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal" />
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 79.734935,111.64108 H 111.86292"
id="path895-6"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 70.272946,101.64109 91.214602,67.670243"
id="path895-5-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="65.776917"
y="52.449402"
id="text963"><tspan
sodipodi:role="line"
id="tspan961"
x="65.776917"
y="52.449402"
style="stroke-width:0.26458332">2</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="18.142857"
y="88.476578"
id="text967"><tspan
sodipodi:role="line"
id="tspan965"
x="18.142857"
y="88.476578"
style="stroke-width:0.26458332">4</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="41.726051"
y="122.42792"
id="text971"><tspan
sodipodi:role="line"
id="tspan969"
x="41.726051"
y="122.42792"
style="stroke-width:0.26458332">1</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="86.178574"
y="88.486832"
id="text975"><tspan
sodipodi:role="line"
id="tspan973"
x="86.178574"
y="88.486832"
style="stroke-width:0.26458332">2</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="92.740341"
y="122.375"
id="text979"><tspan
sodipodi:role="line"
id="tspan977"
x="92.740341"
y="122.375"
style="stroke-width:0.26458332">5</tspan></text>
</g>
</svg>
---
author:
- Les graphes - algorithmes de plus cours chemins
title: Cours de programmation séquentielle
autoSectionLabels: false
autoEqnLabels: true
eqnPrefix:
- "éq."
- "éqs."
chapters: true
numberSections: false
chaptersDepth: 1
sectionsDepth: 3
lang: fr
documentclass: article
papersize: A4
cref: false
urlcolor: blue
toc: false
---
# Préambule
Ce travail pratique est organisé en plusieurs parties traitant la notion de recherche de plus court chemin dans
un graphe. Il faudra implémenter les algorithmes de Floyd et de Dijkstra que vous avez vus en cours.
Vous appliquerez ces algorithmes sur un graphe représentant
un certain nombre de lignes ferroviaires suisses.
Finalement, une partie graphique vous sera demandée pour rendre le travail un peu plus ludique.
Pour cette première partie vous serez assez libres dans le design de votre code.
Des bouts de code vous sont fournis, vous devrez les adapter à vos besoin
que cela soit pour le contenu des fonctions ou leurs signatures.
# Les deux représentations d'un graphe
Dans ce travail, nous ne considérons que des graphes pondérés, non-orientés.
Cela signifie que les sommets du graphe sont reliés par des arêtes et chacune d'entre elle porte un poids. Contrairement aux graphes orientés,
les arête n'ont pas de direction (voir la @fig:graphe).
Les poids seront des **entiers positifs** dans ce travail.
![Exemple de graphe non-orienté.](figs/graph.svg){#fig:graphe width="50.0%"}
Un graphe a deux représentations principales:
1. La liste d'adjacence.
2. La matrice d'adjacence.
Nous allons très brièvement décrire ces deux structures de données sur l'exemple de la @fig:graphe.
## La liste d'adjacence
Pour un graphe non-orienté, la liste d'adjacence, est la liste des voisins pour chaque sommet. La longueur de
cette liste est donc le nombre de sommets.
Pour le cas de la @fig:graphe, elle a une longueur de $5$.
Pour chaque sommet, nous avons ensuite une liste chaînée
contenant l'identifiant du voisin, ainsi que le poids
de l'arête y menant. L'ordre dans lesquels sont placés
les sommets voisins n'a pas d'importance.
![Liste d'adjacence du graphe de la @fig:graphe.](figs/adjacency.svg){#fig:adj width="50.0%"}
Sur la @fig:adj nous pouvons voir la liste d'adjacence correspondant au graphe de la @fig:graphe.
Cette structure sera représentée par un tableau de liste chaînée
dans ce projet.
## La matrice d'adjacence
La matrice d'adjacence d'un graphe avec $N$ sommets est de taille $N\times N$ et contient l'information sur la connectivité du graphe, ainsi que les différentes pondérations des arêtes. Dans le cas de la @fig:graphe,
nous avons donc une matrice, $\underline{\underline{A}}$, de taille $5\times 5$.
$$
\underline{\underline{A}}=\begin{pmatrix}
\infty & 2 & \infty & 4 & \infty\\
2 & \infty & \infty & \infty & \infty\\
\infty & \infty & \infty & \infty & 5\\
4 & \infty & \infty & \infty & 1\\
\infty & \infty & 5 & 1 & \infty
\end{pmatrix},
$$
où l'élément $A_{ij}$ de la matrice représente le poids de l'arête reliant le sommet $i$ au sommet $j$. Les poids infinis signifient qu'il n'y a pas d'arête entre les sommets.
De façon très surprenante la structure de données
qui sera utilisée pour la matrice d'adjacence dans ce travail est une ... matrice d'entiers.
# Lecture de fichier XML
Dans un premier temps, vous devez construire les deux représentations des graphes
discutées ci-dessus à partir du fichier XML, `villes.xml`, que vous trouverez sur Cyberlearn.
Pour ce faire, il faut utiliser la librairie `libxml2`, ainsi que le code
à trous se trouvant également sur Cyberlearn. Il s'agit ici de compléter ce code afin
de faire deux choses:
1. Créer un tableau contenant les noms des villes, ainsi que leurs positions sur la carte.
2. A partir du tableau des villes et des informations de la connectivité, créer la liste et la matrice d'adjacence. Les poids des arêtes représentent le temps de parcours entre les villes.
## Structures de données
Vous devez donc créer différentes structures pour contenir
les informations décrites ci-dessus. Tout d'abord la structure
contenant les informations sur les villes dans la structure `city`
```C
#define NAME_LEN 50
typedef struct _city {
char name[NAME_LEN];
int longitude;
int latitude;
} city;
```
Pour stocker un tableau de villes, vous avez deux choix. Vous reprenez
la structure `vector` que vous avez créée pour le travail pratique
sur la triangulation et en changez le "type".
Vous pouvez également utiliser un vecteur "générique"
si vous l'avez déjà implémenté ou si vous souhaitez le faire
(mais ce n'est pas obligatoire).
Puis pour la liste d'adjacence, vous devez créer un
tableau de listes chaînées de type `connection`
```C
typedef struct _connection {
int neighbor;
int weight;
struct _connection* next;
} connection;
```
Finalement, pour la matrice d'adjacence inspirez-vous de la structure de
matrices que vous avez créée au premier semestre. Il vous suffit de
remplacer le type contenu dans la matrice d'un double en un entier
signé.
<!-- # Lecture du fichier contour de la Suisse
Plus tard dans ce travail, vous devrez afficher le contour de la Suisse.
Ces données se trouvent dans le fichier texte, `suisse.txt`, que vous pouvez
télécharger depuis Cyberlearn. Ce fichier ne contient que des paires d'entiers
représentant la longitude et la latitude du pourtour de la Suisse. -->
# Si vous avez terminé
Si vous avez terminé le travail ci-dessus, attaquez-vous aux algorithmes de Floyd et Dijkstra
que vous avez vus au cours d'algorithmique.
N'oubliez pas de vous servir de la file de priorité
pour l'algorithme de Dijkstra.
# Remarques
1. Une fois le tableau des villes créé, vous devez faire une correspondance
entre le nom de la ville et un indice. Pour ce faire vous pouvez simplement utiliser
l'indice de la ville dans le "tableau des villes".
2. Pour représenter les poids infinis, utiliser la macro `INT_MAX` se trouvant dans `limits.h`.
3. Si elle n'est pas encore installée sur votre système, vous devez installer la librairie
`libxml2`. Si vous utilisez une distribution Ubuntu ou basée sur ArchLinux,
faites les commandes suivantes:
* Ubuntu
```bash
sudo apt install libxml2 libxml2-dev
```
* Manjaro/ArchLinux
```bash
sudo pacman -Sy libxml2
```
Pour compiler avec les fichiers sources et obtenir le code objet vous dever utiliser l'option
`-I` qui permet d'inclure un chemin spécifique.
```bash
gcc -c xml_parser.c -I/usr/include/libxml2
```
Pour linker il faut ensuite utiliser l'option `-lxml2`.
4. Les exemples pour l'utilisation de la lecture de fichiers XML compilent[^1], mais il manque des arguments aux fonctions.
Il faut les rajouter pour que votre code remplisse les différentes structures de données
nécessaires au bon déroulement de ce travail. Notez
également que ces fonctions sont récursives.
[^1]: Ils génèrent le code objet avec la commande `gcc -c xml_parser.c -I/usr/include/libxml2`.
\ No newline at end of file
#include <stdio.h>
#include <string.h>
#include "xml_parser.h"
void city_xml_parser(xmlNode * a_node) {
xmlNode *cur_node = NULL;
for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
if (cur_node->type == XML_ELEMENT_NODE) {
if(!strcmp((const char*)cur_node->name,"Ville")){
xmlNode * sub = cur_node->children;
city c; // no malloc needed values are copied
strncpy(c.name, (const char*)sub->next->children->content, NAME_LEN-1);
c.longitude = atoi((const char*)sub->next->next->next->children->content);
c.latitude = atoi((const char*)sub->next->next->next->next->next->children->content);
// ajouter c dans le vector cities
}
}
city_xml_parser(cur_node->children);
}
}
void graph_xml_parser(xmlNode * a_node)
{
xmlNode *cur_node = NULL;
for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
if (cur_node->type == XML_ELEMENT_NODE) {
if(!strcmp((const char*)cur_node->name,"Liaison")){
xmlNode * sub = cur_node->children;
char src[NAME_LEN];
char dst[NAME_LEN];
strncpy(src, (const char*)sub->next->children->content, NAME_LEN-1);
strncpy(dst, (const char*)sub->next->next->next->children->content, NAME_LEN-1);
int duration = atoi((const char*)sub->next->next->next->next->next->children->content);
// ajouter l'arête dans la liste et la matrice d'adjacence
}
}
graph_xml_parser(cur_node->children);
}
}
#ifndef _XML_PARSER_H_
#define _XML_PARSER_H_
#include <libxml/parser.h>
#include <libxml/tree.h>
#define NAME_LEN 50
typedef struct _city {
char name[NAME_LEN];
int longitude;
int latitude;
} city;
/** append to list of cities those found in xml
*
* @param a_node a xml node
*/
void ville_xml_parser(xmlNode * a_node);
/** add edges to graph based on links found in xml
*
* @param a_node link (liaison) xml node
*/
void graph_xml_parser(xmlNode * a_node);
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment