alobe: inital import (test).
git-svn-id: https://websvn.glenux.net/svn/Upoc/alobe/trunk@1348 eaee96b3-f302-0410-b096-c6cfd47f7835
This commit is contained in:
commit
5ca782e8b1
|
@ -0,0 +1,5 @@
|
|||
SUBDIRS = src
|
||||
|
||||
EXTRA_DIST = doc INSTALL README Doxyfile autogen.sh
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
echo "libtoolize..."
|
||||
libtoolize
|
||||
echo "aclocal..."
|
||||
aclocal
|
||||
echo "autoheader..."
|
||||
autoheader
|
||||
echo "autoconf..."
|
||||
autoconf
|
||||
echo "automake..."
|
||||
automake -a
|
||||
echo "ok."
|
|
@ -0,0 +1,218 @@
|
|||
dnl Copyright (C) 2004-2005 Glenn ROLLAND.
|
||||
dnl
|
||||
dnl This program is free software; you can redistribute it and/or modify
|
||||
dnl it under the terms of the GNU General Public License as published by
|
||||
dnl the Free Software Foundation; either version 2 of the License, or
|
||||
dnl (at your option) any later version.
|
||||
dnl
|
||||
dnl This program is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
dnl GNU General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with this program; if not, write to the Free Software
|
||||
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
dnl
|
||||
|
||||
## Autoconf requirements
|
||||
AC_INIT([alobe], [0.0.2], [glenux@fr.st])
|
||||
AC_PREREQ(2.50)
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
AC_CANONICAL_TARGET
|
||||
|
||||
|
||||
AM_INIT_AUTOMAKE([alobe],[0.0.2])
|
||||
|
||||
#AC_CANONICAL_SYSTEM
|
||||
|
||||
|
||||
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
AC_CONFIG_SRCDIR([src/alobe.h])
|
||||
AC_PROG_INSTALL
|
||||
|
||||
## information on the package
|
||||
## ## checks for programs
|
||||
## checks for libraries
|
||||
## checks for header files
|
||||
## checks for types
|
||||
## checks for structures
|
||||
## checks for compiler characteristics
|
||||
## checks for library functions
|
||||
## checks for system services
|
||||
|
||||
#AM_CONFIG_HEADER(config.h)
|
||||
## required for c sources
|
||||
|
||||
AC_ISC_POSIX
|
||||
AC_PROG_CC
|
||||
## required for c++ sources
|
||||
AC_PROG_CXX
|
||||
AC_PROG_CPP
|
||||
# AC_PROG_RANLIB obsoleted bu LIBTOOL
|
||||
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_CPLUSPLUS
|
||||
|
||||
# AC_PROG_YACC
|
||||
# AC_PROG_LEX
|
||||
# AM_PROG_LEX
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_HEADER_STDC([])
|
||||
|
||||
#TODO: uncomment
|
||||
#AC_CHECK_HEADERS([iostream string list iterator exception],,
|
||||
# AC_MSG_ERROR([You need to have the libstdc++ headers installed]))
|
||||
|
||||
dnl ***************************************************************************
|
||||
dnl Gettext stuff.
|
||||
dnl ***************************************************************************
|
||||
|
||||
#GETTEXT_PACKAGE=yalag-0.1
|
||||
#AC_SUBST(GETTEXT_PACKAGE)
|
||||
#AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Gettext package.])
|
||||
|
||||
#ALL_LINGUAS="fr"
|
||||
#AM_GLIB_GNU_GETTEXT
|
||||
|
||||
|
||||
dnl Check for programs
|
||||
|
||||
dnl Check for build configuration.
|
||||
#AC_PROG_INTLTOOL
|
||||
|
||||
AM_PROG_LIBTOOL
|
||||
|
||||
dnl Checks for header files.
|
||||
|
||||
#AC_MSG_NOTICE([checking presence of SQLite])
|
||||
#AC_CHECK_HEADERS([sqlite.h],[],
|
||||
# [
|
||||
# AC_MSG_NOTICE([*** Please install/upgrade SQLite before proceeding])
|
||||
# AC_MSG_NOTICE([*** with Unlost Memories installation.])
|
||||
# AC_MSG_ERROR([cannot find sqlite.h])
|
||||
# ])
|
||||
|
||||
#sqlite_deps="sqlite3 >= 3.0"
|
||||
#PKG_CHECK_MODULES(SQLITE3,$sqlite_deps,build_sqlite=yes,build_sqlite=no)
|
||||
#AC_SUBST(SQLITE3_CFLAGS)
|
||||
#AC_SUBST(SQLITE3_LIBS)
|
||||
|
||||
#glib_deps="glib-2.0 >= 2.0"
|
||||
#PKG_CHECK_MODULES(GLIB2,$glib_deps, build_glib=yes, build_glib=no)
|
||||
#AC_SUBST(GLIB2_CFLAGS)
|
||||
#AC_SUBST(GLIB2_LIBS)
|
||||
|
||||
#xsock_deps="xsock >= 0.8"
|
||||
#PKG_CHECK_MODULES(XSOCK,$xsock_deps, build_xsock=yes, build_xsock=no)
|
||||
#AC_SUBST(XSOCK_CFLAGS)
|
||||
#AC_SUBST(XSOCK_LIBS)
|
||||
#if test "$build_xsock" = "no"; then
|
||||
# AC_MSG_NOTICE([*** Please install/upgrade libxsock-dev before proceeding])
|
||||
# AC_MSG_NOTICE([*** with installation.])
|
||||
# AC_MSG_ERROR([cannot find xsock])
|
||||
#fi
|
||||
|
||||
#glibmm_deps="glibmm-2.4 >= 2.4"
|
||||
#PKG_CHECK_MODULES(GLIBMM,$glibmm_deps, build_glibmm=yes, build_glibmm=no)
|
||||
#AC_SUBST(GLIBMM_CFLAGS)
|
||||
#AC_SUBST(GLIBMM_LIBS)
|
||||
#if test "$build_glibmm" = "no"; then
|
||||
# AC_MSG_NOTICE([*** Please install/upgrade libglibmm-2.4-dev before proceeding])
|
||||
# AC_MSG_NOTICE([*** with Ytem installation.])
|
||||
# AC_MSG_ERROR([cannot find glibmm-2.4])
|
||||
#fi
|
||||
|
||||
|
||||
#gdkmm_deps="gdkmm-2.4 >= 2.4"
|
||||
#PKG_CHECK_MODULES(GDKMM,$gdkmm_deps, build_gdkmm=yes, build_gdkmm=no)
|
||||
#AC_SUBST(GDKMM_CFLAGS)
|
||||
#AC_SUBST(GDKMM_LIBS)
|
||||
#if test "$build_gdkmm" = "no"; then
|
||||
# AC_MSG_NOTICE([*** ])
|
||||
# AC_MSG_NOTICE([*** Please install/upgrade libgdkmm-2.4-dev before proceeding])
|
||||
# AC_MSG_NOTICE([*** with Ytem installation.])
|
||||
# AC_MSG_NOTICE([*** ])
|
||||
# AC_MSG_ERROR([cannot find gdkmm-2.4])
|
||||
#fi
|
||||
|
||||
#gtkmm_deps="gtkmm-2.4 >= 2.4"
|
||||
#PKG_CHECK_MODULES(GTKMM,$gtkmm_deps, build_gtkmm=yes, build_gtkmm=no)
|
||||
#AC_SUBST(GTKMM_CFLAGS)
|
||||
#AC_SUBST(GTKMM_LIBS)
|
||||
#if test "$build_gtkmm" = "no"; then
|
||||
# AC_MSG_NOTICE([*** ])
|
||||
# AC_MSG_NOTICE([*** Please install/upgrade libgtkmm-2.4-dev before proceeding])
|
||||
# AC_MSG_NOTICE([*** with Ytem installation.])
|
||||
# AC_MSG_NOTICE([*** ])
|
||||
# AC_MSG_ERROR([cannot find gtkmm-2.4])
|
||||
#fi
|
||||
|
||||
##########
|
||||
# Figure out where to get the READLINE header files.
|
||||
#
|
||||
#AC_MSG_CHECKING([readline header files])
|
||||
#found=no
|
||||
#if test "$config_TARGET_READLINE_INC" != ""; then
|
||||
# TARGET_READLINE_INC=$config_TARGET_READLINE_INC
|
||||
# found=yes
|
||||
#fi
|
||||
#if test "$found" = "yes"; then
|
||||
# AC_MSG_RESULT($TARGET_READLINE_INC)
|
||||
#else
|
||||
# AC_MSG_RESULT(not specified: still searching...)
|
||||
# AC_CHECK_HEADER(readline.h, [found=yes])
|
||||
#fi
|
||||
#if test "$found" = "no"; then
|
||||
# for dir in /usr /usr/local /usr/local/readline /usr/contrib /mingw /sw; do
|
||||
# AC_CHECK_FILE($dir/include/readline.h, found=yes)
|
||||
# if test "$found" = "yes"; then
|
||||
# TARGET_READLINE_INC="-I$dir/include"
|
||||
# break
|
||||
# fi
|
||||
# AC_CHECK_FILE($dir/include/readline/readline.h, found=yes)
|
||||
# if test "$found" = "yes"; then
|
||||
# TARGET_READLINE_INC="-I$dir/include/readline"
|
||||
# break
|
||||
# fi
|
||||
# done
|
||||
#fi
|
||||
#if test "$found" = "yes"; then
|
||||
# if test "$TARGET_READLINE_LIBS" = ""; then
|
||||
# TARGET_HAVE_READLINE=0
|
||||
# else
|
||||
# TARGET_HAVE_READLINE=1
|
||||
# fi
|
||||
#else
|
||||
# TARGET_HAVE_READLINE=0
|
||||
#fi
|
||||
#AC_SUBST(TARGET_READLINE_INC)
|
||||
#AC_SUBST(TARGET_HAVE_READLINE)
|
||||
|
||||
#libxml2_deps="libxml-2.0 >= 2.4.1"
|
||||
#PKG_CHECK_MODULES(LIBXML2,$libxml2_deps, build_libxml2=yes, build_libxml2=no)
|
||||
#AC_SUBST(LIBXML2_CFLAGS)
|
||||
#AC_SUBST(LIBXML2_LIBS)
|
||||
|
||||
#if test $build_libxml2 == yes ; then
|
||||
# AC_DEFINE(HAVE_LIBXML2_H,1,[Vaut 1 lorsque l'on utilise LIBXML2.])
|
||||
#else
|
||||
# AC_DEFINE(HAVE_LIBXML2_H,0,[Vaut 1 lorsque l'on utilise LIBXML2.])
|
||||
#fi
|
||||
|
||||
#libxmlpp_deps="libxml++-2.6 >= 2.8"
|
||||
#PKG_CHECK_MODULES(LIBXMLPP,$libxmlpp_deps, build_libxmlpp=yes, build_libxmlpp=no)
|
||||
#AC_SUBST(LIBXMLPP_CFLAGS)
|
||||
#AC_SUBST(LIBXMLPP_LIBS)
|
||||
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
src/Makefile
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
dnl configure.in ends here
|
|
@ -0,0 +1,10 @@
|
|||
Exercice 1 : Récuperer des données pour la page:
|
||||
http://www.liafa.jussieu.fr/~latapy/Data
|
||||
Les fichiers *.index contiennent la corerspondance entre le nom des sommets et leur numéro. Les numéros vont de 0 n-1 ou n est le nombre de sommets du graphe. Le fichier commence par une ligne donnant n.
|
||||
Les fichiers *.data contiennent une description du graphe sous la forme de lignes x y qui signifient qu'il existe un lien entre le sommet numéro x et le sommet numéro y. Il n'y a pas de dupliocation de lignes (autrement dit, chaque lien n'apparait qu'une fois).
|
||||
|
||||
------
|
||||
Défi 1
|
||||
|
||||
prieur@liafa.jussieu.fr
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/* Generated by CaScadeS, a stylesheet editor for Mozilla Composer */
|
||||
|
||||
p.code { border: 2px dashed rgb(153, 153, 153);
|
||||
padding: 5px;
|
||||
background: rgb(204, 204, 204) none repeat scroll 0% 50%;
|
||||
-moz-background-clip: initial;
|
||||
-moz-background-origin: initial;
|
||||
-moz-background-inline-policy: initial;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
div.page { border: 2px dashed rgb(153, 153, 153);
|
||||
padding: 10px;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
right: 10px;
|
||||
bottom: 10px;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
background-color: rgb(255, 255, 255);
|
||||
opacity: 1;
|
||||
width: 60%;
|
||||
font-family: Arial,Helvetica,sans-serif;
|
||||
}
|
||||
|
||||
body { background-color: rgb(51, 51, 51);
|
||||
}
|
||||
|
||||
span.code { border: 1px dashed rgb(153, 153, 153);
|
||||
background-color: rgb(204, 204, 204);
|
||||
font-family: monospace;
|
||||
}
|
||||
|
|
@ -0,0 +1,357 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html lang="fr-fr">
|
||||
<head>
|
||||
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
|
||||
<link rel="stylesheet" type="text/css" href="index.css">
|
||||
<title>Alobé</title>
|
||||
<meta content="Glenn ROLLAND" name="author">
|
||||
</head>
|
||||
<body style="direction: ltr;">
|
||||
<div style="text-align: justify;" class="page">
|
||||
<h1>Alobé</h1>
|
||||
<h2><a name="1._Description"></a>1.
|
||||
<a name="Description"></a>Description</h2>
|
||||
<p>Alobé est
|
||||
un logiciel libres permettant de manipuler de grands graphes
|
||||
non-orientés décrits par la liste de leurs
|
||||
arrêtes. Il possède les
|
||||
caractéristiques
|
||||
suivantes :</p>
|
||||
<ul>
|
||||
<li>Il est distribué
|
||||
sous la licence <a href="http://www.gnu.org/copyleft/gpl.html">GNU
|
||||
General Public License</a></li>
|
||||
<li>Il est
|
||||
écrit en C (bien qu'écrit au départ en
|
||||
C++, comme en témoigne le dépôt
|
||||
subversion) et possède une interface en ligne
|
||||
de
|
||||
commande,</li>
|
||||
<li>Il implémente le
|
||||
filtrage du graphe pour l'extraction d'un sous-ensemble
|
||||
(exercice 2).</li>
|
||||
<li>Il implémente le
|
||||
calcul des degrés (exercice 3)</li>
|
||||
<li>Il implémente les
|
||||
statistiques sur le calcul des degrés (degré
|
||||
moyen, degré maximum, densité du graphe)
|
||||
(exercice 5)</li>
|
||||
<li>Il implémente le
|
||||
stockage des données de façon contigüe
|
||||
en mémoire (en un unique tableau) (exercice 4).</li>
|
||||
<li>Il implémente le
|
||||
calcul des composantes connexes de façon efficace (exercice
|
||||
5). </li>
|
||||
<li>Il implémente une
|
||||
méthode de calcul alternatif des composantes connexes
|
||||
(exercice 6 - défi).</li>
|
||||
</ul>
|
||||
<h3>1.1.
|
||||
Auteurs</h3>
|
||||
<p>Alobé a
|
||||
été entièrement
|
||||
réalisé par Glenn ROLLAND <<a
|
||||
href="mailto:glenux@fr.st">glenux@fr.st</a>>
|
||||
à l'occasion de travaux pratiques du cours de <span
|
||||
style="font-style: italic;">Grand Réseaux</span>
|
||||
du Master 2 Ingénierie Informatique
|
||||
-
|
||||
Systèmes, Réseaux et Internet.</p>
|
||||
<h2><a99 name="2._Pré-requis">2.
|
||||
Pré-requis</a99></h2>
|
||||
<p>Alobé
|
||||
ne nécessite pas de bibliothèques de
|
||||
fonctions
|
||||
particulières pour fonctionnner.</p>
|
||||
<h2>3.
|
||||
Se procurer Alobé</h2>
|
||||
Vous
|
||||
pouvez télécharger la dernière archive
|
||||
des
|
||||
sources, ou bien directement la version la plus récente du
|
||||
projet sur le dépôt Subversion du projet.<br>
|
||||
<h3>3.1. L'archive des sources</h3>
|
||||
Elle est disponible à l'adresse : <br>
|
||||
<a href="http://glenux2.free.fr/pub/projets/Alobe/archives/">http://glenux2.free.fr/pub/projets/Alobe/archives/</a><br>
|
||||
<h3>3.2. Le
|
||||
dépôt Subversion</h3>
|
||||
<p>Afin d'obtenir les sources les
|
||||
plus à jour, vous pouvez utiliser le logiciel de
|
||||
contrôle de sources Subversion </p>
|
||||
<p class="code">$ svn
|
||||
checkout http://repository.glenux.ath.cx/svn/Cours/M2/Grand_Reseaux/TP1/</p>
|
||||
<p>Il n'y a pas de mot de passe,
|
||||
il suffit donc de presser la touche
|
||||
"Entrée" pour l'utilisateur "anonymous", si ce dernier vous
|
||||
est
|
||||
demandé.</p>
|
||||
<h2><a name="4._Utiliser_Alobé"></a>4.
|
||||
Utiliser Alobé</h2>
|
||||
<h3><a name="4.1._Compilation"></a>4.1.
|
||||
Compilation</h3>
|
||||
<p>Commencez par
|
||||
décompressez l'archive.</p>
|
||||
<p class="code">$ tar -xzvf
|
||||
alobe-0.1.tar.gz</p>
|
||||
<p>Rendez vous ensuite dans le
|
||||
dossier qui vient d'être créé lors de
|
||||
la décompression.</p>
|
||||
<p class="code">$ cd
|
||||
alobe-0.1</p>
|
||||
<p>Puis lancez
|
||||
l'auto-configuration du logiciel, puis la compilation.</p>
|
||||
<p class="code">$ ./autogen<br>
|
||||
$ ./configure<br>
|
||||
$ make</p>
|
||||
<p>Le binaire produits se trouve
|
||||
dans le dossier :</p>
|
||||
<ul>
|
||||
<li> <span class="code">src/alobe</span></li>
|
||||
</ul>
|
||||
<h3><a name="4.2._Utilisation"></a>4.2.
|
||||
Utilisation</h3>
|
||||
<div style="text-align: justify;">Les
|
||||
binaires de Alobé doivent être appelés
|
||||
avec la syntaxe suivante:<br>
|
||||
</div>
|
||||
<p class="code">Usage:
|
||||
alobe <commande> <parametres_obligatoires>
|
||||
[options]<br>
|
||||
</p>
|
||||
<p>Les commandes sont
|
||||
les suivants:</p>
|
||||
<dl>
|
||||
<dt>-F, --filter</dt>
|
||||
<dd>Filtrage du fichier
|
||||
d'entrée pour extraire un sous-graphe.</dd>
|
||||
<dt> -D, --degree </dt>
|
||||
<dd>Calcul du degré
|
||||
des noeuds du graphe pris en entrée.</dd>
|
||||
<dt>-S, --store</dt>
|
||||
<dd>Stockage et remplissage du
|
||||
tableau représentant le graphe en mémoire.</dd>
|
||||
<dt>-A, --average</dt>
|
||||
<dd>Calcul des statistiques sur
|
||||
les noeuds du graphe d'entrée (degré moyen,
|
||||
degré max, densité).</dd>
|
||||
<dt>-C, --connexity</dt>
|
||||
<dd>Calcul des composantes
|
||||
connexes par la méthode du tableau unique.</dd>
|
||||
<dt>-E, --defi</dt>
|
||||
<dd>Calcul des composantes
|
||||
connexes par ensembles d'intervalles de noeuds.</dd>
|
||||
</dl>
|
||||
<ul>
|
||||
</ul>
|
||||
<p>Les paramètres
|
||||
obligatoires sont les suivants:</p>
|
||||
<dl>
|
||||
<dt>-c, --count <entier> <fichier>
|
||||
</fichier></dt>
|
||||
<dd>Nombre de noeuds du fichier d'entrée.</dd>
|
||||
<dt>-s, --size <entier></dt>
|
||||
<dd>Taille du filtre</dd>
|
||||
<dt>-t, --offset <entier></dt>
|
||||
<dd>Offset du filtre</dd>
|
||||
</dl>
|
||||
<p>Les parames optionnels sont les
|
||||
suivants:</p>
|
||||
<dl>
|
||||
<dt>-i, --input
|
||||
<fichier></dt>
|
||||
<dd> Le fichier
|
||||
d'entrée, "-" désignant l'entrée
|
||||
standard,</dd>
|
||||
<dt>-o, --output
|
||||
<fichier></dt>
|
||||
<dd>Le fichier de sorftie, "-"
|
||||
désignant la sortie standard.</dd>
|
||||
<dt>-v, --verbose</dt>
|
||||
<dd> Passe l'affichage en mode
|
||||
verbeux.e
|
||||
numéro du noeud à lire et afficher à partir du
|
||||
fichier
|
||||
compressé</dd>
|
||||
</dl>
|
||||
<h2><a name="5._Documentation"></a>5.
|
||||
Documentation</h2>
|
||||
<h3>5.1. Code</h3>
|
||||
<p>Vous pouvez trouver la
|
||||
documentation de Alobé dans le dossier <span class="code">doc/html</span>
|
||||
de l'application, ou en suivant <a href="html/index.html">ce lien</a>.</p>
|
||||
<h3>5.2. Remarques sur les
|
||||
différents exercices</h3>
|
||||
<h4>5.2.1. Exercice 1</h4>
|
||||
<br>
|
||||
<h4>5.2.2. Exercice 2</h4>
|
||||
<p>Il est possible de filtrer le
|
||||
graphe d'entrée pour extraire un sous ensemble de noeuds de
|
||||
la façon suivante :</p>
|
||||
<p class="code">./src/alobe -F -t 0 -s 60 -i ../web.data.gz -c 701654</p>
|
||||
<p class="">Ce qui
|
||||
produit en sortie</p>
|
||||
<p class="code">Command -> FILTER<br>
|
||||
Offset -> 0<br>
|
||||
Size -> 30<br>
|
||||
Input Data -> ../web.data.gz<br>
|
||||
Input Index -> 701654<br>
|
||||
Filtering between [ 0 .. 30 ]...<br>
|
||||
0 1<br>
|
||||
0 2<br>
|
||||
1 3<br>
|
||||
1 4<br>
|
||||
1 5<br>
|
||||
1 6<br>
|
||||
1 7<br>
|
||||
1 8<br>
|
||||
1 9<br>
|
||||
1 10<br>
|
||||
1 11<br>
|
||||
1 12<br>
|
||||
<br>
|
||||
[...]<br>
|
||||
<br>
|
||||
( uniquement les noeuds x compris entre 0 <= x < 30 )</p>
|
||||
<h4>5.2.3. Exercice 3</h4>
|
||||
<p>Le calcul du degré des noeuds se fait par la commande
|
||||
suivante :</p>
|
||||
<p class="code">./src/alobe -D -i ../web.data.gz -c 701654</p>
|
||||
<p class="">Ce qui produit (en première colone l'index du noeud
|
||||
et en seconde le degré):</p>
|
||||
<p class="code">Command -> DEGREE<br>
|
||||
Input Data -> ../web.data.gz<br>
|
||||
Input Index -> 701654<br>
|
||||
Computing degree of each node...<br>
|
||||
done<br>
|
||||
0 2<br>
|
||||
1 1194<br>
|
||||
2 77<br>
|
||||
3 496<br>
|
||||
4 227<br>
|
||||
5 339<br>
|
||||
6 337<br>
|
||||
7 340<br>
|
||||
8 337<br>
|
||||
9 10<br>
|
||||
10 16<br>
|
||||
11 31<br>
|
||||
12 15<br>
|
||||
13 22<br>
|
||||
<br>
|
||||
[...]</p>
|
||||
<p class="">Le calcul du degré est effectué dans un
|
||||
tableau de <span style="font-weight: bold;">sizeof(long) * N</span>
|
||||
(où N est le nombre de noeuds), initialisé à
|
||||
zéro, et où les valeurs des cases sont
|
||||
incrémentées à la lecture des arcs.<br>
|
||||
</p>
|
||||
<h4>5.2.4. Exercice 4</h4>
|
||||
<p>Le simple stockage du graphe en mémoire ne produit pas de
|
||||
sortie visible, mais s'execute en tapant :</p>
|
||||
<p class="code">./src/alobe -S -i ../web.data.gz -c 701654</p>
|
||||
Le programme commence par calculer les degrés, puis initialise
|
||||
un tableau de taille N (N = nombre de noeuds) pointeurs vers les cases
|
||||
d'un tableau de taille <span style="font-weight: bold;">(M + 3) *
|
||||
sizeof(long)</span> (où M est la somme des degrés des
|
||||
noeuds) destiné à contenir les arcs de chaque noeud. Les
|
||||
3 cases supplémentaires ne servent qu'au calcul des composates
|
||||
connexes et seront décrites plus loin.<br>
|
||||
<h4>5.2.5. Exercice 5</h4>
|
||||
<p>Le calcul des statistiques sur les noeuds du graphe se fait de la
|
||||
façon suivante:</p>
|
||||
<p class="code">./src/alobe -A -i ../web.data.gz -c 701654</p>
|
||||
<p class="code">Command -> AVERAGE<br>
|
||||
Input Data -> ../web.data.gz<br>
|
||||
Input Index -> 701654<br>
|
||||
Computing degree of each node...<br>
|
||||
done<br>
|
||||
Degree average: 5.517015<br>
|
||||
Degree maximum: 5331<br>
|
||||
Density : 0.000000<br>
|
||||
</p>
|
||||
<p class="">Cet exercice réutilise la structure de
|
||||
données l'éxercice 3, et en la parcourant effectue le
|
||||
calcul.</p>
|
||||
<h4>5.2.6. Exercice 6</h4>
|
||||
<p>Le calcul des composantes connexes se fait de la façon
|
||||
suivante :</p>
|
||||
<p class="code">./src/alobe -C -i ../web.data.gz -c 701654</p>
|
||||
<p class="code">Command -> CONNEXITY<br>
|
||||
Input Data -> ../web.data.gz<br>
|
||||
Input Index -> 701654<br>
|
||||
Computing degree of each node...<br>
|
||||
done<br>
|
||||
Filling the Big Table...<br>
|
||||
done<br>
|
||||
Found connex component at 0<br>
|
||||
Found connex component at 9484<br>
|
||||
Found connex component at 15516<br>
|
||||
Found connex component at 17477<br>
|
||||
Found connex component at 20073<br>
|
||||
Found connex component at 20100<br>
|
||||
<br>
|
||||
[...]<br>
|
||||
<br>
|
||||
Found connex component at 699413<br>
|
||||
Found connex component at 700568<br>
|
||||
Found connex component at 701306<br>
|
||||
Found connex component at 701313<br>
|
||||
Found 970 connex components</p>
|
||||
<p class="">Pour le fichier <span style="font-weight: bold;">IP.data.gz</span>
|
||||
on obtient :</p>
|
||||
<p class="code">Command -> CONNEXITY<br>
|
||||
Input Data -> /home/warbrain/Films/IP.data.gz<br>
|
||||
Input Index -> 467273<br>
|
||||
Computing degree of each node...<br>
|
||||
done<br>
|
||||
Filling the Big Table...<br>
|
||||
done<br>
|
||||
Found connex component at 0<br>
|
||||
Found connex component at 324896<br>
|
||||
Found 2 connex components</p>
|
||||
<p class="">Et pour le fichier <span style="font-weight: bold;">P2P.data.gz</span>
|
||||
les machines à ma disposition ne possédaient pas
|
||||
suffisament de mémoire...</p>
|
||||
<p class="">Le calcul des composantes connexes utilise le même
|
||||
tableau que l'exercice 4. Le calcul se fait dans les 3 cases
|
||||
supplémentaires :<br>
|
||||
</p>
|
||||
<ul>
|
||||
<li>une case pour le degré du noeud</li>
|
||||
<li>une case pour l'offset du noeud traité</li>
|
||||
<li>une case pour le noeud "père" dans le parcours en
|
||||
profondeur.</li>
|
||||
</ul>
|
||||
<p class="">Lorsqu'on parcours un noeud x en provenance de y, on
|
||||
inscrit la référence du noeud père dans la case 3,
|
||||
puis pour chaque noeud adjacent non visité, on indique le
|
||||
noeud adjacent parcouru actuellement puis on parcourt
|
||||
récursivement le noeud adjacent.</p>
|
||||
<p class="">Remarque: jusque là le TP était
|
||||
programmé en C++, et pour un éventeuel gain de
|
||||
performances il fut réécrit entièrement (en
|
||||
conservant les structures de données) en C. Cependant seules 0.3
|
||||
secondes furent gagnées sur le graphe <span
|
||||
style="font-weight: bold;">web.data.gz</span>... sur un temps de
|
||||
calcul total de 14 sec... (sur un iBook G4 1Ghz avec 256 Mo de RAM sous
|
||||
GNU/Linux).</p>
|
||||
<h4>5.2.7. Défi</h4>
|
||||
<p class="">On suppose que dans le graphe du web, les noeud adjacents
|
||||
ont de fortes chances d'appartenir à la même composante
|
||||
connexe. <br>
|
||||
Ainsi, pour décrire en mémoire une composante regroupant
|
||||
les noeuds <span style="font-weight: bold;">{0, 1, 2 ,3 ,4, 5, 6, 7,
|
||||
8, 9, 10, 14,15,16, 17, 19, 20}</span> null besoin de stocker en
|
||||
mémoire autre chose que les ensembles d'intervalles suivants: <span
|
||||
style="font-weight: bold;">[0 .. 10] U [14 .. 17] U [19 .. 20] </span>...</p>
|
||||
<p class="">Cependant, les fusions d'ensembles nécessitent de
|
||||
nombreuses recopies de données et d'allocations de
|
||||
mémoire. L'algorithme s'en trouve par conséquent fort
|
||||
ralenti...</p>
|
||||
<p class="">On peut lancer le défi en tapant :</p>
|
||||
<p class="code">./src/alobe -E -i ../web.data.gz -c 701654</p>
|
||||
<p class="">..et admirer les résultats (s'il apparaissent, car
|
||||
il y a encore pas mal de soucis de pointeurs se baladant librement...)</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,360 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html lang="fr-fr">
|
||||
<head>
|
||||
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
|
||||
<link rel="stylesheet" type="text/css" href="index.css">
|
||||
<title>Alobé</title>
|
||||
<meta content="Glenn ROLLAND" name="author">
|
||||
</head>
|
||||
<body style="direction: ltr;">
|
||||
<div style="text-align: justify;" class="page">
|
||||
<h1>Alobé (TP2)</h1>
|
||||
<h2><a name="1._Description"></a>1.
|
||||
<a name="Description"></a>Description</h2>
|
||||
<p>Alobé est
|
||||
un logiciel libre permettant de manipuler de grands graphes
|
||||
non-orientés décrits par la liste de leurs
|
||||
arrêtes. Il possède les
|
||||
caractéristiques
|
||||
suivantes :</p>
|
||||
<ul>
|
||||
<li>Il est distribué
|
||||
sous la licence <a href="http://www.gnu.org/copyleft/gpl.html">GNU
|
||||
General Public License</a></li>
|
||||
<li>Il est
|
||||
écrit en C (bien qu'écrit au départ en
|
||||
C++, comme en témoigne le dépôt
|
||||
subversion) et possède une interface en ligne
|
||||
de
|
||||
commande,</li>
|
||||
<li>Il implémente le
|
||||
calcul de la distance d'un noeud à tous les autres
|
||||
(exercice 1).</li>
|
||||
<li>Il fournit en sortie des
|
||||
données permettant de tracer la
|
||||
distribution des distance à un noeud donné
|
||||
(exercice 2)</li>
|
||||
<li>Il fournit en sortie les
|
||||
données permettant de tracer
|
||||
l'évolution de l'estimation de la distance moyenne en
|
||||
fonction
|
||||
du nombre de parcours effectués.
|
||||
(exercice 3)</li>
|
||||
<li>Il implémente le
|
||||
calcul de la borne inférieure du
|
||||
diamètre, en prenant la distance maximale d'un noeud
|
||||
donné à tous les autres (exercice 4).</li>
|
||||
<li>Il implémente le
|
||||
calcul de la borne supérieure du diamètre, en
|
||||
prenant la
|
||||
distance maximale dans l'arbre du parcours en largeur (exercice
|
||||
5). </li>
|
||||
<li>Il fournit en sortie des
|
||||
données permettant de tracer les
|
||||
courbes des meilleurs bornes inférieures et
|
||||
supérieure en
|
||||
fonction du nombre de parcours effectués.
|
||||
(exercice 6 - défi).</li>
|
||||
</ul>
|
||||
<h3>1.1.
|
||||
Auteurs</h3>
|
||||
<p>Alobé a
|
||||
été entièrement
|
||||
réalisé par Glenn ROLLAND <<a
|
||||
href="mailto:glenux@fr.st">glenux@fr.st</a>>
|
||||
à l'occasion de travaux pratiques du cours de <span
|
||||
style="font-style: italic;">Grand Réseaux</span>
|
||||
du Master 2 Ingénierie Informatique
|
||||
-
|
||||
Systèmes, Réseaux et Internet.</p>
|
||||
<h2><a99 name="2._Pré-requis">2.
|
||||
Pré-requis</a99></h2>
|
||||
<p>Alobé
|
||||
ne nécessite pas de bibliothèques de
|
||||
fonctions
|
||||
particulières pour fonctionnner.</p>
|
||||
<h2>3.
|
||||
Se procurer Alobé</h2>
|
||||
Vous
|
||||
pouvez télécharger la dernière archive
|
||||
des
|
||||
sources, ou bien directement la version la plus récente du
|
||||
projet sur le dépôt Subversion du projet.<br>
|
||||
<h3>3.1. L'archive des sources</h3>
|
||||
Elle est disponible à l'adresse : <br>
|
||||
<a href="http://glenux2.free.fr/pub/projets/Alobe/archives/">http://glenux2.free.fr/pub/projets/Alobe/archives/</a><br>
|
||||
<h3>3.2. Le
|
||||
dépôt Subversion</h3>
|
||||
<p>Afin d'obtenir les sources les
|
||||
plus à jour, vous pouvez utiliser le logiciel de
|
||||
contrôle de sources Subversion </p>
|
||||
<p class="code">$ svn
|
||||
checkout http://repository.glenux.ath.cx/svn/Cours/M2/Grand_Reseaux/TP1/</p>
|
||||
<p>Il n'y a pas de mot de passe,
|
||||
il suffit donc de presser la touche
|
||||
"Entrée" pour l'utilisateur "anonymous", si ce dernier vous
|
||||
est
|
||||
demandé.</p>
|
||||
<h2><a name="4._Utiliser_Alobé"></a>4.
|
||||
Utiliser Alobé</h2>
|
||||
<h3><a name="4.1._Compilation"></a>4.1.
|
||||
Compilation</h3>
|
||||
<p>Commencez par
|
||||
décompressez l'archive.</p>
|
||||
<p class="code">$ tar -xzvf
|
||||
alobe-0.2.tar.gz</p>
|
||||
<p>Rendez vous ensuite dans le
|
||||
dossier qui vient d'être créé lors de
|
||||
la décompression.</p>
|
||||
<p class="code">$ cd
|
||||
alobe-0.2</p>
|
||||
<p>Puis lancez
|
||||
l'auto-configuration du logiciel, puis la compilation.</p>
|
||||
<p class="code">$ ./autogen<br>
|
||||
$ ./configure<br>
|
||||
$ make</p>
|
||||
<p>Le binaire produits se trouve
|
||||
dans le dossier :</p>
|
||||
<ul>
|
||||
<li> <span class="code">src/alobe</span></li>
|
||||
</ul>
|
||||
<h3><a name="4.2._Utilisation"></a>4.2.
|
||||
Utilisation</h3>
|
||||
<div style="text-align: justify;">Les
|
||||
binaires de Alobé doivent être appelés
|
||||
avec la syntaxe suivante:<br>
|
||||
</div>
|
||||
<p class="code">Usage:
|
||||
alobe <commande> <parametres_obligatoires>
|
||||
[options]<br>
|
||||
</p>
|
||||
<p>Les commandes sont
|
||||
les suivants:</p>
|
||||
<dl>
|
||||
<dt>-I, --tp2distance</dt>
|
||||
<dd>Calcule les distances
|
||||
à partir du noeud donné.</dd>
|
||||
<dt> -J, --tp2distanceplot </dt>
|
||||
<dd>Donne la distribution des
|
||||
distances à partir du noeud donné.</dd>
|
||||
<dt>-L, --tp2distevolution</dt>
|
||||
<dd>Donne l'évolution
|
||||
de l'estimation de la distance moyenne.pour un noeud donné,
|
||||
ou au hasard, en fonction du nombre d'itérations.</dd>
|
||||
<dt>-M, --tp2limitinf</dt>
|
||||
<dd>Calcule la borne
|
||||
inférieure du diamètre pour un noeud
|
||||
donné ou au hasard, en fonction du nombre
|
||||
d'itérations.</dd>
|
||||
<dt>-N, --tp2limitsup</dt>
|
||||
<dd>Calcule la borne
|
||||
supérieure du diamètre pour un noeud
|
||||
donné ou au hasard, en fonction du nombre
|
||||
d'itérations.</dd>
|
||||
<dt>-O, --tp2defi</dt>
|
||||
<dd>Fournit les
|
||||
données permettant de tracer les courbes de meilleures
|
||||
bornes inférieures et supérieures du
|
||||
diamètre en fonction du nombre d'itération.</dd>
|
||||
</dl>
|
||||
<ul>
|
||||
</ul>
|
||||
<p>Les paramètres
|
||||
obligatoires sont les suivants:</p>
|
||||
<dl>
|
||||
<dt>-c, --count
|
||||
<entier> <fichier> </fichier></dt>
|
||||
<dd>Nombre de noeuds du fichier
|
||||
d'entrée.</dd>
|
||||
</dl>
|
||||
<p>Les parames optionnels sont les
|
||||
suivants:</p>
|
||||
<dl>
|
||||
<dt>-i, --input
|
||||
<fichier></dt>
|
||||
<dd> Le fichier
|
||||
d'entrée, "-" désignant l'entrée
|
||||
standard,</dd>
|
||||
<dt>-o, --output
|
||||
<fichier></dt>
|
||||
<dd>Le fichier de sorftie, "-"
|
||||
désignant la sortie standard.</dd>
|
||||
<dt>-v, --verbose</dt>
|
||||
<dd> Passe l'affichage en mode
|
||||
verbeux.e
|
||||
numéro du noeud à lire et afficher à
|
||||
partir du
|
||||
fichier
|
||||
compressé</dd>
|
||||
<dt>-r, --root
|
||||
<entier></dt>
|
||||
<dd>Noeur servant de racine
|
||||
à la première itération.</dd>
|
||||
<dt>-n, --iterations
|
||||
<entier></dt>
|
||||
<dd>Nombre
|
||||
d'itérations a effectuer.</dd>
|
||||
</dl>
|
||||
<h2><a name="5._Documentation"></a>5.
|
||||
Documentation</h2>
|
||||
<h3>5.1. Code</h3>
|
||||
<p>Vous pouvez trouver la
|
||||
documentation de Alobé dans le dossier <span class="code">doc/html</span>
|
||||
de l'application, ou en suivant <a href="html/index.html">ce lien</a>.</p>
|
||||
<h3>5.2. Remarques sur les
|
||||
différents exercices</h3>
|
||||
<h4>5.2.1. Exercice 1</h4>
|
||||
<p>On calcule la distance d'un
|
||||
noeud (le 24 par exemple) à tous les autres, ainsi que la
|
||||
moyenne de toutes ses distances, par la commande suivante:</p>
|
||||
<p class="code"> ./alobe
|
||||
-I -i web.data.gz -o result.txt -c 701654 -r 24</p>
|
||||
<p class="">Ce qui produit
|
||||
le fichier result.txt suivant :</p>
|
||||
<p class="code">Maximum
|
||||
distance : 1<br>
|
||||
Average distance : 0.666667</p>
|
||||
<h4>5.2.2. Exercice 2</h4>
|
||||
<p>On obtient la distribution des
|
||||
distances pour un noeud donné (le 24 par exemple) de la
|
||||
façon suivante:</p>
|
||||
<p class="code">$ ./alobe
|
||||
-J -i web.data.gz -o result.txt -c 701654 -r 24<br>
|
||||
</p>
|
||||
<p class="">Ce qui
|
||||
produit en sortie</p>
|
||||
<p class="code">0 1<br>
|
||||
1 336<br>
|
||||
2 3017<br>
|
||||
3 21100<br>
|
||||
4 89398<br>
|
||||
5 146225<br>
|
||||
6 145567<br>
|
||||
7 118491<br>
|
||||
8 77830<br>
|
||||
9 47189<br>
|
||||
10 21247<br>
|
||||
11 8628<br>
|
||||
12 1550<br>
|
||||
13 532<br>
|
||||
14 112<br>
|
||||
15 7<br>
|
||||
16 4</p>
|
||||
<p class="">Soit le
|
||||
graphique suivant :<br>
|
||||
<img src="exercice2.png" alt="exercice 2 plot"></p>
|
||||
<h4>5.2.3. Exercice 3</h4>
|
||||
<p>On trace l'évolution
|
||||
de l'estimation de la distance moyenne (en fonction du nombre
|
||||
d'itération) par la commande suivante:</p>
|
||||
<p class="code"> ./alobe
|
||||
-L -i web.data.gz -o result.txt -c 701654 -n 100 -r 24<br>
|
||||
</p>
|
||||
<p class="">Ce qui produit
|
||||
en sortie: </p>
|
||||
<p class="code">0 6.228710<br>
|
||||
1 7.560919<br>
|
||||
2 9.514071<br>
|
||||
3 9.537433<br>
|
||||
4 9.504442<br>
|
||||
5 9.567365<br>
|
||||
6 9.542382<br>
|
||||
7 9.429151<br>
|
||||
8 9.426282<br>
|
||||
9 9.566440<br>
|
||||
10 9.583777<br>
|
||||
11 9.450484<br>
|
||||
12 9.548250<br>
|
||||
13 9.503499<br>
|
||||
14 9.508191<br>
|
||||
15 9.475249<br>
|
||||
16 9.297400<br>
|
||||
17 9.210398<br>
|
||||
[...]</p>
|
||||
<p>Soit sous forme graphique
|
||||
:<br>
|
||||
<img src="exercice3.png" alt="exo 3 plot"></p>
|
||||
<br>
|
||||
<h4>5.2.4. Exercice 4</h4>
|
||||
<p>Pour calculer la borne
|
||||
inférieure, on fera:</p>
|
||||
<p class="code">./alobe -M
|
||||
-i web.data.gz -o result.txt -c 701654 -n 5 -r 24</p>
|
||||
<p class="code">Iteration 0
|
||||
-- choosing root 24<br>
|
||||
|
||||
-- borne inférieure 17<br>
|
||||
Iteration 1 -- choosing root 60401<br>
|
||||
|
||||
-- borne inférieure 18<br>
|
||||
Iteration 2 -- choosing root 700018<br>
|
||||
|
||||
-- borne inférieure 24<br>
|
||||
Iteration 3 -- choosing root 77852<br>
|
||||
|
||||
-- borne inférieure 24<br>
|
||||
Iteration 4 -- choosing root 45944<br>
|
||||
|
||||
-- borne inférieure 24<br>
|
||||
</p>
|
||||
<br>
|
||||
<h4>5.2.5. Exercice 5</h4>
|
||||
<p>Pour le calcul de la borne
|
||||
supérieure, on fait :</p>
|
||||
<p class="code">./alobe -N
|
||||
-i ~/web.data.gz -o result.txt -c 701654 -n 10 -r 24</p>
|
||||
<p class="code">Iteration 0
|
||||
-- choosing root 24<br>
|
||||
|
||||
-- borne supérieure 33<br>
|
||||
Iteration 1 -- choosing root 96542<br>
|
||||
|
||||
-- borne supérieure 33<br>
|
||||
Iteration 2 -- choosing root 49208<br>
|
||||
|
||||
-- borne supérieure 33<br>
|
||||
Iteration 3 -- choosing root 436498<br>
|
||||
|
||||
-- borne supérieure 33<br>
|
||||
Iteration 4 -- choosing root 309990<br>
|
||||
|
||||
-- borne supérieure 32<br>
|
||||
Iteration 5 -- choosing root 538890<br>
|
||||
|
||||
-- borne supérieure 32<br>
|
||||
Iteration 6 -- choosing root 266656<br>
|
||||
|
||||
-- borne supérieure 32<br>
|
||||
Iteration 7 -- choosing root 529998<br>
|
||||
|
||||
-- borne supérieure 32<br>
|
||||
Iteration 8 -- choosing root 140145<br>
|
||||
|
||||
-- borne supérieure 32<br>
|
||||
Iteration 9 -- choosing root 640316<br>
|
||||
|
||||
-- borne supérieure 32<br>
|
||||
<br>
|
||||
</p>
|
||||
<h4>5.2.6. Exercice 6 - Défi</h4>
|
||||
<p>Le cumul des courbes
|
||||
précédentes se fait par :</p>
|
||||
<p class="code">$ ./alobe
|
||||
-O -i web.data.gz -o result.txt -c 701654 -n 100 -r 24</p>
|
||||
<p>Puis :</p>
|
||||
<p class="code">$
|
||||
./defiplot.sh result.txt</p>
|
||||
<p class="">Pour obtenir :
|
||||
<img src="defi.png" alt="defi plot"></p>
|
||||
<p class="">Remarque:
|
||||
pour le défi, il aurait fallu en plus utiliser une
|
||||
heuristique de choix des noeuds permettant de faire converger les deux
|
||||
courbes bornant le diamètre au plus vite. Par exemple,
|
||||
choisir les noeuds par degré décroissant dans la
|
||||
composante connexe, en supposant qu'un noeud a fort degré
|
||||
comme racine donne un arbre plus plat et donc la borne
|
||||
suppérieure par la même occasion...</p>
|
||||
<br>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,84 @@
|
|||
#AM_YFLAGS = -d -v
|
||||
|
||||
SUBDIRS = .
|
||||
|
||||
bin_PROGRAMS = alobe testfifo testlist
|
||||
|
||||
testfifo_SOURCES = \
|
||||
fifo.c \
|
||||
testfifo.c
|
||||
|
||||
testfifo_SOURCES += \
|
||||
fifo.h \
|
||||
units.h
|
||||
|
||||
testlist_SOURCES = \
|
||||
list.c \
|
||||
testlist.c
|
||||
|
||||
testlist_SOURCES += \
|
||||
list.h \
|
||||
units.h
|
||||
|
||||
alobe_SOURCES = \
|
||||
alobe.c \
|
||||
config.c \
|
||||
connexcomponent.c \
|
||||
console.c \
|
||||
defi.c \
|
||||
degree.c \
|
||||
degenerator.c \
|
||||
distance.c \
|
||||
fifo.c \
|
||||
filter.c \
|
||||
generator.c \
|
||||
list.c \
|
||||
nodeset.c \
|
||||
progressindicator.c \
|
||||
store.c
|
||||
|
||||
alobe_SOURCES += \
|
||||
alobe.h \
|
||||
config.h \
|
||||
connexcomponent.h \
|
||||
console.h \
|
||||
degree.h \
|
||||
defi.h \
|
||||
degenerator.h \
|
||||
distance.h \
|
||||
fifo.h
|
||||
filter.h \
|
||||
generator.h \
|
||||
list.h \
|
||||
nodeset.h \
|
||||
progressindicator.h \
|
||||
store.h \
|
||||
units.h
|
||||
|
||||
EXTRA_DIST = mini.0.20 mini.0.60
|
||||
|
||||
INCLUDES= -I../lib/ -I./ -I/usr/include
|
||||
|
||||
#BUILT_SOURCES = source_parser.h source_lexer.cc
|
||||
|
||||
|
||||
# LEXLIB@
|
||||
# libyalag.la
|
||||
# miniftpc_INCLUDE = a
|
||||
|
||||
#rapemode_LDADD =
|
||||
#ytem_LDFLAGS = -L../lib -L../lib/.libs @LDFLAGS@
|
||||
|
||||
#iytem_LDADD = \
|
||||
# ${top_builddir}/src/lib/ytemgrapher/libytemgrapher.la \
|
||||
# ${top_builddir}/src/lib/ytempert/libytempert.la
|
||||
|
||||
# -pg -> profiling
|
||||
# -mcpu=G4 -maltivec
|
||||
#AM_CXXFLAGS = -mcpu=G4 -maltivec
|
||||
#-fprofile-generate -fprofile-use
|
||||
#AM_CFLAGS = -mcpu=G4 -maltivec
|
||||
#-fprofile-generate -fprofile-use
|
||||
|
||||
alobe_LDFLAGS = @LDFLAGS@ -lz
|
||||
|
|
@ -0,0 +1,279 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
#include <time.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "filter.h"
|
||||
#include "degree.h"
|
||||
#include "store.h"
|
||||
#include "defi.h"
|
||||
#include "distance.h"
|
||||
#include "generator.h"
|
||||
#include "degenerator.h"
|
||||
|
||||
#include "units.h"
|
||||
|
||||
#define DEBUG 1
|
||||
|
||||
int main(int argc, char ** argv){
|
||||
srand(time(NULL));
|
||||
|
||||
Config_t * config = config_create (argc, argv);
|
||||
if (!config_is_valid (config)) { config_usage (config); exit(-1); }
|
||||
pDEBUG("Got config from command line\n");
|
||||
|
||||
config_set (config);
|
||||
pDEBUG("Config set\n");
|
||||
|
||||
// en fonction de la commande
|
||||
switch (config->command){
|
||||
case COMMAND_TP1_FILTER_EX2:
|
||||
{
|
||||
Filter_t * filter = filter_create(&(config->io),
|
||||
config->filter_size,
|
||||
config->filter_offset);
|
||||
filter_run (filter);
|
||||
filter_destroy (filter);
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMAND_TP1_DEGREE_EX3:
|
||||
{
|
||||
Degree_t * degree = degree_create (&(config->io),
|
||||
config->nodecount,
|
||||
MODE_DEGREE);
|
||||
degree_set_output (degree, true);
|
||||
degree_fill_from_input_graph (degree);
|
||||
degree_destroy (degree);
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMAND_TP1_STORE_GRAPH_EX4:
|
||||
{
|
||||
Store_t * store = store_create(&(config->io),
|
||||
config->nodecount);
|
||||
store_fill_from_input_graph (store);
|
||||
store_destroy (store);
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMAND_TP1_DENSITY_AVGDEGREE_MAXDEGREE_EX5:
|
||||
{
|
||||
Degree_t * degree = degree_create (&(config->io),
|
||||
config->nodecount,
|
||||
MODE_DEGSTATS);
|
||||
degree_set_output (degree, true);
|
||||
degree_fill_from_input_graph (degree);
|
||||
degree_destroy (degree);
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMAND_TP1_CONNEXITY_EX6:
|
||||
{
|
||||
Store_t * store = store_create(&(config->io),
|
||||
config->nodecount);
|
||||
store_fill_from_input_graph (store);
|
||||
store_connexity (store, NULL);
|
||||
store_destroy (store);
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMAND_TP1_CONNEXITY_DEFI:
|
||||
{
|
||||
Defi_t * defi = defi_create(&(config->io),
|
||||
config->nodecount);
|
||||
defi_run (defi);
|
||||
defi_destroy (defi);
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMAND_TP2_DISTANCE_ONE_TO_OTHER_EX1:
|
||||
{
|
||||
fprintf(stderr,"Exercice 1 - Ecrire un programme qui, étant donné un\n");
|
||||
fprintf(stderr," graphe et un de ses noeud, calcule la distance de ce\n");
|
||||
fprintf(stderr," noeud a tous les autres, ainsi que la moyenne de\n");
|
||||
fprintf(stderr," toutes ces distances.\n\n");
|
||||
|
||||
Distance_t * distance = distance_create((&config->io),
|
||||
config->nodecount);
|
||||
distance_set_mode (distance, MODE_MAX_AND_AVERAGE);
|
||||
|
||||
distance_set_root (distance, config->root_index);
|
||||
distance_set_iterations (distance, 1);
|
||||
|
||||
distance_compute (distance);
|
||||
distance_destroy (distance);
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMAND_TP2_PLOT_DISTRIB_DISTANCES_EX2:
|
||||
{
|
||||
fprintf(stderr,"Exercice 2 - Tracer la distribution des distances à un\n");
|
||||
fprintf(stderr," noeud donné, c'est à dire pour chaque entier i le nom-\n");
|
||||
fprintf(stderr," bre de noeuds à distance i du noeud donné.\n\n");
|
||||
|
||||
Distance_t * distance = distance_create((&config->io),
|
||||
config->nodecount);
|
||||
distance_set_mode (distance, MODE_MAX_DISTRIBUTION);
|
||||
|
||||
distance_set_root (distance, config->root_index);
|
||||
distance_set_iterations (distance, 1);
|
||||
|
||||
distance_compute (distance);
|
||||
distance_destroy (distance);
|
||||
}
|
||||
break;
|
||||
case COMMAND_TP2_EVOL_OF_DISTS_FNC_NB_PARCOURS_EX3:
|
||||
{
|
||||
fprintf(stderr, "Exercice 3 - Ecrire un programme qui permet de tracer\n");
|
||||
fprintf(stderr, " l'évolution de l'estimation de la distance moyenne en\n");
|
||||
fprintf(stderr, " fonction du nombre de parcours effectués.\n");
|
||||
fprintf(stderr, "A chaque étape, le programme calcule la distance moyenne\n");
|
||||
fprintf(stderr, " d'un noeud à tous les autres, puis fait la moyenne avec\n");
|
||||
fprintf(stderr, " toutes les valeurs précédentes.\n\n");
|
||||
|
||||
Distance_t * distance = distance_create((&config->io),
|
||||
config->nodecount);
|
||||
distance_set_mode (distance, MODE_EVOLUTION);
|
||||
|
||||
distance_set_root (distance, config->root_index);
|
||||
distance_set_iterations (distance, config->iterations);
|
||||
|
||||
distance_compute (distance);
|
||||
distance_destroy (distance);
|
||||
}
|
||||
break;
|
||||
case COMMAND_TP2_LIMIT_INFERIOR_EX4:
|
||||
{
|
||||
fprintf(stderr, "Exercice 4 - Ecrire un programme qui calcule une borne\n");
|
||||
fprintf(stderr, " inférieure du diamètre, en prenant la distance maximale\n");
|
||||
fprintf(stderr, " d'un noeud donné à tous les autres.\n\n");
|
||||
|
||||
Distance_t * distance = distance_create((&config->io),
|
||||
config->nodecount);
|
||||
distance_set_mode (distance, MODE_SHOW_LIMIT_INF);
|
||||
|
||||
distance_set_root (distance, config->root_index);
|
||||
distance_set_iterations (distance, config->iterations);
|
||||
|
||||
distance_compute (distance);
|
||||
distance_destroy (distance);
|
||||
}
|
||||
break;
|
||||
case COMMAND_TP2_LIMIT_SUPERIOR_EX5:
|
||||
{
|
||||
fprintf(stderr, "Exercice 5 - Ecrire un programme qui calcule une borne\n");
|
||||
fprintf(stderr, " supérieure du diamètre, en prenant la distance maximale\n");
|
||||
fprintf(stderr, " dans l'arbre du parcours en largeur.\n\n");
|
||||
|
||||
Distance_t * distance = distance_create((&config->io),
|
||||
config->nodecount);
|
||||
distance_set_mode (distance, MODE_SHOW_LIMIT_SUP);
|
||||
|
||||
distance_set_root (distance, config->root_index);
|
||||
distance_set_iterations (distance, config->iterations);
|
||||
|
||||
distance_compute (distance);
|
||||
distance_destroy (distance);
|
||||
}
|
||||
break;
|
||||
case COMMAND_TP2_EVOLUTION_AND_LIMITS_DEFI:
|
||||
{
|
||||
fprintf(stderr, "Défi - Ecrire un programme qui donne un encadrement de\n");
|
||||
fprintf(stderr, " plus en plus fin du diamètre d'un graphe. Le programme\n");
|
||||
fprintf(stderr, " effectue à chaque étape un parcours en largeur et en\n");
|
||||
fprintf(stderr, " déduit une borne inférieure et une borne supérieure pour\n");
|
||||
fprintf(stderr, " le diamètre. Si elle améliorent le résultat elle sont\n");
|
||||
fprintf(stderr, " conservées à la place des meilleures valeurs trouvées\n");
|
||||
fprintf(stderr, " lors des étapes précédentes.\n\n");
|
||||
|
||||
Distance_t * distance = distance_create((&config->io),
|
||||
config->nodecount);
|
||||
distance_set_mode (distance, MODE_DEFI);
|
||||
|
||||
distance_set_root (distance, config->root_index);
|
||||
distance_set_iterations (distance, config->iterations);
|
||||
|
||||
distance_compute (distance);
|
||||
distance_destroy (distance);
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMAND_TP3_DISTRIB_DEG_EX1:
|
||||
{
|
||||
fprintf(stderr, "Exercice 1 - Ecrire un programme qui calcule la distribu-\n");
|
||||
fprintf(stderr, " tion des degrés d'un graphe.\n");
|
||||
|
||||
Degree_t * degree = degree_create (&(config->io),
|
||||
config->nodecount,
|
||||
MODE_DEGREE);
|
||||
degree_set_output (degree, false);
|
||||
degree_fill_from_input_graph (degree);
|
||||
|
||||
degree_output_distribution (degree);
|
||||
degree_destroy (degree);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMAND_TP3_EVOL_AVG_DEG_EX2:
|
||||
{
|
||||
Store_t * store = store_create(&(config->io),
|
||||
config->nodecount);
|
||||
store_fill_from_input_graph (store);
|
||||
|
||||
store_compute_avg_degree(store, config->iterations);
|
||||
|
||||
store_destroy (store);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMAND_TP3_GENERATE_EX3:
|
||||
{
|
||||
|
||||
fprintf(stderr, "Generating a random graph\n");
|
||||
|
||||
Generator_t * generator = generator_create(&(config->io),
|
||||
config->nodecount,
|
||||
config->filter_size);
|
||||
|
||||
generator_run (generator);
|
||||
generator_destroy (generator);
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMAND_TP3_DEGENERATE_EX5:
|
||||
{
|
||||
fprintf(stderr, "Degenerating input graph\n");
|
||||
Degenerator_t * degen = degenerator_create (&(config->io),
|
||||
config->nodecount, config->iterations);
|
||||
degenerator_set_select_mode (degen, DEGENERATOR_SELECT_RANDOM);
|
||||
|
||||
degenerator_compute (degen);
|
||||
degenerator_destroy (degen);
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMAND_TP3_DEGENERATE_MAX_DEG_EX7:
|
||||
{
|
||||
fprintf(stderr, "Degenerating input graph with max degrees first\n");
|
||||
Degenerator_t * degen = degenerator_create (&(config->io),
|
||||
config->nodecount, config->iterations);
|
||||
degenerator_set_select_mode (degen, DEGENERATOR_SELECT_MAX_DEG);
|
||||
|
||||
degenerator_compute (degen);
|
||||
degenerator_destroy (degen);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
printf("Undefined mode\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
config_destroy (config);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
0 1
|
||||
0 2
|
||||
1 3
|
||||
1 7
|
||||
2 3
|
||||
2 4
|
||||
2 5
|
||||
3 5
|
||||
3 6
|
||||
3 7
|
||||
3 8
|
||||
5 7
|
||||
6 7
|
|
@ -0,0 +1,10 @@
|
|||
0 1
|
||||
0 2
|
||||
1 3
|
||||
1 4
|
||||
3 5
|
||||
4 6
|
||||
5 7
|
||||
5 8
|
||||
6 9
|
||||
9 10
|
|
@ -0,0 +1,12 @@
|
|||
0 1
|
||||
0 2
|
||||
1 3
|
||||
1 7
|
||||
2 3
|
||||
2 4
|
||||
2 5
|
||||
3 5
|
||||
3 7
|
||||
3 8
|
||||
5 7
|
||||
6 7
|
|
@ -0,0 +1,345 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
|
||||
#define DEBUG 1
|
||||
|
||||
/**************************************************************************
|
||||
* Constructeur
|
||||
*
|
||||
* @param argc Nombre de parametres
|
||||
* @param argv Tableau vers les chaines de caracteres contenant les
|
||||
* parametres
|
||||
*/
|
||||
|
||||
Config_t * config_create(int argc, char **argv) {
|
||||
Config_t * config = (Config_t*)malloc(sizeof(Config_t));
|
||||
|
||||
config->command = COMMAND_UNDEF;
|
||||
config->filter_size = -1;
|
||||
config->root_index = NODEINDEX_RANDOM;
|
||||
config->filter_offset = -1;
|
||||
config->_inputfile = strdup("-");
|
||||
config->_outputfile = strdup("-");
|
||||
config->nodecount = -1;
|
||||
config->io.verbose = false;
|
||||
|
||||
while (1) {
|
||||
static struct option long_options[] = {
|
||||
//{"compress1", no_argument, 0, 'c'},
|
||||
|
||||
/* TP1 */
|
||||
{"tp1filter", no_argument, 0, 'F'},
|
||||
{"tp1degree", no_argument, 0, 'D'},
|
||||
{"tp1store", no_argument, 0, 'S'},
|
||||
{"tp1average", no_argument, 0, 'A'},
|
||||
{"tp1connexity", no_argument, 0, 'C'},
|
||||
{"tp1defi", no_argument, 0, 'E'},
|
||||
|
||||
/* TP2 */
|
||||
{"tp2distance", no_argument, 0, 'I'},
|
||||
{"tp2distanceplot", no_argument, 0, 'J'},
|
||||
{"tp2distevolution", no_argument, 0, 'L'},
|
||||
{"tp2limitinf", no_argument, 0, 'M'},
|
||||
{"tp2limitsup", no_argument, 0, 'N'},
|
||||
{"tp2defi", no_argument, 0, 'O'},
|
||||
|
||||
/* TP3 */
|
||||
{"tp3distribdeg", no_argument, 0, 'H'},
|
||||
{"tp3evolavgdeg", no_argument, 0, 'K'},
|
||||
{"tp3generate", no_argument, 0, 'G'},
|
||||
{"tp3degenerate", no_argument, 0, 'B'},
|
||||
{"tp3degenmaxdeg", no_argument, 0, 'P'},
|
||||
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
|
||||
{"input", required_argument, 0, 'i'},
|
||||
{"count", required_argument, 0, 'c'},
|
||||
{"output", required_argument, 0, 'o'},
|
||||
{"iterations", required_argument, 0, 'n'},
|
||||
|
||||
{"root", required_argument, 0, 'r'},
|
||||
{"size", required_argument, 0, 's'},
|
||||
{"offset", required_argument, 0, 't'},
|
||||
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
int option_index = 0;
|
||||
|
||||
int c = getopt_long(argc, argv, "vABCDEFGHIJKLMNOPSc:i:o:s:t:r:n:",
|
||||
long_options, &option_index);
|
||||
|
||||
/* detect the end of options */
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case 0:
|
||||
pDEBUG("case NULL\n");
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
pDEBUG("Parameter -> Root index = %s\n",optarg);
|
||||
if (strcmp(optarg,"rand") == 0){
|
||||
config->root_index = NODEINDEX_RANDOM;
|
||||
} else if (strcmp(optarg,"max") == 0){
|
||||
config->root_index = NODEINDEX_MAX_CC;
|
||||
} else {
|
||||
sscanf(optarg, "%ld", &(config->root_index));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
pDEBUG("Parameter -> Iterations = %s\n",optarg);
|
||||
sscanf(optarg, "%d", &(config->iterations));
|
||||
break;
|
||||
|
||||
case 't':
|
||||
pDEBUG("Parameter -> Filter offset = %s\n",optarg);
|
||||
sscanf(optarg, "%ld", &(config->filter_offset));
|
||||
break;
|
||||
|
||||
case 's':
|
||||
pDEBUG("Parameter -> Edge count = %s\n",optarg);
|
||||
sscanf(optarg, "%ld", &(config->filter_size));
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
pDEBUG("Parameter -> Output file = %s\n",optarg);
|
||||
free(config->_outputfile);
|
||||
config->_outputfile = strdup(optarg);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
pDEBUG("Parameter -> Input file -> %s\n",optarg);
|
||||
free(config->_inputfile);
|
||||
config->_inputfile = strdup(optarg);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
pDEBUG("Parameter -> Node count -> %s\n",optarg);
|
||||
sscanf(optarg, "%d", &(config->nodecount));
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
pDEBUG("Command -> TP1 AVERAGE\n");
|
||||
config->command = COMMAND_TP1_DENSITY_AVGDEGREE_MAXDEGREE_EX5;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
pDEBUG("Command -> TP3 DEGENERATE\n");
|
||||
config->command = COMMAND_TP3_DEGENERATE_EX5;
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
pDEBUG("Command -> TP1 CONNEXITY\n");
|
||||
config->command = COMMAND_TP1_CONNEXITY_EX6;
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
pDEBUG("Command -> TP1 DEGREE\n");
|
||||
config->command = COMMAND_TP1_DEGREE_EX3;
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
pDEBUG("Command -> TP1 DEFI\n");
|
||||
config->command = COMMAND_TP1_CONNEXITY_DEFI;
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
pDEBUG("Command -> TP1 FILTER\n");
|
||||
config->command = COMMAND_TP1_FILTER_EX2;
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
pDEBUG("Command -> TP3 GENERATE\n");
|
||||
config->command = COMMAND_TP3_GENERATE_EX3;
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
pDEBUG("Command -> TP3 DISTRIB DEGREEE\n");
|
||||
config->command = COMMAND_TP3_DISTRIB_DEG_EX1;
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
pDEBUG("Command -> TP2 DISTANCE\n");
|
||||
config->command = COMMAND_TP2_DISTANCE_ONE_TO_OTHER_EX1;
|
||||
break;
|
||||
|
||||
case 'J':
|
||||
pDEBUG("Command -> TP2 PLOT DISTRIB DIST\n");
|
||||
config->command = COMMAND_TP2_PLOT_DISTRIB_DISTANCES_EX2;
|
||||
break;
|
||||
|
||||
case 'K':
|
||||
pDEBUG("Command -> TP3 EVOL AVG DEGREEE\n");
|
||||
config->command = COMMAND_TP3_EVOL_AVG_DEG_EX2;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
pDEBUG("Command -> TP2 DISTANCES EVOLUTION OF DISTS / ITERATIONS\n");
|
||||
config->command = COMMAND_TP2_EVOL_OF_DISTS_FNC_NB_PARCOURS_EX3;
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
pDEBUG("Command -> TP2 DISTANCES LIMIT INFERIOR\n");
|
||||
config->command = COMMAND_TP2_LIMIT_INFERIOR_EX4;
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
pDEBUG("Command -> TP2 DISTANCES LIMIT SUPERIOR\n");
|
||||
config->command = COMMAND_TP2_LIMIT_SUPERIOR_EX5;
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
pDEBUG("Command -> TP2 DISTANCES EVOLUTION AND LIMITS DEFI\n");
|
||||
config->command = COMMAND_TP2_EVOLUTION_AND_LIMITS_DEFI;
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
pDEBUG("Command -> TP3 DEGENERATE MAX DEG FIRST\n");
|
||||
config->command = COMMAND_TP3_DEGENERATE_MAX_DEG_EX7;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
pDEBUG("Command -> TP1 STOREGRAPH\n");
|
||||
config->command = COMMAND_TP1_STORE_GRAPH_EX4;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
pDEBUG("Option -> Verbose mode\n");
|
||||
config->io.verbose = true;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
pDEBUG("Unknow option -> '?'\n");
|
||||
exit(-1);
|
||||
break;
|
||||
|
||||
default:
|
||||
pDEBUG("Unknow option -> Default \n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Organise les fichiers d'entrée/sortie dans l'objet Config_t.
|
||||
*
|
||||
* ATTENTION: Etape obligatoire apres la création du Config_t.
|
||||
*
|
||||
* @param config Pointeur sur l'objet Config_t
|
||||
*/
|
||||
|
||||
void config_set(Config_t * config){
|
||||
// on utilise STDIN si le parametre est "-" et un fichier d'entrée (gz?) sinon
|
||||
if (0 == strcmp (config->_inputfile, "-")) {
|
||||
config->io.input = gzdopen (fileno (stdin), "rb");
|
||||
} else {
|
||||
config->io.input = gzopen (config->_inputfile, "rb");
|
||||
}
|
||||
if (config->io.input == NULL) {
|
||||
fprintf (stderr, "%s at %s:%d -- Err: can't gzopen %s\n",
|
||||
__func__, __FILE__, __LINE__, config->_inputfile);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
// on utilise STDOUT si le parametre est "-" est un fichier de sortie sinon
|
||||
if (0 == strcmp(config->_outputfile, "-")){
|
||||
config->io.output = stdout;
|
||||
} else {
|
||||
config->io.output = fopen(config->_outputfile, "wb");
|
||||
}
|
||||
if (config->io.output == NULL){
|
||||
perror(config->_outputfile);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Destructeur
|
||||
*/
|
||||
|
||||
void config_destroy(Config_t * config){
|
||||
gzclose(config->io.input);
|
||||
fclose(config->io.output);
|
||||
|
||||
free(config->_inputfile);
|
||||
free(config->_outputfile);
|
||||
free(config);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Vérifie la validité des options de configuration
|
||||
*/
|
||||
|
||||
bool config_is_valid(Config_t * config) {
|
||||
int score = 0;
|
||||
int valid = 0;
|
||||
|
||||
if (strlen(config->_inputfile) > 0) {
|
||||
score++;
|
||||
}
|
||||
valid++;
|
||||
|
||||
if (config->nodecount > 0) {
|
||||
score++;
|
||||
}
|
||||
valid++;
|
||||
|
||||
if (strlen(config->_outputfile) > 0) {
|
||||
score++;
|
||||
}
|
||||
valid++;
|
||||
|
||||
return (valid == score);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Affiche sur la sortie standard les paramètres acceptés
|
||||
*/
|
||||
|
||||
void config_usage(Config_t * config) {
|
||||
printf("Usage: alobe [options]\n");
|
||||
printf("\n");
|
||||
printf("Mandatory options:\n");
|
||||
printf("-i, -input-data <string> Input filename\n");
|
||||
printf("-c, -input-count <string> Node count\n");
|
||||
printf("-o, -output <string> Input filename\n");
|
||||
printf("-n, -iterations <int> Number of iterations\n");
|
||||
printf("-t, -offset <int> Filter offset\n");
|
||||
printf("-s, -size <int> Edge count\n");
|
||||
printf("-r, -root <value> Root node. Value in : <integer> | 'max' | 'rand' (default 'rand')\n");
|
||||
printf("\n");
|
||||
printf("-F, -tp1filter Cmd: TP1 Filter\n");
|
||||
printf("-D, -tp1degree Cmd: TP1 Compute degree\n");
|
||||
printf("-S, -tp1store Cmd: TP1 Fill the store\n");
|
||||
printf("-A, -tp1average Cmd: TP1 Compute the average degree\n");
|
||||
printf("-C, -tp1connexity Cmd: TP1 Find connex components\n");
|
||||
printf("-E, -tp1defi Cmd: TP1 Find connex components (defi mode)\n");
|
||||
printf("\n");
|
||||
printf("-I, -tp2distance Cmd: TP2 Compute the distances for one node\n");
|
||||
printf("-J, -tp2distanceplot Cmd: TP2 Plot the distances for one node\n");
|
||||
printf("-L, -tp2distevolution Cmd: TP2 Plot evolution of average dist\n");
|
||||
printf("-M, -tp2limitinf Cmd: TP2 Borne inf\n");
|
||||
printf("-N, -tp2limitsup Cmd: TP2 Borne sup\n");
|
||||
printf("-O, -tp2defi Cmd: TP2 Defi\n");
|
||||
printf("\n");
|
||||
printf("-H, -tp3distribdeg Cmd: TP3 Plot the distribution of degrees\n");
|
||||
printf("-K, -tp3evolavgdeg Cmd: TP3 Evolution of average degree\n");
|
||||
printf("-G, -tp3generate Cmd: TP3 Generate a random graph\n");
|
||||
printf("-B, -tp3degenerate Cmd: TP3 Degenerate input graph (random)\n");
|
||||
printf("-P, -tp3degenmaxdeg Cmd: TP3 Degenerate input graph (max degree first)\n");
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#ifndef _GYR_CONFIG_H
|
||||
#define _GYR_CONFIG_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "units.h"
|
||||
|
||||
typedef enum {
|
||||
COMMAND_UNDEF,
|
||||
COMMAND_TP1_FILTER_EX2,
|
||||
COMMAND_TP1_DEGREE_EX3,
|
||||
COMMAND_TP1_STORE_GRAPH_EX4,
|
||||
COMMAND_TP1_DENSITY_AVGDEGREE_MAXDEGREE_EX5,
|
||||
COMMAND_TP1_CONNEXITY_EX6,
|
||||
COMMAND_TP1_CONNEXITY_DEFI,
|
||||
|
||||
COMMAND_TP2_DISTANCE_ONE_TO_OTHER_EX1,
|
||||
COMMAND_TP2_PLOT_DISTRIB_DISTANCES_EX2,
|
||||
COMMAND_TP2_EVOL_OF_DISTS_FNC_NB_PARCOURS_EX3,
|
||||
COMMAND_TP2_LIMIT_INFERIOR_EX4,
|
||||
COMMAND_TP2_LIMIT_SUPERIOR_EX5,
|
||||
COMMAND_TP2_EVOLUTION_AND_LIMITS_DEFI,
|
||||
|
||||
COMMAND_TP3_DISTRIB_DEG_EX1,
|
||||
COMMAND_TP3_EVOL_AVG_DEG_EX2,
|
||||
COMMAND_TP3_GENERATE_EX3,
|
||||
COMMAND_TP3_DEGENERATE_EX5,
|
||||
COMMAND_TP3_DEGENERATE_MAX_DEG_EX7
|
||||
} cmd_t;
|
||||
|
||||
typedef struct {
|
||||
gzFile input;
|
||||
FILE * output;
|
||||
bool verbose;
|
||||
} Config_io_t;
|
||||
|
||||
typedef struct {
|
||||
char * _inputfile;
|
||||
char * _outputfile;
|
||||
|
||||
Config_io_t io;
|
||||
int nodecount;
|
||||
int iterations;
|
||||
nodeindex_t root_index;
|
||||
nodeindex_t filter_size;
|
||||
nodeindex_t filter_offset;
|
||||
cmd_t command;
|
||||
} Config_t;
|
||||
|
||||
void config_set(Config_t * config);
|
||||
|
||||
Config_t * config_create(int argc, char **argv);
|
||||
bool config_is_valid(Config_t * config);
|
||||
void config_usage(Config_t * config);
|
||||
void config_destroy(Config_t * config);
|
||||
|
||||
#endif // _GYR_CONFIG_H
|
|
@ -0,0 +1,91 @@
|
|||
/* src/config.h.in. Generated from configure.in by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <algorithm> header file. */
|
||||
#undef HAVE_ALGORITHM
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the <exception> header file. */
|
||||
#undef HAVE_EXCEPTION
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <iostream> header file. */
|
||||
#undef HAVE_IOSTREAM
|
||||
|
||||
/* Define to 1 if you have the <iterator> header file. */
|
||||
#undef HAVE_ITERATOR
|
||||
|
||||
/* Define to 1 if you have the <list> header file. */
|
||||
#undef HAVE_LIST
|
||||
|
||||
/* Define to 1 if you have the <map> header file. */
|
||||
#undef HAVE_MAP
|
||||
|
||||
/* Define to 1 if you have the <memory> header file. */
|
||||
#undef HAVE_MEMORY
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the <set> header file. */
|
||||
#undef HAVE_SET
|
||||
|
||||
/* Define to 1 if you have the <sstream> header file. */
|
||||
#undef HAVE_SSTREAM
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <string> header file. */
|
||||
#undef HAVE_STRING
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the <utility> header file. */
|
||||
#undef HAVE_UTILITY
|
||||
|
||||
/* Define to 1 if you have the <vector> header file. */
|
||||
#undef HAVE_VECTOR
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
|
@ -0,0 +1,262 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#include "connexcomponent.h"
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* LIST OPERATIONS
|
||||
*
|
||||
*/
|
||||
|
||||
#define DEBUG_APPEND 0
|
||||
#define DEBUG_INSERT 0
|
||||
#define DEBUG (DEBUG_APPEND | DEBUG_INSERT)
|
||||
|
||||
ConnexComponentList_t connexcomponentlist_create(){
|
||||
ConnexComponentList_t result = NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
void connexcomponentlist_destroy(ConnexComponentList_t * list){
|
||||
ConnexComponentItem_t * ptr = *list;
|
||||
if (ptr != NULL){
|
||||
if (ptr->next != NULL){
|
||||
connexcomponentlist_destroy(&(ptr->next));
|
||||
ptr->next = NULL;
|
||||
}
|
||||
connexcomponentitem_destroy(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
ConnexComponentItem_t * connexcomponentlist_find_item_with_node(
|
||||
ConnexComponentList_t list,
|
||||
nodeindex_t nodeidx)
|
||||
{
|
||||
ConnexComponentItem_t * result = NULL;
|
||||
|
||||
ConnexComponentItem_t * curptr = list;
|
||||
while(curptr != NULL){
|
||||
if (connexcomponentitem_contains_node(curptr, nodeidx)){
|
||||
result = curptr;
|
||||
break;
|
||||
}
|
||||
curptr = curptr -> next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ConnexComponentList_t connexcomponentlist_insert_edge(
|
||||
ConnexComponentList_t list,
|
||||
nodeindex_t node_one,
|
||||
nodeindex_t node_two)
|
||||
{
|
||||
bool one_created = false;
|
||||
bool two_created = false;
|
||||
ConnexComponentList_t result = list;
|
||||
|
||||
ConnexComponentItem_t * cci_one =
|
||||
connexcomponentlist_find_item_with_node(list, node_one);
|
||||
if (NULL == cci_one){
|
||||
one_created = true;
|
||||
/* on ajoute le premier noeud de l'edge
|
||||
* dans la liste des composantes connexes
|
||||
*/
|
||||
/* on fait pointer cci_one vers la composante en question */
|
||||
pDEBUG("Node %ld not found in existing component\n", node_one);
|
||||
cci_one = connexcomponentitem_create_from_node(node_one);
|
||||
if (DEBUG_INSERT) {
|
||||
pDEBUG("Created component:\n");
|
||||
connexcomponentitem_display(cci_one);
|
||||
}
|
||||
|
||||
// result = connexcomponentlist_append_component(
|
||||
// result,
|
||||
// cci_one);
|
||||
}
|
||||
|
||||
ConnexComponentItem_t * cci_two =
|
||||
connexcomponentlist_find_item_with_node(list, node_two);
|
||||
if (NULL == cci_two){
|
||||
two_created = true;
|
||||
/* on ajoute le premier noeud de l'edge
|
||||
* dans la liste des composantes connexes
|
||||
*/
|
||||
/* on fait pointer cci_one vers la composante en question */
|
||||
pDEBUG("Node %ld not found in existing component\n", node_two);
|
||||
cci_two = connexcomponentitem_create_from_node(node_two);
|
||||
if (DEBUG_INSERT) {
|
||||
pDEBUG("Created component:\n");
|
||||
connexcomponentitem_display(cci_one); }
|
||||
|
||||
// result = connexcomponentlist_append_component(
|
||||
// result,
|
||||
// cci_two);
|
||||
}
|
||||
|
||||
if (cci_one != cci_two) {
|
||||
ConnexComponentItem_t * cci_merge = connexcomponentitem_create_from_merge(cci_one, cci_two);
|
||||
|
||||
/* on efface les deux précédents */
|
||||
if (!one_created) { result = connexcomponentlist_remove_component(result, cci_one); }
|
||||
if (!two_created) { result = connexcomponentlist_remove_component(result, cci_two); }
|
||||
|
||||
/* on ajoute le nouveau */
|
||||
result = connexcomponentlist_append_component(result, cci_merge);
|
||||
|
||||
if (cci_one) { connexcomponentitem_destroy(cci_one); cci_one = NULL; }
|
||||
if (cci_two) { connexcomponentitem_destroy(cci_two); cci_two = NULL; }
|
||||
} else {
|
||||
/* les deux sont egales */
|
||||
if (cci_one) { connexcomponentitem_destroy(cci_one); cci_one = NULL; }
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ConnexComponentList_t connexcomponentlist_append_component(
|
||||
ConnexComponentList_t list,
|
||||
ConnexComponentItem_t * item
|
||||
)
|
||||
{
|
||||
ConnexComponentList_t head = list;
|
||||
|
||||
if (DEBUG_APPEND) {
|
||||
pDEBUG("PRE-append\n");
|
||||
connexcomponentlist_display(head);
|
||||
}
|
||||
|
||||
item->next = NULL;
|
||||
item->prev = NULL;
|
||||
|
||||
if (head == NULL){
|
||||
head = item;
|
||||
} else {
|
||||
item->next = head;
|
||||
head->prev = item;
|
||||
head = item;
|
||||
}
|
||||
|
||||
if (DEBUG_APPEND){
|
||||
pDEBUG("POST-append\n");
|
||||
connexcomponentlist_display(head);
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
ConnexComponentList_t connexcomponentlist_remove_component(
|
||||
ConnexComponentList_t list,
|
||||
ConnexComponentItem_t * item
|
||||
)
|
||||
{
|
||||
ConnexComponentList_t head = list;
|
||||
ConnexComponentItem_t * previtem = item->prev;
|
||||
ConnexComponentItem_t * nextitem = item->next;
|
||||
|
||||
if (NULL != nextitem) { nextitem->prev = NULL; }
|
||||
if (NULL != previtem){ previtem->next = NULL; }
|
||||
|
||||
if (NULL == previtem){
|
||||
/* si en tete de liste */
|
||||
/* on coupe les liens */
|
||||
/* on re-link la tete */
|
||||
head = nextitem;
|
||||
} else if (NULL == nextitem){
|
||||
/* sinon si en fin de liste */
|
||||
/* on coupe les liens */
|
||||
} else {
|
||||
/* sinon cas normal */
|
||||
previtem->next = NULL;
|
||||
nextitem->prev = NULL;
|
||||
}
|
||||
|
||||
/* on coupe les liens */
|
||||
item->next = NULL;
|
||||
item->prev = NULL;
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
void connexcomponentlist_display(ConnexComponentList_t list)
|
||||
{
|
||||
ConnexComponentItem_t * curptr = list;
|
||||
|
||||
printf("All connex components follow:\n");
|
||||
while (curptr != NULL){
|
||||
connexcomponentitem_display(curptr);
|
||||
curptr = curptr->next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* ITERM OPERATIONS
|
||||
*
|
||||
*/
|
||||
|
||||
ConnexComponentItem_t * connexcomponentitem_create()
|
||||
{
|
||||
ConnexComponentItem_t * result =
|
||||
(ConnexComponentItem_t *) malloc (sizeof(ConnexComponentItem_t));
|
||||
result->list = nodesetlist_create();
|
||||
result->prev = NULL;
|
||||
result->next = NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
ConnexComponentItem_t * connexcomponentitem_create_from_node(
|
||||
nodeindex_t node_idx
|
||||
)
|
||||
{
|
||||
ConnexComponentItem_t * result = connexcomponentitem_create();
|
||||
result->list = nodesetlist_create();
|
||||
result->list = nodesetlist_insert_node(result->list, node_idx);
|
||||
return result;
|
||||
}
|
||||
|
||||
ConnexComponentItem_t * connexcomponentitem_create_from_merge(
|
||||
ConnexComponentItem_t * item_one,
|
||||
ConnexComponentItem_t * item_two
|
||||
)
|
||||
{
|
||||
ConnexComponentItem_t * result = connexcomponentitem_create();
|
||||
|
||||
// copy data from item_one
|
||||
result->list = nodesetlist_merge (result->list, item_one->list);
|
||||
// copy data from item_two
|
||||
result->list = nodesetlist_merge (result->list, item_two->list);
|
||||
|
||||
/*
|
||||
printf("connexcomponentitem_create_from_merge -- MERGING COMPONENT-ITEMS\n");
|
||||
connexcomponentitem_display(item_one);
|
||||
printf("connexcomponentitem_create_from_merge -- AND\n");
|
||||
connexcomponentitem_display(item_two);
|
||||
printf("connexcomponentitem_create_from_merge -- GIVES\n");
|
||||
connexcomponentitem_display(result);
|
||||
*/
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void connexcomponentitem_destroy(ConnexComponentItem_t * item)
|
||||
{
|
||||
nodesetlist_destroy(&(item->list));
|
||||
item->list = NULL;
|
||||
free(item);
|
||||
}
|
||||
|
||||
bool connexcomponentitem_contains_node(
|
||||
ConnexComponentItem_t * item,
|
||||
nodeindex_t node_idx)
|
||||
{
|
||||
return nodesetlist_contains_node (item->list, node_idx);
|
||||
}
|
||||
|
||||
void connexcomponentitem_display(ConnexComponentItem_t * item){
|
||||
nodesetlist_display (item->list);
|
||||
}
|
||||
|
||||
#undef DEBUG_APPEND
|
||||
#undef DEBUG_INSERT
|
||||
#undef DEBUG
|
|
@ -0,0 +1,69 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#ifndef _GYR_CONNEX_COMPONENT_H
|
||||
#define _GYR_CONNEX_COMPONENT_H
|
||||
|
||||
#include "nodeset.h"
|
||||
|
||||
typedef struct _ConnexComponentItem_t ConnexComponentItem_t;
|
||||
typedef struct _ConnexComponentItem_t * ConnexComponentList_t;
|
||||
|
||||
struct _ConnexComponentItem_t {
|
||||
NodeSetList_t list;
|
||||
ConnexComponentItem_t * prev;
|
||||
ConnexComponentItem_t * next;
|
||||
};
|
||||
|
||||
/* List opts */
|
||||
ConnexComponentList_t connexcomponentlist_create();
|
||||
|
||||
void connexcomponentlist_destroy(ConnexComponentList_t * list);
|
||||
|
||||
ConnexComponentItem_t * connexcomponentlist_find_item_with_node(
|
||||
ConnexComponentList_t list,
|
||||
nodeindex_t nodeidx);
|
||||
|
||||
ConnexComponentList_t connexcomponentlist_insert_edge(
|
||||
ConnexComponentList_t list,
|
||||
nodeindex_t node_one,
|
||||
nodeindex_t node_two);
|
||||
|
||||
ConnexComponentList_t connexcomponentlist_append_component(
|
||||
ConnexComponentList_t list,
|
||||
ConnexComponentItem_t * item
|
||||
);
|
||||
|
||||
ConnexComponentList_t connexcomponentlist_remove_component(
|
||||
ConnexComponentList_t list,
|
||||
ConnexComponentItem_t * item
|
||||
);
|
||||
|
||||
void connexcomponentlist_display(ConnexComponentList_t list);
|
||||
|
||||
/* Item opts */
|
||||
|
||||
ConnexComponentItem_t * connexcomponentitem_create();
|
||||
|
||||
ConnexComponentItem_t * connexcomponentitem_create_from_node(
|
||||
nodeindex_t node_idx
|
||||
);
|
||||
|
||||
ConnexComponentItem_t * connexcomponentitem_create_from_merge(
|
||||
ConnexComponentItem_t * item_one,
|
||||
ConnexComponentItem_t * item_two
|
||||
);
|
||||
|
||||
void connexcomponentitem_destroy(ConnexComponentItem_t * item);
|
||||
|
||||
void connexcomponentitem_display(ConnexComponentItem_t * item);
|
||||
|
||||
ConnexComponentList_t connexcomponentitem_insert_edge(
|
||||
ConnexComponentList_t list,
|
||||
nodeindex_t node_one,
|
||||
nodeindex_t node_two);
|
||||
|
||||
bool connexcomponentitem_contains_node(
|
||||
ConnexComponentItem_t * item,
|
||||
nodeindex_t node_idx);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,64 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "console.h"
|
||||
|
||||
#define DEBUG 1
|
||||
|
||||
|
||||
Console_t * console_create(){
|
||||
Console_t * result = (Console_t *) malloc (sizeof(Console_t));
|
||||
result->varlist = list_create();
|
||||
result->cmdlist = list_create();
|
||||
return result;
|
||||
}
|
||||
|
||||
void console_destroy(Console_t * console){
|
||||
// FIXME: on dépop toutes les listes et on détruit tout...
|
||||
free (console);
|
||||
}
|
||||
|
||||
void console_register_variable(Console_t * console,
|
||||
char * varname,
|
||||
char * vardesc,
|
||||
short varnamelen,
|
||||
bool (* varcheckfun) (char *, short))
|
||||
{
|
||||
// vérifier si la variable est enregistrée
|
||||
if (!console_is_registered_variable(console, varname)){
|
||||
// on crée la structure;
|
||||
console_var_t * cell_var =
|
||||
(console_var_t *) malloc (sizeof(console_var_t *));
|
||||
|
||||
// remplir les champs de cell_var;
|
||||
//cell_var->name = strndup(varname, varnamelen);
|
||||
cell_var->namelen = varnamelen;
|
||||
cell_var->checkfun = varcheckfun;
|
||||
cell_var->value = NULL;
|
||||
|
||||
// sinon, on ajoute au début...
|
||||
list_push_back(console->varlist, (void *)cell_var);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool console_is_registered_variable(Console_t * console,
|
||||
char * varname){
|
||||
// FIXME console_is_registered_variable
|
||||
return false;
|
||||
}
|
||||
|
||||
void console_register_command(Console_t * console,
|
||||
char * cmdname,
|
||||
char * cmdparamcount,
|
||||
void * cmdcheckfun,
|
||||
void * cmdrunfun){
|
||||
}
|
||||
|
||||
bool console_is_registered_command(Console_t * console,
|
||||
char * cmdname){
|
||||
// FIXME: console_is_registered_command
|
||||
}
|
||||
|
||||
|
||||
#undef DEBUG
|
|
@ -0,0 +1,54 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#ifndef _CONSOLE_H
|
||||
#define _CONSOLE_H
|
||||
|
||||
#include "units.h"
|
||||
#include "list.h"
|
||||
|
||||
typedef struct {
|
||||
char * name;
|
||||
short namelen;
|
||||
char * value;
|
||||
void * checkfun;
|
||||
} console_var_t;
|
||||
|
||||
typedef struct {
|
||||
char * cmdname;
|
||||
char * cmdparams;
|
||||
void * cmdcheckfun;
|
||||
void * cmdrunfun;
|
||||
} console_cmd_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
List_t * varlist;
|
||||
List_t * cmdlist;
|
||||
} Console_t;
|
||||
|
||||
|
||||
Console_t * console_create();
|
||||
|
||||
void console_destroy(Console_t * console);
|
||||
|
||||
void console_register_variable(Console_t * console,
|
||||
char * varname,
|
||||
char * vardesc,
|
||||
short varnamelen,
|
||||
bool (* varcheckfun) (char *, short));
|
||||
|
||||
bool console_is_registered_variable(Console_t * console,
|
||||
char * varname);
|
||||
|
||||
void console_register_command(Console_t * console,
|
||||
char * cmdname,
|
||||
char * cmdparamcount,
|
||||
void * cmdcheckfun,
|
||||
void (* cmdrunfun)
|
||||
);
|
||||
|
||||
bool console_is_registered_command(Console_t * console,
|
||||
char * cmdname);
|
||||
|
||||
#endif /* _CONSOLE_H */
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#include "defi.h"
|
||||
|
||||
#define DEBUG 1
|
||||
|
||||
Defi_t * defi_create(Config_io_t * io, nodeindex_t size){
|
||||
Defi_t * defi = (Defi_t *) malloc (sizeof(Defi_t));
|
||||
|
||||
defi->_io = io;
|
||||
defi->_size = size;
|
||||
defi->_list = connexcomponentlist_create();
|
||||
return defi;
|
||||
}
|
||||
|
||||
void defi_destroy(Defi_t * defi){
|
||||
free (defi);
|
||||
defi = NULL;
|
||||
}
|
||||
|
||||
void defi_run(Defi_t * defi){
|
||||
printf("Run !!!\n");
|
||||
|
||||
char * buf = (char *) malloc (sizeof(char) * 100);
|
||||
char * buf2;
|
||||
nodeindex_t one, two;
|
||||
int re;
|
||||
|
||||
gzrewind(defi->_io->input);
|
||||
gzclearerr(defi->_io->input);
|
||||
|
||||
printf("Searching connex comFilling the Big Table...\n");
|
||||
for (;;){
|
||||
if (gzeof(defi->_io->input)){ break; }
|
||||
|
||||
buf2 = gzgets(defi->_io->input, buf, 100);
|
||||
if (buf2 == Z_NULL){
|
||||
printf("READ OFF\n");
|
||||
break;
|
||||
} else {
|
||||
re = sscanf(buf, "%ld %ld", &one, &two);
|
||||
pDEBUG("=== DEFI READING %ld %ld ===\n", one, two);
|
||||
defi->_list =
|
||||
connexcomponentlist_insert_edge(defi->_list, one, two);
|
||||
|
||||
if (DEBUG) { connexcomponentlist_display(defi->_list); }
|
||||
}
|
||||
}
|
||||
connexcomponentlist_destroy(&(defi->_list));
|
||||
free(buf);
|
||||
printf("done\n");
|
||||
|
||||
}
|
||||
|
||||
#undef DEBUG
|
|
@ -0,0 +1,36 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#ifndef _GYR_CONNEXITY_H
|
||||
#define _GYR_CONNEXITY_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "units.h"
|
||||
#include "config.h"
|
||||
#include "connexcomponent.h"
|
||||
|
||||
typedef struct {
|
||||
Config_io_t * _io;
|
||||
nodeindex_t _size;
|
||||
ConnexComponentList_t _list;
|
||||
} Defi_t;
|
||||
|
||||
|
||||
/*
|
||||
* nodemetaset * nodeset_list_create()
|
||||
* nodemetaset_insert_set(nodeset *);
|
||||
* nodemetaset_add_edge(nodeindex_t from, nodeindex_t to);
|
||||
*/
|
||||
|
||||
Defi_t * defi_create(Config_io_t * io, nodeindex_t size);
|
||||
|
||||
void defi_destroy(Defi_t * defi);
|
||||
|
||||
void defi_append_edge(nodeindex_t from, nodeindex_t to);
|
||||
|
||||
void defi_run(Defi_t * store);
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,96 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#include <assert.h>
|
||||
#include "degenerator.h"
|
||||
#include "progressindicator.h"
|
||||
#include "store.h"
|
||||
#include "fifo.h"
|
||||
|
||||
#define DEBUG 1
|
||||
|
||||
Degenerator_t * degenerator_create (Config_io_t * io, nodeindex_t n_count, int iterations){
|
||||
Degenerator_t * degenerator = (Degenerator_t *) malloc (sizeof(Degenerator_t));
|
||||
|
||||
degenerator->_io = io;
|
||||
|
||||
degenerator->_store = store_create(io, n_count);
|
||||
store_set_output(degenerator->_store, false);
|
||||
store_fill_from_input_graph (degenerator->_store);
|
||||
|
||||
degenerator->_size = n_count;
|
||||
degenerator->_iterations = iterations;
|
||||
degenerator->_iterations_offset = 10;
|
||||
|
||||
|
||||
degenerator_set_select_mode (degenerator, DEGENERATOR_SELECT_RANDOM);
|
||||
|
||||
printf("create ok\n");
|
||||
return degenerator;
|
||||
}
|
||||
|
||||
void degenerator_set_select_mode (Degenerator_t * degenerator, Degenerator_select_mode_t mode){
|
||||
printf("select %d\n", mode);
|
||||
degenerator->_select_mode = mode;
|
||||
}
|
||||
|
||||
void degenerator_destroy (Degenerator_t * degenerator){
|
||||
store_destroy(degenerator->_store);
|
||||
free(degenerator);
|
||||
}
|
||||
|
||||
nodeindex_t degenerator_select_max_deg (Degenerator_t * degenerator){
|
||||
nodeindex_t deg, max_deg;
|
||||
nodeindex_t cur_node, max_node;
|
||||
|
||||
max_deg = 0;
|
||||
max_node = 0;
|
||||
for (cur_node = 0; cur_node < degenerator->_size; cur_node++){
|
||||
deg = store_get_degree(degenerator->_store, cur_node);
|
||||
if (deg > max_deg){
|
||||
max_deg = deg;
|
||||
max_node = cur_node;
|
||||
}
|
||||
}
|
||||
return max_node;
|
||||
}
|
||||
|
||||
nodeindex_t degenerator_select_random (Degenerator_t * degenerator){
|
||||
// Choisir un noeud de degré > 0
|
||||
bool is_bad;
|
||||
nodeindex_t selected_node;
|
||||
do {
|
||||
is_bad = false;
|
||||
selected_node = random() % degenerator->_size;
|
||||
|
||||
// ne pas virer un noeud déja supprimé...
|
||||
if (store_get_degree(degenerator->_store, selected_node) <= 0) { is_bad = true; }
|
||||
} while (is_bad);
|
||||
return selected_node;
|
||||
}
|
||||
|
||||
void degenerator_compute (Degenerator_t * degenerator){
|
||||
int cur_iter;
|
||||
|
||||
|
||||
pDEBUG("Iterating %d times\n", degenerator->_iterations);
|
||||
for (cur_iter = 0; cur_iter < degenerator->_iterations; cur_iter++){
|
||||
if ((cur_iter % degenerator->_iterations_offset) == 0){
|
||||
// faire des calculs (nombre de composantes connexes)
|
||||
store_reset (degenerator->_store, STORE_RESET_ALL ^ STORE_RESET_DEGREE);
|
||||
|
||||
Fifo_t * fifo_idx = fifo_create(degenerator->_size);
|
||||
store_connexity (degenerator->_store, fifo_idx);
|
||||
|
||||
fprintf(degenerator->_io->output, "%d %ld\n", cur_iter, fifo_get_size (fifo_idx));
|
||||
fifo_destroy(fifo_idx);
|
||||
// afficher la courbe...
|
||||
}
|
||||
// Choisir un noeud selon une certaine méthode...
|
||||
nodeindex_t selected_node = (degenerator_select_mode_table[degenerator->_select_mode])(degenerator);
|
||||
printf("Node %ld\n", selected_node);
|
||||
|
||||
store_del_node(degenerator->_store, selected_node);
|
||||
}
|
||||
}
|
||||
|
||||
#undef DEBUG
|
|
@ -0,0 +1,51 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#ifndef _DEGENERATOR_H
|
||||
#define _DEGENERATOR_H
|
||||
|
||||
#include "config.h"
|
||||
#include "store.h"
|
||||
#include "list.h"
|
||||
|
||||
typedef enum {
|
||||
DEGENERATOR_SELECT_RANDOM = 0,
|
||||
DEGENERATOR_SELECT_MAX_DEG = 1
|
||||
} Degenerator_select_mode_t;
|
||||
|
||||
|
||||
|
||||
typedef struct _Degenerator_t {
|
||||
Config_io_t * _io;
|
||||
|
||||
int _iterations;
|
||||
int _iterations_offset;
|
||||
|
||||
Store_t * _store;
|
||||
|
||||
nodeindex_t _size;
|
||||
|
||||
Degenerator_select_mode_t _select_mode;
|
||||
|
||||
} Degenerator_t ;
|
||||
|
||||
|
||||
typedef nodeindex_t (* Degenerator_select_fun_t)(Degenerator_t * degenerator);
|
||||
|
||||
|
||||
Degenerator_t * degenerator_create (Config_io_t * io, nodeindex_t n_count, int iterations);
|
||||
|
||||
void degenerator_destroy (Degenerator_t * distance);
|
||||
|
||||
|
||||
nodeindex_t degenerator_select_random (Degenerator_t * degenerator);
|
||||
nodeindex_t degenerator_select_max_deg (Degenerator_t * degenerator);
|
||||
|
||||
|
||||
static Degenerator_select_fun_t degenerator_select_mode_table[] = {
|
||||
degenerator_select_random,
|
||||
degenerator_select_max_deg
|
||||
};
|
||||
|
||||
void degenerator_set_select_mode (Degenerator_t * degenerator, Degenerator_select_mode_t mode);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,233 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#include <assert.h>
|
||||
#include "degree.h"
|
||||
|
||||
#define DEBUG 1
|
||||
|
||||
Degree_t * degree_create(Config_io_t * io, nodeindex_t size, Degree_mode_t mode )
|
||||
{
|
||||
nodeindex_t i;
|
||||
|
||||
Degree_t * degree = (Degree_t*) malloc (sizeof (Degree_t));
|
||||
degree->_io = io;
|
||||
degree->_show_output = false;
|
||||
degree->_size = size;
|
||||
degree->_mode = mode;
|
||||
|
||||
degree->arcs = 0;
|
||||
degree->average = 0;
|
||||
degree->maximum = 0;
|
||||
degree->density = 0;
|
||||
|
||||
degree->_maxIdx = 0; /* set to the minimum */
|
||||
degree->_minIdx = size; /* set to the maximum */
|
||||
|
||||
degree->_data = (nodeindex_t*) malloc (sizeof (nodeindex_t) * size);
|
||||
|
||||
for (i = 0; i < size; i++){ degree_set (degree, i, 0); }
|
||||
|
||||
return degree;
|
||||
}
|
||||
|
||||
void degree_destroy(Degree_t * degree){
|
||||
free(degree->_data);
|
||||
free(degree);
|
||||
degree = NULL;
|
||||
}
|
||||
|
||||
void degree_set_output(Degree_t * degree, bool out){
|
||||
degree->_show_output = out;
|
||||
}
|
||||
|
||||
nodeindex_t degree_begin(Degree_t * degree){
|
||||
return degree->_minIdx;
|
||||
}
|
||||
|
||||
nodeindex_t degree_end(Degree_t * degree){
|
||||
return degree->_maxIdx;
|
||||
}
|
||||
|
||||
nodeindex_t degree_size(Degree_t * degree){
|
||||
return (1 + degree->_maxIdx - degree->_minIdx);
|
||||
}
|
||||
|
||||
nodeindex_t degree_get(Degree_t * degree, nodeindex_t nodeidx){
|
||||
return degree->_data[nodeidx];
|
||||
}
|
||||
|
||||
void degree_set(Degree_t * degree, nodeindex_t nodeidx, nodeindex_t value){
|
||||
assert(nodeidx < degree->_size);
|
||||
degree->_data[nodeidx] = value;
|
||||
}
|
||||
|
||||
void degree_fill_from_random(Degree_t * degree, nodeindex_t edge_count){
|
||||
|
||||
if (degree->_size > edge_count){
|
||||
printf("ATTENTION: il y aura des noeuds de degré zéro!\n");
|
||||
} else {
|
||||
nodeindex_t cur;
|
||||
nodeindex_t remaining = edge_count - degree->_size;
|
||||
|
||||
for (cur = 0; cur < degree->_size; cur++){
|
||||
nodeindex_t selected_node;
|
||||
// si le degré est nul, alors on crée un lien
|
||||
// vers un autre noeud (rempli ou non)
|
||||
// (pour qu'aucun des noeuds ne soit seul)
|
||||
if (degree_get (degree, cur) == 0){
|
||||
degree_set(degree, cur, 1);
|
||||
|
||||
selected_node = rand() % degree->_size;
|
||||
nodeindex_t deg = degree_get(degree, selected_node);
|
||||
degree_set(degree, selected_node, deg + 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (cur = 0; cur < remaining; cur++){
|
||||
nodeindex_t src_node;
|
||||
nodeindex_t dst_node;
|
||||
nodeindex_t deg;
|
||||
|
||||
printf("\r%s Selecting degrees... (%d of %d)",
|
||||
progress_indicator(),
|
||||
cur+1,
|
||||
remaining);
|
||||
|
||||
bool is_bad;
|
||||
do {
|
||||
is_bad = false;
|
||||
|
||||
src_node = rand() % degree->_size;
|
||||
dst_node = rand() % degree->_size;
|
||||
if (src_node == dst_node){ is_bad = true; }
|
||||
} while(is_bad);
|
||||
|
||||
deg = degree_get(degree, src_node);
|
||||
degree_set(degree, src_node, deg + 1); //
|
||||
|
||||
deg = degree_get(degree, dst_node);
|
||||
degree_set(degree, dst_node, deg + 1); //
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
degree_display(degree);
|
||||
}
|
||||
|
||||
void degree_display(Degree_t * degree){
|
||||
nodeindex_t cur_node;
|
||||
for (cur_node = 0; cur_node < degree->_size; cur_node++){
|
||||
printf("degree[ %ld ] = %ld\n", cur_node, degree_get (degree, cur_node));
|
||||
}
|
||||
}
|
||||
|
||||
void degree_output_distribution(Degree_t * degree){
|
||||
nodeindex_t max = degree->maximum + 1;
|
||||
nodeindex_t * distrib = (nodeindex_t *) malloc (sizeof(nodeindex_t) * max);
|
||||
|
||||
nodeindex_t cur;
|
||||
for (cur = 0; cur < max; cur++){
|
||||
distrib[cur] = 0;
|
||||
}
|
||||
|
||||
for (cur = 0; cur < degree->_size; cur++){
|
||||
nodeindex_t deg = degree_get(degree, cur);
|
||||
distrib[deg] = distrib[deg] + 1;
|
||||
}
|
||||
for (cur = 0; cur < max; cur++){
|
||||
fprintf(degree->_io->output, "%ld %ld\n", cur, distrib[cur]);
|
||||
}
|
||||
}
|
||||
|
||||
void degree_fill_from_input_graph(Degree_t * degree){
|
||||
|
||||
pDEBUG("Computing degree of each node...\n");
|
||||
|
||||
char * buf = (char*) malloc (sizeof(char) * 100);
|
||||
char * buf2;
|
||||
int rep;
|
||||
nodeindex_t one, two;
|
||||
|
||||
gzseek(degree->_io->input, 0, SEEK_SET);
|
||||
|
||||
for (;;){
|
||||
if (gzeof(degree->_io->input)){ break; }
|
||||
|
||||
buf2 = gzgets(degree->_io->input, buf, 100);
|
||||
if (buf2 == Z_NULL){
|
||||
pDEBUG("READ END\n");
|
||||
break;
|
||||
} else {
|
||||
|
||||
|
||||
rep = sscanf(buf,"%ld %ld",&one,&two);
|
||||
|
||||
if (one < degree->_minIdx) { degree->_minIdx = one; }
|
||||
else if (one > degree->_maxIdx) { degree->_maxIdx = one; }
|
||||
|
||||
if (two < degree->_minIdx) { degree->_minIdx = two; }
|
||||
else if (two > degree->_maxIdx) { degree->_maxIdx = two; }
|
||||
|
||||
nodeindex_t one_deg, two_deg;
|
||||
one_deg = degree_get (degree, one) + 1;
|
||||
two_deg = degree_get (degree, two) + 1;
|
||||
degree_set (degree, one, one_deg);
|
||||
degree_set (degree, two, two_deg);
|
||||
|
||||
/* on fait les STATS tout le temps... */
|
||||
degree->arcs = degree->arcs + 2;
|
||||
if (two_deg > degree->maximum){
|
||||
degree->maximum = two_deg;
|
||||
}
|
||||
if (one_deg > degree->maximum){
|
||||
degree->maximum = one_deg;
|
||||
}
|
||||
|
||||
} /* end else */
|
||||
|
||||
} /* end for */
|
||||
|
||||
|
||||
if (degree->_mode == MODE_DEGSTATS){
|
||||
/* arcs_reel = compute_arcs/ 2;
|
||||
* arcs_possible = density->size * (density->_size - 1) / 2
|
||||
* compute_density = arcs_reel / arcs_possible
|
||||
*/
|
||||
|
||||
degree->density = (degree->arcs /
|
||||
(degree->_size * (degree->_size - 1)));
|
||||
degree->average = (float)degree->arcs / (float)degree->_size;
|
||||
}
|
||||
|
||||
pDEBUG("done\n");
|
||||
|
||||
if (degree->_show_output){
|
||||
// on affiche les résultats
|
||||
if (degree->_mode == MODE_DEGSTATS){
|
||||
// calculs statistiques
|
||||
fprintf (degree->_io->output,
|
||||
"degree_run -- Degree average: %f\n",
|
||||
degree->average);
|
||||
fprintf (degree->_io->output,
|
||||
"degree_run -- Degree maximum: %ld\n",
|
||||
degree->maximum);
|
||||
fprintf (degree->_io->output,
|
||||
"degree_run -- Density : %f\n",
|
||||
degree->density);
|
||||
} else {
|
||||
// degrés bruts
|
||||
nodeindex_t idx;
|
||||
|
||||
for (idx = 0; idx < degree->_size; idx++){
|
||||
fprintf (degree->_io->output,
|
||||
"%ld %ld\n",
|
||||
idx,
|
||||
degree_get (degree, idx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free (buf);
|
||||
return;
|
||||
}
|
||||
|
||||
#undef DEBUG
|
|
@ -0,0 +1,54 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#ifndef _GYR_DEGREE_H
|
||||
#define _GYR_DEGREE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "units.h"
|
||||
#include "config.h"
|
||||
|
||||
typedef enum {
|
||||
MODE_DEGREE,
|
||||
MODE_DEGSTATS
|
||||
} Degree_mode_t;
|
||||
|
||||
typedef struct {
|
||||
Config_io_t * _io;
|
||||
|
||||
bool _show_output;
|
||||
Degree_mode_t _mode;
|
||||
|
||||
nodeindex_t _size;
|
||||
nodeindex_t _minIdx;
|
||||
nodeindex_t _maxIdx;
|
||||
|
||||
nodeindex_t arcs;
|
||||
float average;
|
||||
nodeindex_t maximum;
|
||||
float density;
|
||||
|
||||
nodeindex_t * _data;
|
||||
} Degree_t;
|
||||
|
||||
Degree_t * degree_create(Config_io_t * io, nodeindex_t size, Degree_mode_t mode);
|
||||
void degree_destroy(Degree_t * degree);
|
||||
void degree_display(Degree_t * degree);
|
||||
|
||||
void degree_set_output(Degree_t * degree, bool out);
|
||||
|
||||
void degree_set(Degree_t * degree, nodeindex_t nodeidx, nodeindex_t value);
|
||||
|
||||
nodeindex_t degree_get(Degree_t * degree, nodeindex_t nodeidx);
|
||||
|
||||
nodeindex_t degree_begin(Degree_t * degree);
|
||||
nodeindex_t degree_end(Degree_t * degree);
|
||||
nodeindex_t degree_size(Degree_t * degree);
|
||||
void degree_run(Degree_t * degree);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,560 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#include <assert.h>
|
||||
#include "distance.h"
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
/**************************************************************************
|
||||
* Constructeur
|
||||
*
|
||||
* @return Pointeur sur l'objet Distance_t
|
||||
*/
|
||||
|
||||
Distance_t * distance_create (Config_io_t * io, nodeindex_t size){
|
||||
Distance_t * distance = (Distance_t *) malloc (sizeof(Distance_t));
|
||||
|
||||
distance->_io = io;
|
||||
distance->_size = size;
|
||||
distance->_mode = MODE_UNDEF;
|
||||
distance->_root = NODEINDEX_ROOT;
|
||||
// distance->_fifo = fifo_create(size);
|
||||
distance->_store = store_create (io, size);
|
||||
store_set_output(distance->_store, false);
|
||||
|
||||
store_fill_from_input_graph (distance->_store);
|
||||
return distance;
|
||||
}
|
||||
|
||||
|
||||
void distance_destroy(Distance_t * distance){
|
||||
Store_t * store = distance->_store;
|
||||
store_destroy (store);
|
||||
free(distance);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Fixe le nombre d'itérations pour les calculs de distance
|
||||
*
|
||||
* @param distance Pointeur sur l'objet Distance_t
|
||||
* @param iterations Nombre d'itérations
|
||||
*/
|
||||
|
||||
void distance_set_iterations(Distance_t * distance, int iterations){
|
||||
|
||||
pDEBUG("iterations %d\n", iterations);
|
||||
|
||||
distance->_iterations = iterations;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Fixe la racine pour le calcul des distances
|
||||
*
|
||||
* @param distance Pointeur sur l'objet Distance_t
|
||||
* @param rootidx Index du noeud racine pour le calcul
|
||||
*/
|
||||
|
||||
void distance_set_root(Distance_t * distance, nodeindex_t rootidx){
|
||||
|
||||
pDEBUG("root %ld\n", rootidx);
|
||||
|
||||
distance->_root = rootidx;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Fixe le mode d'affichage lors du calcul
|
||||
*
|
||||
* @param distance Pointeur sur l'objet Distance_t
|
||||
* @param mode Mode selectionné
|
||||
*/
|
||||
|
||||
void distance_set_mode(Distance_t * distance, distance_mode_t mode){
|
||||
pDEBUG("mode %d\n", mode);
|
||||
|
||||
distance->_mode = mode;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Retourne tous les noeuds de la plus grande composante connexe
|
||||
*
|
||||
* ATTENTION: modifie STORE_EXTRA_VALUE
|
||||
*
|
||||
* ATTENTION: modifie STORE_EXTRA_VALUE2
|
||||
*
|
||||
* ATTENTION: modifie STORE_EXTRAPLACEles champs EXTRA des noeuds du distance->_store
|
||||
*
|
||||
* @return Un pointeur sur une Fifo_t contenant les index des noeuds
|
||||
*/
|
||||
|
||||
Fifo_t * distance_get_roots_from_max_cc(Distance_t * distance){
|
||||
pDEBUG("FIXME: NOT IMPLEMENTED\n");
|
||||
#warning "FIXME: NOT IMPLEMENTED"
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Retourne tous les noeuds d'une même composante connexe
|
||||
*
|
||||
* ATTENTION: modifie STORE_EXTRA_VALUE
|
||||
*
|
||||
* ATTENTION: modifie STORE_EXTRA_VALUE2
|
||||
*
|
||||
* ATTENTION: modifie STORE_EXTRAPLACEles champs EXTRA des noeuds du distance->_store
|
||||
*
|
||||
* @return Un pointeur sur une Fifo_t contenant les index des noeuds
|
||||
*/
|
||||
|
||||
Fifo_t * distance_get_roots_from_random_cc(Distance_t * distance){
|
||||
Fifo_t * result;
|
||||
nodeindex_t selected_cc;
|
||||
/* on parcours les composantes connexes */
|
||||
Fifo_t * fifo_cc_list = fifo_create(distance->_size);
|
||||
|
||||
pDEBUG("root not selected, preparing the cc list\n");
|
||||
|
||||
store_connexity (distance->_store, fifo_cc_list);
|
||||
|
||||
/* on choisi une index de composante au hasard*/
|
||||
selected_cc = fifo_get_random (fifo_cc_list);
|
||||
printf("Composantes connexes disponibles : ");
|
||||
fifo_display(fifo_cc_list);
|
||||
|
||||
pDEBUG("selected reference node %ld from the cc list\n", selected_cc);
|
||||
|
||||
fifo_destroy (fifo_cc_list);
|
||||
|
||||
pDEBUG("destroying the cc list\n");
|
||||
pDEBUG("reset of the store\n");
|
||||
|
||||
store_reset (distance->_store, STORE_RESET_ALL ^ STORE_RESET_DEGREE);
|
||||
|
||||
/* on crée un fifo fifo_roots avec les noeuds a parcourir... */
|
||||
result = fifo_create(distance->_size);
|
||||
/* on met tous les noeuds de la composante connexe dans le fifo fifo_roots */
|
||||
store_fill_cc_from_node (distance->_store, selected_cc, result);
|
||||
|
||||
pDEBUG("display the cc of node\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Calcul de la distance
|
||||
*
|
||||
* @param distance Pointeur sur l'objet Distance_t
|
||||
*/
|
||||
|
||||
void distance_compute(Distance_t * distance){
|
||||
|
||||
pDEBUG("begin\n");
|
||||
int cur_iteration;
|
||||
// nodeindex_t root;
|
||||
Fifo_t * fifo_roots = NULL;
|
||||
nodeindex_t limit_inferior = 0;
|
||||
nodeindex_t limit_superior = distance->_size;
|
||||
float average_average_distance = 0;
|
||||
nodeindex_t max_max_distance = 0;
|
||||
|
||||
if (distance->_root < 0){
|
||||
if (distance->_root == NODEINDEX_RANDOM){
|
||||
fifo_roots = distance_get_roots_from_random_cc(distance);
|
||||
} else if (distance->_root == NODEINDEX_MAX_CC) {
|
||||
fifo_roots = distance_get_roots_from_max_cc(distance);
|
||||
} else {
|
||||
pDEBUG("C'est quoi ce choix de noeud ????");
|
||||
exit(4);
|
||||
}
|
||||
} else {
|
||||
store_reset (distance->_store, STORE_RESET_ALL ^ STORE_RESET_DEGREE);
|
||||
fifo_roots = fifo_create(distance->_size);
|
||||
store_fill_cc_from_node(distance->_store, distance->_root, fifo_roots);
|
||||
/* fifo_push (fifo_roots, distance->_root); */
|
||||
}
|
||||
printf("Noeuds utilisables comme racines : ");
|
||||
fifo_display(fifo_roots);
|
||||
|
||||
for (cur_iteration = 0; cur_iteration < distance->_iterations; cur_iteration++){
|
||||
pDEBUG("iteration %d begin \n", cur_iteration);
|
||||
distance_computation_t * computation;
|
||||
|
||||
nodeindex_t root_cc;
|
||||
if (distance->_mode == MODE_DEFI){
|
||||
// FIXME: selection optimisée des noeuds
|
||||
root_cc = fifo_get_random (fifo_roots);
|
||||
} else {
|
||||
if ((distance->_root >= 0) && (cur_iteration == 0)) {
|
||||
pDEBUG("first of roots %ld\n", distance->_root);
|
||||
root_cc = fifo_front (fifo_roots);
|
||||
} else {
|
||||
pDEBUG("random root\n");
|
||||
root_cc = fifo_get_random (fifo_roots);
|
||||
}
|
||||
}
|
||||
printf("Iteration %d -- choosing root %ld\n", cur_iteration, root_cc);
|
||||
|
||||
computation = distance_all_from_one_node (distance, root_cc, cur_iteration);
|
||||
|
||||
pDEBUG("Ordre de visite : ");
|
||||
if (DEBUG) fifo_display(computation->visited_nodes);
|
||||
|
||||
max_max_distance = MAX(max_max_distance, computation->maximum);
|
||||
|
||||
average_average_distance += computation->average;
|
||||
|
||||
float approx_average_distance = (
|
||||
(float)average_average_distance
|
||||
/ (float)(1 + cur_iteration));
|
||||
|
||||
/* on sait que la longueur max peut servir de borne inférieure
|
||||
* on choisit donc la limite inférieure maximale
|
||||
*/
|
||||
|
||||
limit_inferior = MAX(computation->maximum, limit_inferior);
|
||||
|
||||
if ((distance->_mode == MODE_SHOW_LIMIT_SUP)
|
||||
|| (distance->_mode == MODE_DEFI)) {
|
||||
/* tous les noeuds ont été visités, on calcule alors la distance
|
||||
* maximale dans l'arbre (largeur) , et on garde a chaque fois le
|
||||
* minimum */
|
||||
|
||||
nodeindex_t width = distance_width (distance,
|
||||
computation->visited_nodes);
|
||||
|
||||
limit_superior = MIN(limit_superior, width);
|
||||
}
|
||||
|
||||
switch(distance->_mode){
|
||||
case MODE_MAX_AND_AVERAGE:
|
||||
{
|
||||
fprintf (distance->_io->output,
|
||||
"Maximum distance : %ld\n",
|
||||
computation->maximum);
|
||||
fprintf (distance->_io->output,
|
||||
"Average distance : %f\n",
|
||||
computation->average);
|
||||
}
|
||||
break;
|
||||
case MODE_MAX_DISTRIBUTION:
|
||||
{
|
||||
/* affichage déporté dans le calcul des distances */
|
||||
};
|
||||
break;
|
||||
case MODE_EVOLUTION:
|
||||
{
|
||||
fprintf(distance->_io->output, "%d %f\n",
|
||||
cur_iteration,
|
||||
approx_average_distance);
|
||||
}
|
||||
break;
|
||||
case MODE_SHOW_LIMIT_INF:
|
||||
{
|
||||
fprintf (distance->_io->output, "%d %ld\n",
|
||||
cur_iteration,
|
||||
limit_inferior);
|
||||
printf (" -- borne inférieure %ld\n",
|
||||
limit_inferior);
|
||||
};
|
||||
break;
|
||||
case MODE_SHOW_LIMIT_SUP:
|
||||
{
|
||||
|
||||
fprintf (distance->_io->output, "%d %ld\n",
|
||||
cur_iteration,
|
||||
limit_superior);
|
||||
printf (" -- borne supérieure %ld\n",
|
||||
limit_superior);
|
||||
|
||||
};
|
||||
break;
|
||||
case MODE_DEFI:
|
||||
{
|
||||
/* tous les noeuds ont été visités, on calcule alors la distance
|
||||
* maximale dans l'arbre (largeur) , et on garde a chaque fois le
|
||||
* minimum */
|
||||
|
||||
fprintf (distance->_io->output, "inf %d %ld\n",
|
||||
cur_iteration,
|
||||
limit_inferior);
|
||||
|
||||
fprintf(distance->_io->output, "avg %d %f\n",
|
||||
cur_iteration,
|
||||
approx_average_distance);
|
||||
|
||||
fprintf (distance->_io->output, "sup %d %ld\n",
|
||||
cur_iteration,
|
||||
limit_superior);
|
||||
|
||||
};
|
||||
break;
|
||||
default:
|
||||
assert(1==0);
|
||||
break;
|
||||
}
|
||||
|
||||
fifo_destroy (computation->visited_nodes);
|
||||
free (computation);
|
||||
pDEBUG(" -- end \n");
|
||||
}
|
||||
|
||||
fifo_destroy(fifo_roots);
|
||||
|
||||
average_average_distance =
|
||||
(float)average_average_distance
|
||||
/ (float)(distance->_iterations);
|
||||
|
||||
if ((distance->_mode == MODE_MAX_AND_AVERAGE)
|
||||
&& (distance->_mode != MODE_MAX_DISTRIBUTION)) {
|
||||
printf ("Final maximum distance : %ld\n", max_max_distance);
|
||||
printf ("Final average distance : %f\n", average_average_distance);
|
||||
}
|
||||
|
||||
pDEBUG("end\n");
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Calcule de toutes les distances à partir d'un unique noeud
|
||||
*
|
||||
* ATTENTION: utilise STORE_EXTRA_DEGREE
|
||||
*/
|
||||
|
||||
distance_computation_t * distance_all_from_one_node(
|
||||
Distance_t * distance,
|
||||
nodeindex_t cc_root,
|
||||
int iteration)
|
||||
{
|
||||
/** oblige a avoir initilisé les degrés */
|
||||
assert(distance->_store->_mod_degree == STORE_MODIF_END);
|
||||
|
||||
distance_computation_t * result;
|
||||
result = (distance_computation_t *) malloc (sizeof(distance_computation_t));
|
||||
result->average = 0;
|
||||
result->cc_size = 0;
|
||||
result->maximum = 0;
|
||||
result->visited_nodes = fifo_create(distance->_size);
|
||||
|
||||
/* choisir aléatoirement une valeur dans le Fifo_t */
|
||||
nodeindex_t root = cc_root;
|
||||
|
||||
/* on reset le store afin de pouvoir faire des calculs dessus */
|
||||
store_reset (distance->_store, STORE_RESET_ALL ^ STORE_RESET_DEGREE);
|
||||
|
||||
/* on indique au store qu'on s'apprete a faire des modifications sur
|
||||
* les références */
|
||||
distance->_store->_mod_ref = STORE_MODIF_BEGIN;
|
||||
distance->_store->_mod_value = STORE_MODIF_BEGIN;
|
||||
|
||||
nodeindex_t dist_nodecounter = 0; /* compteur de noeuds pour une distance donnée */
|
||||
nodeindex_t dist_curdist = 0; /* distance comptée actuelle */
|
||||
nodeindex_t root_distance;
|
||||
nodeindex_t root_oldvalue = root;
|
||||
|
||||
Fifo_t * fifo_remaining_nodes = fifo_create(distance->_size);
|
||||
pDEBUG("choosing %ld as the root\n", root);
|
||||
fifo_push (fifo_remaining_nodes, root);
|
||||
|
||||
store_set_ref (distance->_store, root, NODEINDEX_ROOT);
|
||||
store_set_value (distance->_store, root, 0); /* distance 0 */
|
||||
|
||||
while (!fifo_is_empty (fifo_remaining_nodes)) {
|
||||
result->cc_size += 1;
|
||||
root_oldvalue = root;
|
||||
root = fifo_pop (fifo_remaining_nodes);
|
||||
fifo_push (result->visited_nodes, root);
|
||||
|
||||
root_distance = store_get_value (distance->_store, root);
|
||||
|
||||
if (distance->_mode == MODE_MAX_DISTRIBUTION){
|
||||
if ((root_distance > dist_curdist) || (root_distance > result->maximum)){
|
||||
fprintf(distance->_io->output, "%ld %ld\n", dist_curdist, dist_nodecounter);
|
||||
dist_curdist = root_distance;
|
||||
dist_nodecounter = 0;
|
||||
}
|
||||
dist_nodecounter += 1;
|
||||
}
|
||||
|
||||
if (root_distance > result->maximum) {
|
||||
result->maximum = root_distance;
|
||||
}
|
||||
result->average += root_distance;
|
||||
|
||||
nodeindex_t cur;
|
||||
nodeindex_t degree = store_get_degree (distance->_store, root);
|
||||
|
||||
/* pour tous les noeuds adjacents, ajouter a la fifo */
|
||||
for (cur = 0; cur < degree; cur++){
|
||||
nodeindex_t node = store_get_adjacent (distance->_store, root, cur);
|
||||
/* printf("Adjacent node %ld\n", node); */
|
||||
|
||||
store_modif_t ref_status = distance->_store->_mod_ref;
|
||||
distance->_store->_mod_ref = STORE_MODIF_END;
|
||||
|
||||
bool is_undone = store_is_visit_undone (distance->_store, node);
|
||||
distance->_store->_mod_ref = ref_status;
|
||||
|
||||
if (is_undone){
|
||||
nodeindex_t cur_distance = root_distance + 1;
|
||||
|
||||
store_set_ref (distance->_store, node, root);
|
||||
store_set_value (distance->_store, node, cur_distance);
|
||||
fifo_push (fifo_remaining_nodes, node);
|
||||
}
|
||||
}
|
||||
|
||||
/* parcourir tous les noeuds de la composante connexe, si on les connait pas */
|
||||
|
||||
} /* end while fifo_is_empty*/
|
||||
|
||||
/* on a fini de faire des modifications sur les références */
|
||||
distance->_store->_mod_value = STORE_MODIF_END;
|
||||
distance->_store->_mod_ref = STORE_MODIF_END;
|
||||
|
||||
pDEBUG("done\n");
|
||||
result->average = ((float)(result->average) / (float)(result->cc_size));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Trouve la plus grande distance dans l'arbre du parcours en largeur
|
||||
* FIXME: probablement une erreur de calcul dans la largeur pour les
|
||||
* arbres plats a nombreux voisins
|
||||
*
|
||||
* ATTENTION: utilise STORE_EXTRA_REF
|
||||
*
|
||||
* ATTENTION: modifie STORE_EXTRA_VALUE
|
||||
*
|
||||
* ATTENTION: modifie STORE_EXTRA_VALUE2
|
||||
*
|
||||
* VALUE indique la hauteur et
|
||||
* VALUE2 indique la largeur max
|
||||
*/
|
||||
|
||||
nodeindex_t distance_width (Distance_t * distance, Fifo_t * fifo_visit){
|
||||
Fifo_t * fifo_inverse_visit = fifo_copy (fifo_visit);
|
||||
fifo_reverse (fifo_inverse_visit);
|
||||
|
||||
assert(distance->_store->_mod_ref == STORE_MODIF_END);
|
||||
|
||||
store_reset (distance->_store, STORE_RESET_VALUE | STORE_RESET_VALUE2);
|
||||
distance->_store->_mod_value = STORE_MODIF_BEGIN;
|
||||
distance->_store->_mod_value2 = STORE_MODIF_BEGIN;
|
||||
|
||||
nodeindex_t last_node = NODEINDEX_UNDEF;
|
||||
|
||||
while(!fifo_is_empty(fifo_inverse_visit)){
|
||||
nodeindex_t cur_node = fifo_pop (fifo_inverse_visit);
|
||||
last_node = cur_node;
|
||||
pDEBUG("visiting %ld\n", cur_node);
|
||||
|
||||
nodeindex_t father_node = store_get_ref (distance->_store, cur_node);
|
||||
|
||||
nodeindex_t cur_height = store_get_value (distance->_store, cur_node);
|
||||
nodeindex_t cur_width = store_get_value_2 (distance->_store, cur_node);
|
||||
|
||||
|
||||
if (cur_height == NODEINDEX_UNDEF){
|
||||
/* hauteur zéro pour le noeud si jamais visité, car
|
||||
* il s'agit d'une feuille */
|
||||
cur_height = 0;
|
||||
}
|
||||
if (cur_width == NODEINDEX_UNDEF){
|
||||
/* largeur zéro pour le noeud si jamais visité, car
|
||||
* il s'agit d'une feuille */
|
||||
cur_width = 0;
|
||||
}
|
||||
|
||||
store_set_value (distance->_store, cur_node, cur_height);
|
||||
store_set_value_2 (distance->_store, cur_node, cur_width);
|
||||
|
||||
pDEBUG(" - %ld height = %ld\n", cur_node, cur_height);
|
||||
pDEBUG(" - %ld width = %ld\n", cur_node, cur_width);
|
||||
|
||||
if (father_node != NODEINDEX_ROOT){
|
||||
nodeindex_t father_height = store_get_value (distance->_store, father_node);
|
||||
nodeindex_t father_width = store_get_value_2 (distance->_store, father_node);
|
||||
|
||||
if (father_height == NODEINDEX_UNDEF){
|
||||
/* hauteur zéro pour le noeud si jamais visité */
|
||||
father_height = 0;
|
||||
}
|
||||
if (father_width == NODEINDEX_UNDEF){
|
||||
/* largeur zéro pour le noeud si jamais visité */
|
||||
father_width = 0;
|
||||
}
|
||||
|
||||
nodeindex_t old_father_height = father_height;
|
||||
|
||||
father_height =
|
||||
MAX(
|
||||
cur_height + 1,
|
||||
father_height
|
||||
);
|
||||
|
||||
/* marche pas
|
||||
father_width = MAX(
|
||||
cur_width + 1, // passe par cur_node
|
||||
MAX(
|
||||
//father_height + cur_height,
|
||||
father_height + cur_height + 1, //passe par cur_node et father_node
|
||||
father_width // pas dans le sous arbre de cur_node
|
||||
)
|
||||
);
|
||||
*/
|
||||
/* marche */
|
||||
|
||||
/*
|
||||
* printf("cur plus grand : %ld\n", cur_width);
|
||||
* printf("plus grand déja passé : %ld\n", father_width);
|
||||
* printf("rejoint les plus longs: %ld\n", old_father_height + cur_height + 1);
|
||||
*/
|
||||
|
||||
father_width =
|
||||
MAX(
|
||||
MAX(
|
||||
// si cur est le plus grand
|
||||
cur_width,
|
||||
// si le plus grand est déja passé par là avant
|
||||
father_width
|
||||
),
|
||||
old_father_height + cur_height + 1// on rejoint deux plus longs chemins
|
||||
);
|
||||
/**/
|
||||
/*
|
||||
father_width =
|
||||
MAX(
|
||||
cur_width + 1,
|
||||
MAX(
|
||||
father_height + cur_height,
|
||||
father_width
|
||||
)
|
||||
);
|
||||
*/
|
||||
store_set_value (distance->_store, father_node, father_height);
|
||||
store_set_value_2 (distance->_store, father_node, father_width);
|
||||
|
||||
pDEBUG(" - father %ld\n", father_node);
|
||||
pDEBUG(" - height = %ld\n", father_height);
|
||||
pDEBUG(" - width = %ld\n", father_width);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
nodeindex_t max_height = store_get_value (distance->_store, last_node);
|
||||
nodeindex_t max_width = store_get_value_2 (distance->_store, last_node);
|
||||
|
||||
distance->_store->_mod_value = STORE_MODIF_END;
|
||||
distance->_store->_mod_value2 = STORE_MODIF_END;
|
||||
|
||||
pDEBUG("Maximum height = %ld\n", max_height);
|
||||
pDEBUG("Maximum width = %ld\n", max_width);
|
||||
|
||||
fifo_destroy (fifo_inverse_visit);
|
||||
return max_width;
|
||||
}
|
||||
|
||||
#undef DEBUG
|
|
@ -0,0 +1,59 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#ifndef _DISTANCE_H
|
||||
#define _DISTANCE_H
|
||||
|
||||
#include "config.h"
|
||||
#include "store.h"
|
||||
#include "fifo.h"
|
||||
|
||||
typedef struct {
|
||||
float average;
|
||||
nodeindex_t cc_size;
|
||||
nodeindex_t maximum;
|
||||
Fifo_t * visited_nodes;
|
||||
} distance_computation_t;
|
||||
|
||||
typedef enum {
|
||||
MODE_UNDEF,
|
||||
MODE_MAX_AND_AVERAGE,
|
||||
MODE_MAX_DISTRIBUTION,
|
||||
MODE_EVOLUTION,
|
||||
MODE_SHOW_LIMIT_INF,
|
||||
MODE_SHOW_LIMIT_SUP,
|
||||
MODE_DEFI
|
||||
} distance_mode_t ;
|
||||
|
||||
typedef struct {
|
||||
Config_io_t * _io;
|
||||
|
||||
distance_mode_t _mode;
|
||||
Store_t * _store;
|
||||
int _iterations;
|
||||
nodeindex_t _size;
|
||||
nodeindex_t _root;
|
||||
// Fifo_t * _fifo;
|
||||
} Distance_t ;
|
||||
|
||||
|
||||
Distance_t * distance_create (Config_io_t * io, nodeindex_t size);
|
||||
|
||||
void distance_compute(Distance_t * distance);
|
||||
|
||||
void distance_destroy (Distance_t * distance);
|
||||
|
||||
distance_computation_t * distance_all_from_one_node(
|
||||
Distance_t * distance,
|
||||
nodeindex_t cc_root,
|
||||
int iteration);
|
||||
|
||||
void distance_set_root(Distance_t * distance, nodeindex_t rootidx);
|
||||
|
||||
void distance_set_mode(Distance_t * distance, distance_mode_t mode);
|
||||
|
||||
nodeindex_t distance_width (Distance_t * distance, Fifo_t * fifo_visit);
|
||||
|
||||
void distance_set_iterations(Distance_t * distance, int iterations);
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,235 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "fifo.h"
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
/**
|
||||
* Constructeur de la file (d'index de noeuds) Fifo_t
|
||||
*
|
||||
* @param size Longueur maximum de la Fifo_t
|
||||
* @return Un pointeur sur la Fifo_t créée
|
||||
*/
|
||||
|
||||
Fifo_t * fifo_create(nodeindex_t size){
|
||||
Fifo_t * fifo = (Fifo_t *) malloc (sizeof(Fifo_t));
|
||||
|
||||
|
||||
fifo->_fill = 0;
|
||||
|
||||
pDEBUG("Fifo size : %ld\n", size);
|
||||
fifo->_size = size;
|
||||
fifo->_head = -1;
|
||||
fifo->_tail = -1;
|
||||
|
||||
fifo->_data = (nodeindex_t *) malloc (sizeof(nodeindex_t) * size);
|
||||
|
||||
return fifo;
|
||||
}
|
||||
|
||||
Fifo_t * fifo_copy(Fifo_t * fifo){
|
||||
pDEBUG("Fifo size : %ld\n", fifo->_size);
|
||||
Fifo_t * result = fifo_create(fifo->_size);
|
||||
result->_fill = fifo->_fill;
|
||||
result->_head = fifo->_head;
|
||||
result->_tail = fifo->_tail;
|
||||
memcpy(result->_data, fifo->_data, (sizeof(nodeindex_t) * fifo->_size));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void fifo_reverse(Fifo_t * fifo){
|
||||
pDEBUG("Fifo size : %ld\n", fifo->_size);
|
||||
|
||||
// pour chaque element du fifo on inverse sa position
|
||||
nodeindex_t tail = fifo->_tail;
|
||||
nodeindex_t head = fifo->_head;
|
||||
nodeindex_t fillcounter = 0;
|
||||
if (fifo->_fill > 0){
|
||||
while( (2 * fillcounter) < fifo->_fill ){
|
||||
pDEBUG("head %ld tail %ld swap %ld and %ld\n",
|
||||
head, tail, fifo->_data[head],
|
||||
fifo->_data[tail]);
|
||||
nodeindex_t tmp = fifo->_data[head];
|
||||
fifo->_data[head] = fifo->_data[tail];
|
||||
fifo->_data[tail] = tmp;
|
||||
tail += -1;
|
||||
head += 1;
|
||||
if (tail < 0) { tail = fifo->_size - 1; }
|
||||
if (head >= fifo->_size) { head = 0; }
|
||||
fillcounter += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destructeur de la file Fifo_t
|
||||
*
|
||||
* @param Un pointeur sur la Fifo_t
|
||||
*/
|
||||
|
||||
void fifo_destroy(Fifo_t * fifo){
|
||||
free(fifo->_data);
|
||||
free(fifo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indique si la file Fifo_t est vide
|
||||
*
|
||||
* @param Un pointeur sur la Fifo_t
|
||||
* @return TRUE si la Fifo_t est vide, FALSE sinon
|
||||
*/
|
||||
|
||||
bool fifo_is_empty(Fifo_t * fifo){
|
||||
bool result;
|
||||
if ((fifo->_head == -1) && (fifo->_tail == -1)){
|
||||
result = true;
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ajoute un élément en fin de liste Fifo_t
|
||||
*
|
||||
* @param Un pointeur sur la Fifo_t
|
||||
* @param Un index de noeud a enregistrer dans la Fifo_t
|
||||
*/
|
||||
|
||||
void fifo_push(Fifo_t * fifo, nodeindex_t node){
|
||||
pDEBUG("value %ld\n", node);
|
||||
pnDEBUG("tail %ld ->", fifo->_tail);
|
||||
|
||||
if (fifo->_tail == -1){
|
||||
pnDEBUG("(undef) ");
|
||||
assert(fifo->_head == -1);
|
||||
|
||||
fifo->_tail = 0;
|
||||
fifo->_head = 0;
|
||||
} else {
|
||||
fifo->_tail += 1;
|
||||
if (fifo->_tail >= fifo->_size){
|
||||
fifo->_tail = 0;
|
||||
pnDEBUG("(loop) ");
|
||||
}
|
||||
}
|
||||
fifo->_data[fifo->_tail] = node;
|
||||
fifo->_fill += 1;
|
||||
pnDEBUG("%ld\n", fifo->_tail);
|
||||
assert(fifo->_fill <= fifo->_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lit sans retirer le premier élément de la Fifo_t
|
||||
*
|
||||
* @param Un pointeur sur la Fifo_t
|
||||
* @return Le premier élément de la Fifo_t
|
||||
*/
|
||||
|
||||
nodeindex_t fifo_front(Fifo_t * fifo){
|
||||
nodeindex_t result ;
|
||||
result = fifo->_data[fifo->_head];
|
||||
pDEBUG("value %ld\n", result);
|
||||
pDEBUG("head at %ld\n", fifo->_head);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lit et retire le premier élément de la Fifo_t
|
||||
*
|
||||
* @param Un pointeur sur la Fifo_t
|
||||
* @return Le premier élément de la Fifo_t
|
||||
*/
|
||||
|
||||
nodeindex_t fifo_pop(Fifo_t * fifo){
|
||||
nodeindex_t result ;
|
||||
result = fifo->_data[fifo->_head];
|
||||
pDEBUG("value %ld\n", result);
|
||||
pnDEBUG("head %ld -> ", fifo->_head);
|
||||
|
||||
fifo->_head += 1;
|
||||
if (fifo->_head >= fifo->_size){
|
||||
fifo->_head = 0;
|
||||
}
|
||||
|
||||
fifo->_fill -= 1;
|
||||
if (fifo->_fill == 0){
|
||||
pnDEBUG("(empty) ");
|
||||
fifo->_head = -1;
|
||||
fifo->_tail = -1;
|
||||
}
|
||||
assert(fifo->_fill >= 0);
|
||||
pnDEBUG("%ld\n", fifo->_head);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Lit un élément au hasard dans la file Fifo_t
|
||||
*
|
||||
* @param Un pointeur sur la Fifo_t
|
||||
*/
|
||||
|
||||
nodeindex_t fifo_get_random(Fifo_t * fifo){
|
||||
nodeindex_t idx = rand() % fifo_get_size(fifo);
|
||||
nodeindex_t result;
|
||||
pDEBUG("between %ld and %ld (size %ld)\n",
|
||||
(long)fifo->_head,
|
||||
(long)fifo->_tail,
|
||||
fifo->_size);
|
||||
idx += fifo->_head;
|
||||
if (idx >= fifo->_size){
|
||||
idx = idx % (fifo->_size);
|
||||
}
|
||||
result = fifo->_data[idx];
|
||||
pDEBUG("gives %ld (value = %ld)\n",idx, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indique la taille de la file Fifo_t passée en paramètre
|
||||
*
|
||||
* @param Un pointeur sur la Fifo_t
|
||||
*/
|
||||
|
||||
nodeindex_t fifo_get_size(Fifo_t * fifo){
|
||||
return fifo->_fill;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Affiche le contenu de la file Fifo_t sur la sortie
|
||||
* standard
|
||||
*/
|
||||
|
||||
void fifo_display(Fifo_t * fifo){
|
||||
int idx = fifo->_head;
|
||||
bool done = false;
|
||||
pDEBUG(" ");
|
||||
printf("[");
|
||||
while (!done){
|
||||
if (idx == -1) { break; }
|
||||
if (idx == fifo->_tail) { done = true; }
|
||||
printf("%ld", fifo->_data[idx]);
|
||||
|
||||
if (!done){ printf(", "); }
|
||||
|
||||
idx += 1;
|
||||
if (idx >= fifo->_size){ idx = 0; }
|
||||
}
|
||||
printf(" ]\n");
|
||||
}
|
||||
|
||||
#undef DEBUG
|
|
@ -0,0 +1,40 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#ifndef _FIFO_H
|
||||
#define _FIFO_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
typedef struct {
|
||||
nodeindex_t * _data;
|
||||
|
||||
nodeindex_t _fill;
|
||||
nodeindex_t _size;
|
||||
nodeindex_t _head;
|
||||
nodeindex_t _tail;
|
||||
} Fifo_t;
|
||||
|
||||
|
||||
Fifo_t * fifo_create(nodeindex_t size);
|
||||
|
||||
void fifo_push(Fifo_t * fifo, nodeindex_t node);
|
||||
|
||||
Fifo_t * fifo_copy(Fifo_t * fifo);
|
||||
|
||||
void fifo_reverse(Fifo_t * fifo);
|
||||
|
||||
bool fifo_is_empty(Fifo_t * fifo);
|
||||
|
||||
nodeindex_t fifo_front(Fifo_t * fifo);
|
||||
|
||||
nodeindex_t fifo_pop(Fifo_t * fifo);
|
||||
|
||||
nodeindex_t fifo_get_size(Fifo_t * fifo);
|
||||
|
||||
void fifo_display(Fifo_t * fifo);
|
||||
|
||||
void fifo_destroy(Fifo_t * fifo);
|
||||
|
||||
nodeindex_t fifo_get_random(Fifo_t * fifo);
|
||||
|
||||
#endif // _FIFO_H
|
|
@ -0,0 +1,50 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#include "filter.h"
|
||||
|
||||
Filter_t * filter_create(Config_io_t * io, nodeindex_t size, nodeindex_t offset)
|
||||
{
|
||||
Filter_t * filter = (Filter_t*) malloc (sizeof(Filter_t));
|
||||
|
||||
filter->_io = io;
|
||||
filter->_size = size;
|
||||
filter->_offset = offset;
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
void filter_destroy(Filter_t * filter){
|
||||
free(filter);
|
||||
filter = NULL;
|
||||
}
|
||||
|
||||
void filter_run(Filter_t * filter){
|
||||
|
||||
printf("filter_run -- Filtering between [ %d .. %d ]...\n",
|
||||
filter->_offset,
|
||||
filter->_size + filter->_offset);
|
||||
|
||||
char * buf = (char *) malloc (sizeof(char) * 100);
|
||||
char * buf2;
|
||||
for (;;){
|
||||
if (gzeof(filter->_io->input)){ break; }
|
||||
|
||||
buf2 = gzgets (filter->_io->input, buf, 100);
|
||||
if (buf2 == Z_NULL){
|
||||
printf ("filter_run -- READ OFF\n");
|
||||
break;
|
||||
} else {
|
||||
nodeindex_t one, two;
|
||||
sscanf(buf,"%ld %ld",&one,&two);
|
||||
if ((one >= filter->_offset)
|
||||
&& (one < (filter->_offset + filter->_size))
|
||||
&& (two >= filter->_offset)
|
||||
&& (two < (filter->_offset + filter->_size))
|
||||
){
|
||||
fwrite (buf2, sizeof(char), strlen(buf2), filter->_io->output);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("filter_run -- done\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#ifndef _GYR_FILTER_H
|
||||
#define _GYR_FILTER_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "units.h"
|
||||
#include "config.h"
|
||||
|
||||
typedef struct {
|
||||
Config_io_t * _io;
|
||||
int _size;
|
||||
int _offset;
|
||||
|
||||
} Filter_t;
|
||||
|
||||
Filter_t * filter_create(Config_io_t * io, nodeindex_t size, nodeindex_t offset);
|
||||
void filter_run(Filter_t * filter);
|
||||
void filter_destroy(Filter_t * filter);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,150 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#include <assert.h>
|
||||
#include "generator.h"
|
||||
#include "progressindicator.h"
|
||||
#include "list.h"
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
nodeindex_t * nodeindex_create(nodeindex_t value){
|
||||
nodeindex_t * var = ((nodeindex_t *) malloc (sizeof(nodeindex_t)));
|
||||
*var = value;
|
||||
return var;
|
||||
}
|
||||
|
||||
void nodeindex_destroy(void * daInt){
|
||||
nodeindex_t * truc = daInt;
|
||||
free(truc);
|
||||
}
|
||||
|
||||
Generator_t * generator_create (Config_io_t * io, nodeindex_t n_count, nodeindex_t e_count){
|
||||
Generator_t * generator = (Generator_t *) malloc (sizeof(Generator_t));
|
||||
|
||||
generator->_io = io;
|
||||
generator->_node_count = n_count;
|
||||
generator->_edge_count = e_count;
|
||||
|
||||
// on crée le tableau et on initialise tout le monde à zéro.
|
||||
generator->_data = (List_t **) malloc (sizeof(List_t*) * n_count);
|
||||
|
||||
nodeindex_t cur;
|
||||
for (cur = 0; cur < generator->_node_count; cur++){
|
||||
generator->_data[cur] = list_create();
|
||||
}
|
||||
|
||||
return generator;
|
||||
}
|
||||
|
||||
void generator_destroy (Generator_t * generator){
|
||||
free(generator->_data);
|
||||
free(generator);
|
||||
//FIXME: détruire les données
|
||||
//FIXME: détruire l'objet
|
||||
}
|
||||
|
||||
bool generator_is_already_adjacent (Generator_t * generator, nodeindex_t src, nodeindex_t dst){
|
||||
nodeindex_t min, max;
|
||||
if (src < dst){
|
||||
min = src;
|
||||
max = dst;
|
||||
} else {
|
||||
min = dst;
|
||||
max = src;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
List_cell_t * iterator = list_iterator(generator->_data[min]);
|
||||
while(!list_iterator_is_end(iterator)){
|
||||
|
||||
nodeindex_t * val = list_iterator_value(iterator);
|
||||
if (*val == max) { found = true; break; }
|
||||
|
||||
iterator = list_iterator_next(iterator);
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
bool generator_degree_is_null (Generator_t * generator, nodeindex_t idx){
|
||||
return list_is_empty(generator->_data[idx]);
|
||||
}
|
||||
|
||||
void generator_add_edge(Generator_t * generator, nodeindex_t src, nodeindex_t dest){
|
||||
if (src < dest){
|
||||
list_push_back(generator->_data[src], nodeindex_create(dest));
|
||||
} else {
|
||||
list_push_back(generator->_data[dest], nodeindex_create(src));
|
||||
}
|
||||
}
|
||||
|
||||
void generator_run(Generator_t * generator){
|
||||
|
||||
nodeindex_t cur;
|
||||
if (generator->_node_count > generator->_edge_count){
|
||||
fprintf(stderr, "ATTENTION: il y aura des noeuds de degré zéro!\n");
|
||||
} else {
|
||||
nodeindex_t remaining = generator->_edge_count - generator->_node_count;
|
||||
|
||||
for (cur = 0; cur < generator->_node_count; cur++){
|
||||
|
||||
fprintf(stderr,"\r%s Selecting degrees... (%d of %d)",
|
||||
progress_indicator(),
|
||||
cur + 1,
|
||||
generator->_edge_count);
|
||||
nodeindex_t selected_node;
|
||||
// si le degré est nul, alors on crée un lien
|
||||
// vers un autre noeud (rempli ou non)
|
||||
// (pour qu'aucun des noeuds ne soit seul)
|
||||
if (generator_degree_is_null (generator, cur)){
|
||||
bool is_bad;
|
||||
do {
|
||||
is_bad = false;
|
||||
selected_node = rand() % generator->_node_count;
|
||||
if (selected_node == cur){ is_bad = true; }
|
||||
} while(is_bad);
|
||||
generator_add_edge (generator, cur, selected_node);
|
||||
}
|
||||
}
|
||||
|
||||
for (cur = 0; cur < remaining; cur++){
|
||||
nodeindex_t src_node;
|
||||
nodeindex_t dst_node;
|
||||
nodeindex_t deg;
|
||||
|
||||
fprintf(stderr,"\r%s Selecting degreex... (%d of %d)",
|
||||
progress_indicator(),
|
||||
cur + 1 + generator->_node_count,
|
||||
generator->_edge_count);
|
||||
|
||||
bool is_bad;
|
||||
do {
|
||||
is_bad = false;
|
||||
|
||||
src_node = rand() % generator->_node_count;
|
||||
dst_node = rand() % generator->_node_count;
|
||||
if (src_node == dst_node){ is_bad = true; }
|
||||
if (generator_is_already_adjacent (generator, src_node, dst_node)){ is_bad = true; }
|
||||
} while(is_bad);
|
||||
|
||||
generator_add_edge (generator, src_node, dst_node);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
|
||||
//FIXME: créer un deuxieme tableau de taille n, avec tab[i] = i;
|
||||
//utiliser ce tableau pour remplir les listes, afin d'éparpiller un peu moins les trucs en mémoire
|
||||
|
||||
}
|
||||
|
||||
//FIXME output sur stdout...
|
||||
for (cur = 0; cur < generator->_node_count; cur++){
|
||||
while(!generator_degree_is_null (generator, cur)){
|
||||
nodeindex_t * dest = list_pop_front (generator->_data[cur]);
|
||||
fprintf(generator->_io->output, "%ld %ld\n", cur, *dest);
|
||||
nodeindex_destroy(dest);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#undef DEBUG
|
|
@ -0,0 +1,24 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#ifndef _GENERATOR_H
|
||||
#define _GENERATOR_H
|
||||
|
||||
#include "config.h"
|
||||
#include "list.h"
|
||||
|
||||
typedef struct {
|
||||
Config_io_t * _io;
|
||||
|
||||
int _iterations;
|
||||
nodeindex_t _node_count;
|
||||
nodeindex_t _edge_count;
|
||||
|
||||
List_t ** _data;
|
||||
} Generator_t ;
|
||||
|
||||
|
||||
Generator_t * generator_create (Config_io_t * io, nodeindex_t n_count, nodeindex_t e_count);
|
||||
|
||||
void generator_destroy (Generator_t * distance);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,274 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "list.h"
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
List_t * list_create(){
|
||||
pDEBUG("\n");
|
||||
List_t * list = (List_t *) malloc (sizeof(List_t));
|
||||
|
||||
list_init(list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
void list_init(List_t * list){
|
||||
list->head = NULL;
|
||||
list->tail = NULL;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
void list_destroy(List_t * list){
|
||||
pDEBUG("\n");
|
||||
// on détruit tous les noeuds de la liste,
|
||||
// sans détruire les données dedans ?
|
||||
while(!list_is_empty(list)){
|
||||
pDEBUG("destroying front cell\n");
|
||||
void * data = list_pop_front(list);
|
||||
pDEBUG("set data to NULL\n");
|
||||
data = NULL;
|
||||
}
|
||||
free(list);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
void list_destroy_with_data(List_t * list, void (* data_destroy_fun) (void *)){
|
||||
// on détruit tous les noeuds de la liste,
|
||||
// sans détruire les données dedans ?
|
||||
while(!list_is_empty(list)){
|
||||
pDEBUG("destroying front cell and data\n");
|
||||
void * data = list_pop_front(list);
|
||||
(* data_destroy_fun)(data);
|
||||
}
|
||||
free(list);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
List_cell_t * list_cell_create(){
|
||||
List_cell_t * list_cell =
|
||||
(List_cell_t *) malloc (sizeof(List_cell_t));
|
||||
pDEBUG("set data to NULL\n");
|
||||
list_cell->data = NULL;
|
||||
list_cell->next = NULL;
|
||||
list_cell->prev = NULL;
|
||||
return list_cell;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
void list_cell_destroy(List_cell_t * list_cell){
|
||||
assert(list_cell->data == NULL);
|
||||
free(list_cell);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
void list_cell_destroy_with_data(List_cell_t * list_cell,
|
||||
void (* data_destroy_fun) (void *))
|
||||
{
|
||||
data_destroy_fun(list_cell->data);
|
||||
|
||||
pDEBUG("set data to NULL\n");
|
||||
list_cell->data = NULL;
|
||||
list_cell_destroy(list_cell);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
bool list_is_empty(List_t * list){
|
||||
bool result = false;
|
||||
if ((list->head == list->tail)
|
||||
&& (list->head == NULL)){
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
void list_push_back(List_t * list, void * data){
|
||||
// si la liste est vide ?
|
||||
if (list_is_empty(list)){
|
||||
List_cell_t * cell = list_cell_create();
|
||||
cell->data = data;
|
||||
|
||||
list->head = cell;
|
||||
list->tail = cell;
|
||||
} else {
|
||||
List_cell_t * old_tail = list->tail;
|
||||
List_cell_t * new_tail = list_cell_create();
|
||||
|
||||
new_tail->data = data;
|
||||
|
||||
old_tail->next = new_tail;
|
||||
new_tail->prev = old_tail;
|
||||
|
||||
list->tail = new_tail;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
void list_push_front(List_t * list, void * data){
|
||||
// si la liste est vide ?
|
||||
if (list_is_empty(list)){
|
||||
List_cell_t * cell = list_cell_create();
|
||||
cell->data = data;
|
||||
|
||||
list->head = cell;
|
||||
list->tail = cell;
|
||||
} else {
|
||||
List_cell_t * old_head = list->head;
|
||||
List_cell_t * new_head = list_cell_create();
|
||||
|
||||
new_head->data = data;
|
||||
|
||||
old_head->prev = new_head;
|
||||
new_head->next = old_head;
|
||||
|
||||
list->head = new_head;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
void * list_pop_front(List_t * list){
|
||||
void * celldata = NULL;
|
||||
if (!list_is_empty(list)){
|
||||
pDEBUG("\n");
|
||||
celldata = list_front(list);
|
||||
List_cell_t * cell = list->head;
|
||||
|
||||
list->head = cell->next;
|
||||
if (list->head == NULL){ list->tail = NULL; }
|
||||
|
||||
pDEBUG("set data to NULL\n");
|
||||
cell->data = NULL;
|
||||
list_cell_destroy(cell);
|
||||
}
|
||||
return celldata;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
void * list_pop_back(List_t * list){
|
||||
void * celldata = NULL;
|
||||
if (!list_is_empty(list)){
|
||||
pDEBUG("\n");
|
||||
celldata = list_back(list);
|
||||
|
||||
List_cell_t * cell = list->tail;
|
||||
list->tail = cell->prev;
|
||||
if (list->tail == NULL){ list->head = NULL; }
|
||||
|
||||
pDEBUG("set data to NULL\n");
|
||||
cell->data = NULL;
|
||||
list_cell_destroy(cell);
|
||||
}
|
||||
return celldata;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
void * list_front(List_t * list){
|
||||
List_cell_t * cell = list->head;
|
||||
|
||||
void * celldata;
|
||||
if (cell != NULL){
|
||||
celldata = cell->data;
|
||||
} else {
|
||||
celldata = NULL;
|
||||
//assert(0==1); //FIXME! trouver un moyen d'indiquer que la liste est vide...
|
||||
}
|
||||
|
||||
return celldata;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
void * list_back(List_t * list){
|
||||
List_cell_t * cell = list->tail;
|
||||
|
||||
void * celldata;
|
||||
if (cell != NULL){
|
||||
celldata = cell->data;
|
||||
} else {
|
||||
celldata = NULL;
|
||||
// assert(0==1); //FIXME! trouver un moyen d'indiquer que la liste est vide...
|
||||
}
|
||||
return celldata;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
void * list_iterator_value(List_iterator_t * iterator){
|
||||
return iterator->data;
|
||||
}
|
||||
|
||||
List_iterator_t * list_iterator(List_t * list){
|
||||
return list->head;
|
||||
}
|
||||
|
||||
List_iterator_t * list_iterator_next(List_iterator_t * iterator){
|
||||
return iterator->next;
|
||||
}
|
||||
|
||||
bool list_iterator_is_end(List_cell_t * iterator){
|
||||
return (iterator == NULL);
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#ifndef _LIST_H
|
||||
#define _LIST_H
|
||||
|
||||
#include "units.h"
|
||||
|
||||
typedef struct list_cell_t {
|
||||
void * data;
|
||||
struct list_cell_t * prev;
|
||||
struct list_cell_t * next;
|
||||
} List_cell_t;
|
||||
|
||||
typedef List_cell_t List_iterator_t;
|
||||
|
||||
typedef struct {
|
||||
List_cell_t * head;
|
||||
List_cell_t * tail;
|
||||
} List_t ;
|
||||
|
||||
|
||||
List_t * list_create();
|
||||
|
||||
void list_init(List_t * list);
|
||||
|
||||
void list_destroy(List_t * list);
|
||||
|
||||
void list_destroy_with_data(List_t * list, void (* datadestroyfun)(void *) );
|
||||
|
||||
|
||||
List_cell_t * list_cell_create();
|
||||
|
||||
void list_cell_destroy(List_cell_t * cell);
|
||||
|
||||
void list_cell_destroy_with_data(List_cell_t * cell, void (* datadestroyfun)(void *) );
|
||||
|
||||
|
||||
bool list_is_empty(List_t * list);
|
||||
|
||||
void list_push_back(List_t * list, void * data);
|
||||
|
||||
void list_push_front(List_t * list, void * data);
|
||||
|
||||
// void list_merge(List_t * list_one, List_t * list_two);
|
||||
|
||||
void * list_pop_front(List_t * list);
|
||||
|
||||
void * list_pop_back(List_t * lista);
|
||||
|
||||
void * list_front(List_t * list);
|
||||
|
||||
void * list_back(List_t * list);
|
||||
|
||||
// void * list_remove(List_t * list, void * data);
|
||||
|
||||
void * list_reverse(List_t * list);
|
||||
|
||||
|
||||
void * list_iterator_value(List_cell_t *);
|
||||
|
||||
List_iterator_t * list_iterator(List_t * list);
|
||||
|
||||
List_iterator_t * list_iterator_next(List_cell_t * iterator);
|
||||
|
||||
bool list_iterator_is_end(List_cell_t * iterator);
|
||||
|
||||
|
||||
#endif /* _LIST_H */
|
|
@ -0,0 +1,66 @@
|
|||
0 1
|
||||
0 2
|
||||
1 3
|
||||
1 4
|
||||
1 5
|
||||
1 6
|
||||
1 7
|
||||
1 8
|
||||
1 9
|
||||
1 10
|
||||
1 11
|
||||
1 12
|
||||
1 13
|
||||
1 15
|
||||
1 16
|
||||
1 18
|
||||
1 19
|
||||
3 4
|
||||
3 5
|
||||
3 6
|
||||
3 7
|
||||
3 8
|
||||
3 13
|
||||
3 10
|
||||
16 3
|
||||
16 4
|
||||
16 5
|
||||
16 6
|
||||
16 7
|
||||
16 8
|
||||
4 5
|
||||
4 6
|
||||
4 7
|
||||
4 8
|
||||
4 15
|
||||
5 6
|
||||
5 7
|
||||
5 8
|
||||
5 19
|
||||
5 18
|
||||
6 7
|
||||
6 8
|
||||
7 8
|
||||
7 19
|
||||
7 18
|
||||
10 4
|
||||
10 5
|
||||
10 6
|
||||
10 7
|
||||
10 8
|
||||
13 4
|
||||
13 5
|
||||
13 6
|
||||
13 7
|
||||
13 8
|
||||
14 17
|
||||
15 3
|
||||
15 5
|
||||
15 6
|
||||
15 7
|
||||
15 8
|
||||
18 3
|
||||
18 4
|
||||
18 6
|
||||
18 8
|
||||
18 19
|
|
@ -0,0 +1,246 @@
|
|||
0 1
|
||||
0 2
|
||||
1 3
|
||||
1 4
|
||||
1 5
|
||||
1 6
|
||||
1 7
|
||||
1 8
|
||||
1 9
|
||||
1 10
|
||||
1 11
|
||||
1 12
|
||||
1 13
|
||||
1 15
|
||||
1 16
|
||||
1 18
|
||||
1 19
|
||||
1 20
|
||||
1 21
|
||||
1 22
|
||||
1 23
|
||||
1 25
|
||||
1 26
|
||||
1 27
|
||||
1 28
|
||||
1 29
|
||||
1 30
|
||||
27 31
|
||||
27 32
|
||||
27 33
|
||||
27 35
|
||||
27 36
|
||||
27 37
|
||||
27 40
|
||||
27 41
|
||||
27 42
|
||||
27 43
|
||||
27 44
|
||||
27 45
|
||||
27 46
|
||||
27 47
|
||||
27 48
|
||||
9 49
|
||||
9 50
|
||||
9 51
|
||||
2 52
|
||||
2 53
|
||||
2 54
|
||||
2 55
|
||||
2 56
|
||||
2 57
|
||||
2 58
|
||||
2 59
|
||||
3 4
|
||||
3 5
|
||||
3 6
|
||||
3 7
|
||||
3 8
|
||||
3 25
|
||||
3 26
|
||||
3 13
|
||||
3 10
|
||||
59 1
|
||||
16 3
|
||||
16 4
|
||||
16 5
|
||||
16 6
|
||||
16 7
|
||||
16 8
|
||||
16 25
|
||||
16 26
|
||||
49 51
|
||||
4 5
|
||||
4 6
|
||||
4 7
|
||||
4 8
|
||||
4 25
|
||||
4 26
|
||||
4 15
|
||||
31 33
|
||||
31 34
|
||||
31 35
|
||||
31 36
|
||||
31 44
|
||||
31 45
|
||||
31 46
|
||||
31 47
|
||||
31 48
|
||||
31 1
|
||||
31 43
|
||||
50 51
|
||||
5 6
|
||||
5 7
|
||||
5 8
|
||||
5 25
|
||||
5 26
|
||||
5 19
|
||||
5 18
|
||||
5 20
|
||||
32 31
|
||||
32 33
|
||||
32 34
|
||||
32 35
|
||||
32 36
|
||||
32 43
|
||||
32 44
|
||||
32 45
|
||||
32 46
|
||||
32 47
|
||||
32 48
|
||||
6 7
|
||||
6 8
|
||||
6 25
|
||||
6 26
|
||||
33 34
|
||||
33 35
|
||||
33 36
|
||||
33 43
|
||||
33 44
|
||||
33 45
|
||||
33 46
|
||||
33 47
|
||||
33 48
|
||||
7 8
|
||||
7 25
|
||||
7 26
|
||||
7 22
|
||||
7 21
|
||||
7 19
|
||||
7 18
|
||||
34 35
|
||||
34 36
|
||||
34 43
|
||||
34 44
|
||||
34 45
|
||||
34 46
|
||||
34 47
|
||||
34 48
|
||||
35 36
|
||||
35 1
|
||||
35 43
|
||||
35 44
|
||||
35 45
|
||||
35 46
|
||||
35 47
|
||||
35 48
|
||||
8 25
|
||||
8 26
|
||||
10 4
|
||||
10 5
|
||||
10 6
|
||||
10 7
|
||||
10 8
|
||||
10 25
|
||||
10 26
|
||||
36 23
|
||||
36 43
|
||||
11 59
|
||||
12 59
|
||||
38 39
|
||||
13 4
|
||||
13 5
|
||||
13 6
|
||||
13 7
|
||||
13 8
|
||||
13 25
|
||||
13 26
|
||||
15 5
|
||||
15 6
|
||||
15 7
|
||||
15 8
|
||||
15 25
|
||||
15 26
|
||||
17 14
|
||||
17 24
|
||||
18 3
|
||||
18 4
|
||||
18 6
|
||||
18 8
|
||||
18 25
|
||||
18 26
|
||||
18 19
|
||||
18 22
|
||||
43 1
|
||||
43 30
|
||||
43 44
|
||||
43 45
|
||||
43 46
|
||||
43 47
|
||||
43 48
|
||||
44 36
|
||||
44 3
|
||||
44 45
|
||||
44 46
|
||||
44 47
|
||||
44 48
|
||||
20 3
|
||||
20 4
|
||||
20 6
|
||||
20 7
|
||||
20 8
|
||||
20 25
|
||||
20 26
|
||||
45 36
|
||||
45 46
|
||||
45 47
|
||||
45 48
|
||||
46 36
|
||||
46 47
|
||||
46 48
|
||||
22 3
|
||||
22 4
|
||||
22 5
|
||||
22 6
|
||||
22 8
|
||||
22 25
|
||||
22 26
|
||||
22 19
|
||||
22 21
|
||||
47 36
|
||||
47 1
|
||||
47 48
|
||||
23 18
|
||||
23 21
|
||||
23 30
|
||||
48 36
|
||||
25 26
|
||||
25 28
|
||||
25 19
|
||||
26 28
|
||||
28 3
|
||||
28 4
|
||||
28 5
|
||||
28 6
|
||||
28 7
|
||||
28 8
|
||||
28 27
|
||||
29 3
|
||||
29 4
|
||||
29 5
|
||||
29 6
|
||||
29 7
|
||||
29 8
|
||||
29 25
|
||||
29 26
|
||||
29 28
|
|
@ -0,0 +1,359 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#include "nodeset.h"
|
||||
|
||||
#define DEBUG_INSERT 0
|
||||
#define DEBUG_MERGE 1
|
||||
|
||||
#define DEBUG (DEBUG_INSERT | DEBUG_MERGE)
|
||||
|
||||
/**
|
||||
*
|
||||
* LIST OPERATIONS
|
||||
*
|
||||
*/
|
||||
|
||||
NodeSetList_t nodesetlist_create(){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void nodesetlist_destroy(NodeSetList_t * list){
|
||||
/* FIXME : delete all elements of the list with ptr */
|
||||
NodeSetItem_t * ptr = *list;
|
||||
if (ptr != NULL) {
|
||||
if (ptr->next != NULL){
|
||||
nodesetlist_destroy(&(ptr->next));
|
||||
ptr->next = NULL;
|
||||
} else {
|
||||
// on est le dernier, on se détruit
|
||||
nodesetitem_destroy(ptr); // DESTROY OK
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool nodesetlist_contains_node(NodeSetList_t list, nodeindex_t node_idx){
|
||||
NodeSetItem_t * curptr = list;
|
||||
bool answer = false;
|
||||
while (curptr != NULL){
|
||||
if (nodesetitem_contains_node(curptr, node_idx)) {
|
||||
answer = true;
|
||||
break;
|
||||
}
|
||||
curptr = curptr->next;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
NodeSetList_t nodesetlist_insert_node(NodeSetList_t list, nodeindex_t node_idx)
|
||||
{
|
||||
NodeSetList_t head = list;
|
||||
/* on crée un élément pour le noeud */
|
||||
NodeSetItem_t * item = nodesetitem_create_from_node(node_idx);
|
||||
/*
|
||||
* char * str = nodesetitem_tostr(item);
|
||||
* printf("Created nodesetitem %s\n",str);
|
||||
* free(str);
|
||||
*/
|
||||
head = nodesetlist_insert_item(head, item);
|
||||
nodesetitem_destroy(item);
|
||||
return head;
|
||||
}
|
||||
|
||||
|
||||
NodeSetList_t nodesetlist_insert_item(NodeSetList_t root,
|
||||
NodeSetItem_t * item)
|
||||
{
|
||||
bool action_done = false;
|
||||
NodeSetList_t head = root;
|
||||
// on insere de façon triée...
|
||||
NodeSetItem_t * prevptr = NULL;
|
||||
NodeSetItem_t * curptr = root;
|
||||
char * curstr = NULL;
|
||||
char * itemstr = nodesetitem_tostr(item);
|
||||
|
||||
while(curptr != NULL){
|
||||
|
||||
curstr = nodesetitem_tostr(curptr);
|
||||
|
||||
if (nodesetitem_is_overlap(curptr, item)){
|
||||
pDEBUG("OVERLAP %s vs %s\n", curstr, itemstr);
|
||||
/* on fusionne les deux... cf SNAP*/
|
||||
NodeSetItem_t * newptr =
|
||||
nodesetitem_create_from_bounds(curptr, item);
|
||||
|
||||
curptr->minimum = newptr->minimum;
|
||||
curptr->maximum = newptr->maximum;
|
||||
|
||||
/*
|
||||
* char * str = nodesetitem_tostr(curptr);
|
||||
* printf("=> %s\n",str);
|
||||
* free(str);
|
||||
*/
|
||||
|
||||
nodesetitem_destroy(newptr);
|
||||
|
||||
action_done = true;
|
||||
break;
|
||||
}
|
||||
else if (nodesetitem_is_snap(curptr, item))
|
||||
{
|
||||
pDEBUG("SNAP %s vs %s\n", curstr, itemstr);
|
||||
/* on fusionne les deux... cf OVERLAP*/
|
||||
NodeSetItem_t * newptr =
|
||||
nodesetitem_create_from_bounds(curptr, item);
|
||||
|
||||
curptr->minimum = newptr->minimum;
|
||||
curptr->maximum = newptr->maximum;
|
||||
|
||||
/*
|
||||
* char * str = nodesetitem_tostr(curptr);
|
||||
* printf("=> %s\n",str);
|
||||
* free(str);
|
||||
*/
|
||||
|
||||
nodesetitem_destroy(newptr);
|
||||
|
||||
action_done = true;
|
||||
break;
|
||||
}
|
||||
else if (curptr->minimum > item->maximum) {
|
||||
/* alors on insère le noeud ici... */
|
||||
NodeSetItem_t * newptr = nodesetitem_copy(item);
|
||||
if (NULL == curptr->prev)
|
||||
{ /* on est en tete de liste */
|
||||
newptr->next = head;
|
||||
if (head){ head->prev = newptr; }
|
||||
head = newptr;
|
||||
}
|
||||
else
|
||||
{ /* on est en milieu de liste */
|
||||
prevptr->next = newptr;
|
||||
newptr->prev = prevptr;
|
||||
newptr->next = curptr;
|
||||
curptr->prev = newptr;
|
||||
}
|
||||
|
||||
action_done = true;
|
||||
break;
|
||||
} else {
|
||||
pDEBUG("Rien en commun : %s vs %s\n", curstr, itemstr);
|
||||
// on va ajouter à la fin ?
|
||||
}
|
||||
|
||||
prevptr = curptr;
|
||||
curptr = curptr->next;
|
||||
|
||||
free(curstr);
|
||||
curstr = NULL;
|
||||
}
|
||||
if (head == NULL){
|
||||
NodeSetItem_t * newptr = nodesetitem_copy(item);
|
||||
head = newptr;
|
||||
action_done = true;
|
||||
}
|
||||
|
||||
if (!action_done){
|
||||
pDEBUG("On ajoute %s a la fin de la nodesetlist\n",itemstr);
|
||||
NodeSetItem_t * newptr = nodesetitem_copy(item);
|
||||
if (NULL != prevptr) { prevptr->next = newptr; } // n'arrive jamais
|
||||
newptr->prev = prevptr;
|
||||
}
|
||||
|
||||
if (NULL != curstr) { free(curstr); }
|
||||
if (NULL != itemstr) { free(itemstr); }
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
NodeSetList_t nodesetlist_merge(NodeSetList_t one, NodeSetList_t two){
|
||||
NodeSetList_t result = nodesetlist_create();
|
||||
|
||||
NodeSetItem_t * curptr;
|
||||
|
||||
if (DEBUG_MERGE){
|
||||
pDEBUG("MERGING NODESETLIST\n");
|
||||
nodesetlist_display(one);
|
||||
}
|
||||
|
||||
curptr = one;
|
||||
while (curptr != NULL){
|
||||
/*
|
||||
* str = nodesetitem_tostr(curptr);
|
||||
* printf("Copying... %s\n", str);
|
||||
* free(str);
|
||||
*/
|
||||
result = nodesetlist_insert_item (result, curptr);
|
||||
curptr = curptr->next;
|
||||
}
|
||||
|
||||
if (DEBUG_MERGE){
|
||||
pDEBUG("AND\n");
|
||||
nodesetlist_display(two);
|
||||
}
|
||||
|
||||
curptr = two;
|
||||
while (curptr != NULL){
|
||||
/*
|
||||
* str = nodesetitem_tostr(curptr);
|
||||
* printf("Copying... %s\n", str);
|
||||
* free(str);
|
||||
*/
|
||||
result = nodesetlist_insert_item (result, curptr);
|
||||
curptr = curptr->next;
|
||||
}
|
||||
|
||||
if (DEBUG_MERGE){
|
||||
pDEBUG("GIVES\n");
|
||||
nodesetlist_display(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void nodesetlist_display(NodeSetList_t list)
|
||||
{
|
||||
|
||||
printf("NodeSetList = {\n");
|
||||
NodeSetItem_t * curptr = list;
|
||||
while(curptr != NULL){
|
||||
char * set = nodesetitem_tostr(curptr);
|
||||
printf("\t%s, \n",set);
|
||||
free(set);
|
||||
curptr = curptr->next;
|
||||
}
|
||||
printf("}\n");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* ITEM OPERATIONS
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
NodeSetItem_t * nodesetitem_create(){
|
||||
NodeSetItem_t * node = (NodeSetItem_t *) malloc (sizeof(NodeSetItem_t));
|
||||
node->next = NULL;
|
||||
node->prev = NULL;
|
||||
node->minimum = -1;
|
||||
node->maximum = -1;
|
||||
return node;
|
||||
}
|
||||
|
||||
NodeSetItem_t * nodesetitem_create_from_node(nodeindex_t node_idx){
|
||||
NodeSetItem_t * node = nodesetitem_create();
|
||||
node->minimum = node_idx;
|
||||
node->maximum = node_idx;
|
||||
return node;
|
||||
}
|
||||
|
||||
NodeSetItem_t * nodesetitem_copy(NodeSetItem_t * original){
|
||||
NodeSetItem_t * result = nodesetitem_create();
|
||||
result->minimum = original->minimum;
|
||||
result->maximum = original->maximum;
|
||||
return result;
|
||||
}
|
||||
|
||||
void nodesetitem_destroy(NodeSetItem_t * root){
|
||||
root->prev = NULL;
|
||||
root->next = NULL;
|
||||
free(root);
|
||||
root = NULL;
|
||||
}
|
||||
|
||||
|
||||
bool nodesetitem_contains_node(NodeSetItem_t * item, nodeindex_t node_idx){
|
||||
if ((item->minimum <= node_idx) && (item->maximum >= node_idx)){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool nodesetitem_is_overlap(NodeSetItem_t * one, NodeSetItem_t * two){
|
||||
bool answer = false;
|
||||
if (
|
||||
(
|
||||
(one->minimum <= two->minimum) // om <= tm <= oM
|
||||
&& (one->maximum >= two->minimum)
|
||||
)
|
||||
|| (
|
||||
(one->minimum <= two->maximum) // om <= tM <= oM
|
||||
&& (one->maximum >= two->maximum)
|
||||
)
|
||||
|| (
|
||||
(two->minimum <= one->minimum) // tm <= om <= tM
|
||||
&& (two->maximum >= one->minimum)
|
||||
)
|
||||
|| (
|
||||
(two->minimum <= one->maximum) // tm <= oM <= tM
|
||||
&& (two->maximum >= one->maximum)
|
||||
)
|
||||
)
|
||||
{
|
||||
answer = true;
|
||||
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
bool nodesetitem_is_snap(NodeSetItem_t * one, NodeSetItem_t * two){
|
||||
bool answer = false;
|
||||
if ((one->maximum + 1) == two->minimum){
|
||||
answer = true;
|
||||
} else if ((two->maximum +1) == one->minimum){
|
||||
answer = true;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
char * nodesetitem_tostr(NodeSetItem_t * root){
|
||||
char * str = (char *) malloc (sizeof(char) * 100);
|
||||
sprintf(str,"[ %ld .. %ld ]", root->minimum, root->maximum);
|
||||
return str;
|
||||
}
|
||||
|
||||
NodeSetItem_t * nodesetitem_create_from_bounds(NodeSetItem_t * one,
|
||||
NodeSetItem_t * two){
|
||||
NodeSetItem_t * result;
|
||||
result = nodesetitem_create();
|
||||
result->minimum =
|
||||
(one->minimum < two->minimum) ? (one->minimum) : (two->minimum);
|
||||
result->maximum =
|
||||
(one->maximum > two->maximum) ? (one->maximum) : (two->maximum);
|
||||
|
||||
/*
|
||||
* char * str= nodesetitem_tostr(result);
|
||||
* printf("CREATING FROM BOUNDS -> %s\n", str);
|
||||
* free(str);
|
||||
*/
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
NodeSetList_t nodesetlist_insert_edge(NodeSetList_t list,
|
||||
nodeindex_t from,
|
||||
nodeindex_t to)
|
||||
{
|
||||
NodeSetList_t head = list;
|
||||
NodeSetItem_t * edgeset_from;
|
||||
NodeSetItem_t * edgeset_to;
|
||||
|
||||
printf("INSERTING EDGE (%ld - %ld)\n",from, to);
|
||||
|
||||
if (NULL == list){
|
||||
printf("Empty set");
|
||||
edgeset_from = nodesetitem_create_from_node(from);
|
||||
head = nodesetlist_insert_item(head, edgeset_from); /* edgeset_from may have been deleted */
|
||||
|
||||
edgeset_to = nodesetitem_create_from_node (to);
|
||||
head = nodesetlist_insert_item(head, edgeset_to); /* edgeset_to may have been deleted */
|
||||
} else {
|
||||
#warning "NODESETLIST_INSERT_EDGE NOT IMPLEMENTED FOR LIST!=NULL"
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
#undef DEBUG_INSERT
|
||||
#undef DEBUG_MERGE
|
||||
#undef DEBUG
|
|
@ -0,0 +1,70 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#ifndef _GYR_EDGESET_H
|
||||
#define _GYR_EDGESET_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "units.h"
|
||||
#include "config.h"
|
||||
|
||||
typedef struct _NodeSetItem_t NodeSetItem_t;
|
||||
typedef struct _NodeSetItem_t * NodeSetList_t;
|
||||
|
||||
struct _NodeSetItem_t {
|
||||
nodeindex_t minimum;
|
||||
nodeindex_t maximum;
|
||||
|
||||
NodeSetItem_t * next;
|
||||
NodeSetItem_t * prev;
|
||||
} ;
|
||||
|
||||
/* List opts */
|
||||
NodeSetList_t nodesetlist_create ();
|
||||
|
||||
void nodesetlist_destroy (NodeSetList_t * list);
|
||||
|
||||
bool nodesetlist_contains_node (NodeSetList_t list, nodeindex_t node_idx);
|
||||
|
||||
NodeSetList_t nodesetlist_insert_node (NodeSetList_t list, nodeindex_t node_idx);
|
||||
|
||||
NodeSetList_t nodesetlist_insert_item (NodeSetList_t root,
|
||||
NodeSetItem_t * item);
|
||||
|
||||
NodeSetList_t nodesetlist_merge(NodeSetList_t one, NodeSetList_t two);
|
||||
|
||||
void nodesetlist_display(NodeSetList_t list);
|
||||
|
||||
|
||||
/* Item opts */
|
||||
/* nodesetitem*/
|
||||
NodeSetItem_t * nodesetitem_create ();
|
||||
|
||||
NodeSetItem_t * nodesetitem_copy (NodeSetItem_t * one);
|
||||
|
||||
NodeSetItem_t * nodesetitem_create_from_node (nodeindex_t node_idx);
|
||||
|
||||
NodeSetItem_t * nodesetitem_create_from_bounds (NodeSetItem_t * one,
|
||||
NodeSetItem_t * two);
|
||||
|
||||
void nodesetitem_destroy (NodeSetItem_t * node);
|
||||
|
||||
bool nodesetitem_is_snap (NodeSetItem_t * one, NodeSetItem_t * two);
|
||||
|
||||
bool nodesetitem_is_overlap (NodeSetItem_t * one, NodeSetItem_t * two);
|
||||
|
||||
bool nodesetitem_contains_node (NodeSetItem_t * item, nodeindex_t node_idx);
|
||||
|
||||
char * nodesetitem_tostr (NodeSetItem_t * root);
|
||||
|
||||
NodeSetItem_t * nodeset_insert_node (NodeSetItem_t * root,
|
||||
NodeSetItem_t * node);
|
||||
|
||||
|
||||
/* edgeset */
|
||||
NodeSetItem_t * edgeset_insert_edge(NodeSetItem_t * edgeset, nodeindex_t from, nodeindex_t to);
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,7 @@
|
|||
NOTE 1:
|
||||
je pensais que l'appel de fonction/méthode causait la lenteur en C++
|
||||
cependant, en déplaçant le code appellé en lieu et place du code appelant,
|
||||
on obtient aucun gain...
|
||||
|
||||
NOTE 2:
|
||||
avec le mode BIDIRECT on gagne une seconde...
|
|
@ -0,0 +1,21 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#include "progressindicator.h"
|
||||
|
||||
char * progress_indicator(){
|
||||
char * result;
|
||||
static int prog = 0;
|
||||
int max = 1200;
|
||||
prog = prog % max;
|
||||
if (prog < (max/4)){
|
||||
result = progress_indicator_table[0];
|
||||
} else if (prog < (max/2)) {
|
||||
result = progress_indicator_table[1];
|
||||
} else if (prog < ((3 * max)/4)) {
|
||||
result = progress_indicator_table[2];
|
||||
} else {
|
||||
result = progress_indicator_table[3];
|
||||
}
|
||||
prog += 1;
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef _PROGESS_INDICATOR_H
|
||||
#define _PROGESS_INDICATOR_H
|
||||
|
||||
static char* progress_indicator_table[] = {
|
||||
"[|]",
|
||||
"[/]",
|
||||
"[-]",
|
||||
"[\\]"
|
||||
};
|
||||
|
||||
char * progress_indicator();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,758 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "units.h"
|
||||
#include "store.h"
|
||||
|
||||
#include "degree.h"
|
||||
|
||||
#include "progressindicator.h"
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
/**
|
||||
* Constructeur de l'objet
|
||||
* @param io Configuration des flux d'entrée/sortie
|
||||
* @param size Nombre de noeuds
|
||||
* @return Pointeur sur la structure de l'objet
|
||||
*/
|
||||
|
||||
Store_t * store_create(Config_io_t * io, nodeindex_t size)
|
||||
{
|
||||
Store_t * store = (Store_t *) malloc (sizeof(Store_t));
|
||||
|
||||
store->_io = io;
|
||||
store->_size = size;
|
||||
store->_show_output = true;
|
||||
|
||||
store->_mod_degree = STORE_MODIF_UNDEF;
|
||||
store->_mod_value = STORE_MODIF_UNDEF;
|
||||
store->_mod_value2 = STORE_MODIF_UNDEF;
|
||||
store->_mod_ref = STORE_MODIF_UNDEF;
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destructeur de l'objet passé en paramètre.
|
||||
* @param store Pointeur sur la structure de l'objet
|
||||
*/
|
||||
|
||||
void store_destroy(Store_t * store){
|
||||
free(store->_thetable);
|
||||
free(store->_refs);
|
||||
free(store);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixe le mode d'affichage (silencieux ou pas)
|
||||
*/
|
||||
|
||||
void store_set_output(Store_t * store, bool output){
|
||||
store->_show_output = output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ré-initilaise les données EXTRA du Store_t
|
||||
*
|
||||
* @param store Pointeur sur l'objet Store_t manipulé
|
||||
*/
|
||||
|
||||
void store_reset(Store_t * store, store_reset_t mode){
|
||||
nodeindex_t i;
|
||||
for (i = 0; i < store->_size; i++){
|
||||
if (mode & STORE_RESET_DEGREE) {
|
||||
store->_refs[i][STORE_EXTRA_DEGREE] = 0; // default degree
|
||||
}
|
||||
if (mode & STORE_RESET_VALUE) {
|
||||
store->_refs[i][STORE_EXTRA_VALUE] = NODEINDEX_UNDEF; // current seach
|
||||
}
|
||||
if (mode & STORE_RESET_VALUE2) {
|
||||
store->_refs[i][STORE_EXTRA_VALUE2] = NODEINDEX_UNDEF; // current seach
|
||||
}
|
||||
if (mode & STORE_RESET_REF) {
|
||||
store->_refs[i][STORE_EXTRA_REF] = NODEINDEX_UNDEF; // node reference in DFS
|
||||
}
|
||||
}
|
||||
if (mode & STORE_RESET_DEGREE){
|
||||
pDEBUG("reset STORE_RESET_DEGREE\n");
|
||||
store->_mod_degree = STORE_MODIF_RESET;
|
||||
}
|
||||
if (mode & STORE_RESET_VALUE){
|
||||
pDEBUG("reset STORE_RESET_VALUE\n");
|
||||
store->_mod_value = STORE_MODIF_RESET;
|
||||
}
|
||||
if (mode & STORE_RESET_VALUE2){
|
||||
pDEBUG("reset STORE_RESET_VALUE2\n");
|
||||
store->_mod_value2 = STORE_MODIF_RESET;
|
||||
}
|
||||
if (mode & STORE_RESET_REF){
|
||||
pDEBUG("reset STORE_RESET_REF\n");
|
||||
store->_mod_ref = STORE_MODIF_RESET;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Génère le modèle du Store_t
|
||||
*
|
||||
* Alloue la mémoire nécessaire en fonction des degrés des noeuds
|
||||
* et initialise les cases aux bonnes valeurs par défaut.
|
||||
*
|
||||
* @param store Pointeur sur l'objet Store_t manipulé
|
||||
* @param degree Pointeur sur l'objet Degree_t fournissant les degrés.
|
||||
*/
|
||||
|
||||
void store_generate_model(Store_t * store, Degree_t * degree){
|
||||
store->_size = degree->_size;
|
||||
|
||||
store->_refs = (nodeindex_t **) malloc (sizeof(nodeindex_t *) * store->_size);
|
||||
|
||||
/* should be initialized to 1 instead of 0 else causes erroneous memory
|
||||
* read/write, but why ?
|
||||
* FIXME: find the bug... */
|
||||
nodeindex_t tablesize = 1;
|
||||
|
||||
nodeindex_t i;
|
||||
|
||||
for (i = 0; i < store->_size; i++){
|
||||
/* extra infos + index size (degree) */
|
||||
tablesize += degree_get (degree, i) + STORE_EXTRAPLACE;
|
||||
}
|
||||
|
||||
store->_thetable = (nodeindex_t *) malloc (sizeof(nodeindex_t) * tablesize);
|
||||
|
||||
|
||||
nodeindex_t ref = 1;
|
||||
for (i = 0; i < store->_size; i++){
|
||||
store->_refs[i] = (nodeindex_t*) (store->_thetable + ref);
|
||||
ref += degree_get (degree, i) + STORE_EXTRAPLACE;
|
||||
}
|
||||
|
||||
store_reset (store, STORE_RESET_ALL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enregistre une valeur (sémantique arbitraire) dans le noeud choisi
|
||||
*
|
||||
* @param store Pointeur sur l'objet Store_t manipulé
|
||||
* @param node_index Index du noeud choisi dans le Store_t
|
||||
* @param value Valeur a enregistrer
|
||||
*/
|
||||
|
||||
void store_set_value(Store_t * store, nodeindex_t node_index, nodeindex_t value){
|
||||
assert(store->_mod_value == STORE_MODIF_BEGIN);
|
||||
pDEBUG("setting value-one %ld at %ld\n", value, node_index);
|
||||
store->_refs[node_index][STORE_EXTRA_VALUE] = value;
|
||||
}
|
||||
|
||||
void store_set_value_2(Store_t * store, nodeindex_t node_index, nodeindex_t value){
|
||||
assert(store->_mod_value2 == STORE_MODIF_BEGIN);
|
||||
pDEBUG("setting value-two %ld at %ld\n", value, node_index);
|
||||
store->_refs[node_index][STORE_EXTRA_VALUE2] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lit la valeur (sémantique arbitraire) dans le noeud choisi
|
||||
*
|
||||
* @param store Pointeur sur l'objet Store_t manipulé
|
||||
* @param node_index Index du noeud choisi dans le Store_t
|
||||
*/
|
||||
|
||||
nodeindex_t store_get_value(Store_t * store, nodeindex_t from){
|
||||
return store->_refs[from][STORE_EXTRA_VALUE];
|
||||
}
|
||||
|
||||
|
||||
nodeindex_t store_get_value_2(Store_t * store, nodeindex_t from){
|
||||
return store->_refs[from][STORE_EXTRA_VALUE2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enregistrer dans un noeud la référence à un autre noeud
|
||||
*
|
||||
* @param store Pointeur sur l'objet Store_t manipulé
|
||||
* @param node_index Index du noeud choisi dans le Store_t
|
||||
* @param index_value Index du noeud référencé dans le Store_t
|
||||
*/
|
||||
|
||||
void store_set_ref(Store_t * store, nodeindex_t node_index, nodeindex_t index_value){
|
||||
assert(store->_mod_ref == STORE_MODIF_BEGIN);
|
||||
pDEBUG("index %ld / value %ld\n", node_index, index_value);
|
||||
store->_refs[node_index][STORE_EXTRA_REF] = index_value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Lit la référence contenue dans le noeud choisi
|
||||
*
|
||||
* @param store Pointeur sur l'objet Store_t manipulé
|
||||
* @param node_index Index du noeud choisi dans le Store_t
|
||||
*/
|
||||
|
||||
nodeindex_t store_get_ref(Store_t * store, nodeindex_t from){
|
||||
return store->_refs[from][STORE_EXTRA_REF];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ajoute un arc vers un autre noeud au noeud choisi
|
||||
*
|
||||
* @param store Pointeur sur l'objet Store_t manipulé
|
||||
* @param from Index du noeud choisi dans le Store_t
|
||||
* @param to Index du noeud destination (de l'arc) dans le Store_t
|
||||
*/
|
||||
|
||||
#undef DEBUG
|
||||
#define DEBUG 0
|
||||
void store_add_adjacent(Store_t * store, nodeindex_t from, nodeindex_t to){
|
||||
pDEBUG("from = %ld to =%ld\n", from, to);
|
||||
assert( from < store->_size);
|
||||
assert( from >= 0);
|
||||
assert( to < store->_size);
|
||||
assert( to >= 0);
|
||||
assert(store->_mod_degree == STORE_MODIF_BEGIN);
|
||||
|
||||
nodeindex_t from_degree = store_get_degree (store, from);
|
||||
nodeindex_t redir = STORE_EXTRAPLACE + from_degree;
|
||||
store->_refs[from][redir] = to;
|
||||
store->_refs[from][STORE_EXTRA_DEGREE] = from_degree + 1; /* increment degree */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Trouve l'index du noeud cherché dans la liste d'ajacence du noeud choisi
|
||||
*/
|
||||
|
||||
#undef DEBUG
|
||||
#define DEBUG 0
|
||||
nodeindex_t store_find_adjacent (Store_t * store, nodeindex_t from, nodeindex_t to){
|
||||
nodeindex_t cur;
|
||||
|
||||
nodeindex_t result = NODEINDEX_UNDEF;
|
||||
|
||||
nodeindex_t from_degree = store_get_degree (store, from);
|
||||
nodeindex_t redir;
|
||||
|
||||
pDEBUG("Degree [ %ld ] = %ld\n", from, from_degree);
|
||||
for (cur = 0; cur < from_degree; cur++){
|
||||
redir = STORE_EXTRAPLACE + cur;
|
||||
if (store->_refs[from][redir] == to){
|
||||
result = cur;
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void store_display_adjacent (Store_t * store, nodeindex_t from){
|
||||
nodeindex_t cur;
|
||||
|
||||
nodeindex_t from_degree = store_get_degree (store, from);
|
||||
printf("%ld -> [ ", from);
|
||||
for (cur = 0; cur < from_degree; cur++){
|
||||
nodeindex_t redir = STORE_EXTRAPLACE + cur;
|
||||
|
||||
printf("%ld ",store->_refs[from][redir]);
|
||||
}
|
||||
printf("]\n");
|
||||
}
|
||||
/**
|
||||
* Retire l'arc vers un autre noeud, à partir du noeud choisi
|
||||
*
|
||||
*/
|
||||
|
||||
void store_del_adjacent(Store_t * store, nodeindex_t from, nodeindex_t to){
|
||||
nodeindex_t idx = store_find_adjacent (store, from, to);
|
||||
|
||||
if (idx == NODEINDEX_UNDEF){
|
||||
printf("Adjacent %ld non trouvé dans la liste de %ld!\n", to, from);
|
||||
store_display_adjacent(store, from);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// on décale tous les suivants de 1, et on décrémente le degré
|
||||
nodeindex_t from_degree = store_get_degree (store, from);
|
||||
nodeindex_t cur;
|
||||
for (cur = idx; cur < (from_degree - 1); cur++){
|
||||
nodeindex_t redir = STORE_EXTRAPLACE + cur;
|
||||
store->_refs[from][redir] = store->_refs[from][redir + 1];
|
||||
store->_refs[from][redir + 1] = NODEINDEX_UNDEF;
|
||||
}
|
||||
store->_refs[from][STORE_EXTRA_DEGREE] = from_degree - 1; /* increment degree */
|
||||
}
|
||||
|
||||
/**
|
||||
* Supprime le noeud choisi
|
||||
*/
|
||||
|
||||
void store_del_node (Store_t * store, nodeindex_t from){
|
||||
// on visite tous les adjacents,
|
||||
// et on leur dit de supprimer le noeud courant de leur liste...
|
||||
|
||||
pDEBUG("Deleting node %ld\n", from);
|
||||
nodeindex_t from_degree = store_get_degree (store, from);
|
||||
|
||||
nodeindex_t cur;
|
||||
store_display_adjacent(store, from);
|
||||
for (cur = 0; cur < from_degree; cur++){
|
||||
nodeindex_t redir = STORE_EXTRAPLACE + cur;
|
||||
nodeindex_t adj = store->_refs[from][redir];
|
||||
store->_refs[from][redir] = NODEINDEX_UNDEF;
|
||||
|
||||
pDEBUG(" - Removing adjacent %ld from %ld\n", from, adj);
|
||||
store_display_adjacent(store, adj);
|
||||
// supprimer le noeud courrant de la liste d'adjacence de ses voisins
|
||||
store_del_adjacent(store, adj, from);
|
||||
store_display_adjacent(store, adj);
|
||||
|
||||
}
|
||||
// on anihile le noeud...
|
||||
store->_refs[from][STORE_EXTRA_DEGREE] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
nodeindex_t store_get_adjacent(Store_t * store, nodeindex_t from, nodeindex_t index){
|
||||
nodeindex_t result;
|
||||
|
||||
assert(index < store->_refs[from][STORE_EXTRA_DEGREE]);
|
||||
result = store->_refs[from][STORE_EXTRAPLACE + index];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Lit le degré du noeud choisi
|
||||
*
|
||||
* @param store Pointeur sur l'objet Store_t manipulé
|
||||
* @param node_index Index du noeud choisi dans le Store_t
|
||||
*/
|
||||
|
||||
nodeindex_t store_get_degree (Store_t * store, nodeindex_t from){
|
||||
nodeindex_t result;
|
||||
|
||||
result = store->_refs[from][STORE_EXTRA_DEGREE];
|
||||
return result;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
double store_compute_avg_degree(Store_t * store, int iterations){
|
||||
double average_sum;
|
||||
double average_avg;
|
||||
|
||||
nodeindex_t cur;
|
||||
nodeindex_t rand_node = (nodeindex_t)(random() % store->_size);
|
||||
for(cur = 0; cur < iterations; cur++){
|
||||
nodeindex_t rand_node = (nodeindex_t)(random()) % store->_size;
|
||||
fprintf(stderr, "Selecting node %ld\n", rand_node);
|
||||
|
||||
average_sum += store_get_degree(store, rand_node);
|
||||
average_avg = average_sum / (cur + 1);
|
||||
fprintf(store->_io->output, "%ld %lf\n", cur, average_avg);
|
||||
}
|
||||
}
|
||||
|
||||
void store_init_from_degrees (Store_t * store, Degree_t * degree){
|
||||
store->_mod_value = STORE_MODIF_BEGIN;
|
||||
nodeindex_t cur_node;
|
||||
for (cur_node = 0; cur_node < store->_size; cur_node++){
|
||||
nodeindex_t cur_deg = degree_get (degree, cur_node);
|
||||
printf("\r%s Degree = %ld for node %ld... ", progress_indicator(), cur_deg, cur_node);
|
||||
store_set_value(store, cur_node, cur_deg);
|
||||
}
|
||||
store->_mod_value = STORE_MODIF_END;
|
||||
}
|
||||
|
||||
void store_fill_from_random_graph (Store_t * store, nodeindex_t edge_count){
|
||||
assert(store->_mod_degree == STORE_MODIF_RESET);
|
||||
|
||||
store->_mod_degree = STORE_MODIF_BEGIN;
|
||||
store->_mod_value = STORE_MODIF_BEGIN;
|
||||
|
||||
nodeindex_t cur_node;
|
||||
nodeindex_t cur_deg;
|
||||
|
||||
printf("Filling 'remaining degrees' %ld...\n", store->_size);
|
||||
|
||||
/*
|
||||
|
||||
// on remplit les "remaining degree" dans les VALUES du store
|
||||
for (cur_node = 0; cur_node < store->_size; cur_node++){
|
||||
nodeindex_t cur_deg = store_get_degree(store, cur_node);
|
||||
store_set_value(store, cur_node, cur_deg);
|
||||
}
|
||||
*/
|
||||
|
||||
nodeindex_t nb_edges = 0;
|
||||
|
||||
printf("Filling random nodes %ld...\n", store->_size);
|
||||
for (cur_node = 0; cur_node < store->_size; cur_node++){
|
||||
// on lit le degré du noeud
|
||||
nodeindex_t src_deg = store_get_value(store, cur_node);
|
||||
|
||||
while(src_deg > 0){
|
||||
printf("r_degree[ %ld ] => %ld = ?\n", cur_node, src_deg);
|
||||
// choisir un autre noeud au pif
|
||||
bool choix_is_bad;
|
||||
nodeindex_t dest_node;
|
||||
do {
|
||||
dest_node = rand() % store->_size;
|
||||
choix_is_bad = false;
|
||||
|
||||
// on vérifie que le noeud dest est différent du noeud source
|
||||
if (dest_node == cur_node){ choix_is_bad = true; }
|
||||
|
||||
// on vérifie qu'il reste des places disponibles dans le noeud
|
||||
// visé...
|
||||
nodeindex_t dest_remaining_deg = store_get_value(store, dest_node);
|
||||
if (dest_remaining_deg <= 0){ choix_is_bad = true; }
|
||||
|
||||
// vérifier que le noeud n'est pas _deja_ dans les adjacents...
|
||||
nodeindex_t dest_deg = store_get_degree(store, dest_node);
|
||||
nodeindex_t inf_deg;
|
||||
|
||||
for (inf_deg = 0; inf_deg < dest_deg; inf_deg++){
|
||||
printf("Checking adjacent %ld of node %ld\n", inf_deg, dest_node);
|
||||
// lire les numéros des noeuds afin de vérifier
|
||||
// si les adjacents ne contiennent pas le noeud source
|
||||
if (store_get_adjacent(store, dest_node, inf_deg) == cur_node){
|
||||
choix_is_bad = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(choix_is_bad);
|
||||
|
||||
// on ajoute un lien vers le noeud à partir de ce noeud,
|
||||
// puis l'inverse...
|
||||
store_add_adjacent(store, cur_node, dest_node);
|
||||
store_add_adjacent(store, dest_node, cur_node);
|
||||
nb_edges += 1;
|
||||
|
||||
printf("Adding edge from %ld to %ld\n", cur_node, dest_node);
|
||||
|
||||
nodeindex_t dest_deg;
|
||||
// décrémenter le nombre de dispo sur la destination
|
||||
dest_deg = store_get_value (store, dest_node);
|
||||
assert(dest_deg > 0);
|
||||
store_set_value (store, dest_node, dest_deg - 1);
|
||||
printf("r_degree[ %ld ] => %ld = ?\n", dest_node, dest_deg - 1 );
|
||||
|
||||
|
||||
// décrementer le nombre de dispo sur la source
|
||||
src_deg = src_deg - 1;
|
||||
store_set_value (store, cur_node, src_deg);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialise la structure du store à partir d'une premiere
|
||||
* lecture des degrés des noeuds dans le fichier
|
||||
*
|
||||
* ATTENTION: modifie STORE_EXTRA_DEGREE (ok)
|
||||
*
|
||||
* @param store Pointeur sur l'objet Store_t manipulé
|
||||
*/
|
||||
|
||||
void store_init_from_input_graph(Store_t * store){
|
||||
/* on interdit de re-remplir un tableau qui aurait déja été
|
||||
* rempli. L'utilisateur n'avait qu'a faire attention a ses
|
||||
* données... */
|
||||
assert(store->_mod_degree == STORE_MODIF_UNDEF);
|
||||
|
||||
Degree_t * degree = degree_create (store->_io,
|
||||
store->_size,
|
||||
MODE_DEGREE);
|
||||
degree_set_output (degree, false);
|
||||
degree_fill_from_input_graph (degree);
|
||||
|
||||
// on allocate la mémoire du tableau
|
||||
store_generate_model(store, degree);
|
||||
degree_destroy(degree);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remplit le store à partir des informations d'adjacence contenues
|
||||
* dans le fichier.
|
||||
*
|
||||
* ATTENTION: modifie STORE_EXTRA_DEGREE (ok)
|
||||
* FIXME: penser a découper la premiere partie dans une fonction à part
|
||||
*
|
||||
* @param store Pointeur sur l'objet Store_t manipulé
|
||||
*/
|
||||
|
||||
void store_fill_from_input_graph(Store_t * store){
|
||||
store_init_from_input_graph(store);
|
||||
|
||||
/* on interdit de remplit autre chose qu'un tableau propre
|
||||
* au niveau des degrés */
|
||||
assert(store->_mod_degree == STORE_MODIF_RESET);
|
||||
|
||||
store->_mod_degree = STORE_MODIF_BEGIN;
|
||||
|
||||
//int len;
|
||||
char * buf = (char *) malloc (sizeof(char) * 100);
|
||||
char * buf2;
|
||||
nodeindex_t counter = 0;
|
||||
nodeindex_t one, two;
|
||||
int re;
|
||||
|
||||
gzrewind(store->_io->input);
|
||||
gzclearerr(store->_io->input);
|
||||
|
||||
fprintf(stderr,"\r Filling the big table from file data...");
|
||||
|
||||
for (;;){
|
||||
// fprintf(stderr,"\r%s", progress_indicator());
|
||||
if (gzeof(store->_io->input)){ break; }
|
||||
|
||||
buf2 = gzgets(store->_io->input, buf, 100);
|
||||
if (buf2 == Z_NULL){
|
||||
pDEBUG("READ OFF\n");
|
||||
break;
|
||||
} else {
|
||||
counter++;
|
||||
re = sscanf(buf, "%ld %ld", &one, &two);
|
||||
//printf("Add from %d to %d\n", one, two);
|
||||
store_add_adjacent(store, one, two);
|
||||
store_add_adjacent(store, two, one);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
|
||||
store->_mod_degree = STORE_MODIF_END;
|
||||
|
||||
free (buf);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indique si la visite du noeud est terminée
|
||||
*
|
||||
* ATTENTION: utilise STORE_EXTRA_REF (ok)
|
||||
*
|
||||
* @param store Pointeur sur l'objet Store_t manipulé
|
||||
* @return bool TRUE si le noeud a été visité
|
||||
*/
|
||||
|
||||
bool store_is_visit_done(Store_t * store, nodeindex_t index){
|
||||
assert((store->_mod_ref == STORE_MODIF_RESET)
|
||||
|| (store->_mod_ref == STORE_MODIF_END));
|
||||
|
||||
return (store->_refs[index][STORE_EXTRA_REF] != NODEINDEX_UNDEF);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indique si la visite du noeud n'a pas été faite
|
||||
*
|
||||
* ATTENTION: utilise STORE_EXTRA_REF (ok)
|
||||
*
|
||||
* @param store Pointeur sur l'objet Store_t manipulé
|
||||
* @return bool TRUE si le noeud a été visité
|
||||
*/
|
||||
|
||||
bool store_is_visit_undone(Store_t * store, nodeindex_t index){
|
||||
assert((store->_mod_ref == STORE_MODIF_RESET)
|
||||
|| (store->_mod_ref == STORE_MODIF_END));
|
||||
|
||||
return (store->_refs[index][STORE_EXTRA_REF] == NODEINDEX_UNDEF);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Visite récursivement le noeud pour un parcours en profondeur
|
||||
*
|
||||
* ATTENTION: utilise STORE_EXTRA_DEGREE (ok)
|
||||
*
|
||||
* ATTENTION: utilise STORE_EXTRA_REF (ok)
|
||||
* ATTENTION: modifie STORE_EXTRA_REF (ok)
|
||||
*
|
||||
* @param store Pointeur sur l'objet Store_t manipulé
|
||||
* @param cur_idx Index du noeud par lequel commencer
|
||||
* @param reference Index du noeud père
|
||||
*/
|
||||
|
||||
void store_visit_node(Store_t * store,
|
||||
nodeindex_t cur_idx,
|
||||
nodeindex_t reference,
|
||||
Fifo_t * fifo_cc )
|
||||
{
|
||||
/* on oblige l'initialisation des degrés */
|
||||
assert(store->_mod_degree == STORE_MODIF_END);
|
||||
|
||||
/* on oblige l'utilisateur a indiquer qu'il est entrain de faire
|
||||
* des modifications sur STORE_EXTRA_REF */
|
||||
assert(store->_mod_ref == STORE_MODIF_BEGIN);
|
||||
|
||||
pDEBUG("store_visit_node -- %ld \n",cur_idx);
|
||||
if (fifo_cc){ fifo_push (fifo_cc, cur_idx); }
|
||||
store->_refs[cur_idx][STORE_EXTRA_REF] = reference;
|
||||
/* pour chacun des noeuds visitables, on visite... */
|
||||
nodeindex_t adj_pos = 0;
|
||||
|
||||
for (adj_pos = 0; adj_pos < store_get_degree (store, cur_idx); adj_pos++){
|
||||
nodeindex_t adj_idx = store->_refs[cur_idx][STORE_EXTRAPLACE + adj_pos];
|
||||
|
||||
store_modif_t mod_ref_status = store->_mod_ref;
|
||||
store->_mod_ref = STORE_MODIF_END;
|
||||
bool is_undone = store_is_visit_undone(store, adj_idx);
|
||||
pDEBUG("visit of %ld %s\n", adj_idx, (is_undone?"undone":"done"));
|
||||
store->_mod_ref = mod_ref_status;
|
||||
|
||||
if (is_undone){
|
||||
/* alors on visite... */
|
||||
store_visit_node(store, adj_idx, cur_idx, fifo_cc);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Trouve l'index du premier noeud non visité (en partant du noeud indiqué)
|
||||
*
|
||||
* ATTENTION: utilise STORE_EXTRA_REF (ok)
|
||||
*
|
||||
* @param store Pointeur sur l'objet Store_t manipulé
|
||||
* @param index Indique le noeud de départ dans la recherche
|
||||
*/
|
||||
|
||||
nodeindex_t store_find_undone(Store_t * store, nodeindex_t index){
|
||||
assert((store->_mod_ref == STORE_MODIF_RESET)
|
||||
|| (store->_mod_ref == STORE_MODIF_END));
|
||||
nodeindex_t first_idx;
|
||||
for (first_idx = index; first_idx < store->_size; first_idx++){
|
||||
if (store_is_visit_undone(store, first_idx)){ break; }
|
||||
}
|
||||
if (first_idx == store->_size){ first_idx = NODEINDEX_UNDEF; }
|
||||
return first_idx;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Trouve les composantes connexes dans le graphe représenté par le Store_t
|
||||
*
|
||||
* ATTENTION: modifie STORE_EXTRA_REF (ok)
|
||||
*
|
||||
* @param store Pointeur sur l'objet Store_t manipulé
|
||||
* @param fifo_indexes File contenant les noeuds de référence des composantes
|
||||
* connexes
|
||||
*/
|
||||
|
||||
void store_connexity(Store_t * store, Fifo_t * fifo_indexes){
|
||||
nodeindex_t first_idx = 0;
|
||||
nodeindex_t counter = 0;
|
||||
|
||||
assert(store->_mod_ref == STORE_MODIF_RESET);
|
||||
|
||||
|
||||
while(first_idx != NODEINDEX_UNDEF){
|
||||
first_idx = store_find_undone (store, first_idx);
|
||||
|
||||
store->_mod_ref = STORE_MODIF_BEGIN;
|
||||
|
||||
if (first_idx != NODEINDEX_UNDEF){
|
||||
if (fifo_indexes) { fifo_push(fifo_indexes, first_idx); }
|
||||
counter++;
|
||||
if (store->_show_output){
|
||||
pDEBUG(" ");
|
||||
fprintf (store->_io->output, "Found connex component at %ld\n", first_idx);
|
||||
}
|
||||
if (store->_io->verbose){ printf ("store_connexity -- = { \n"); }
|
||||
|
||||
// visit with no ancestors
|
||||
store_visit_node (store, first_idx, NODEINDEX_ROOT, NULL);
|
||||
|
||||
if (store->_io->verbose){ printf ("store_connexity -- }\n"); }
|
||||
}
|
||||
store->_mod_ref = STORE_MODIF_END;
|
||||
}
|
||||
|
||||
|
||||
if (store->_show_output){
|
||||
pDEBUG(" ");
|
||||
fprintf (store->_io->output, "Found %ld connex components\n", counter);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remplit la file passée en parametre avec les noeuds de la composante
|
||||
* connexe contenant le noeud de référence.
|
||||
*
|
||||
* ATTENTION: utilise STORE_EXTRA_DEGREE (ok)
|
||||
*
|
||||
* ATTENTION: modifie STORE_EXTRA_REF (ok)
|
||||
*
|
||||
* @param store Pointeur sur l'objet Store_t manipulé
|
||||
* @param from Index du noeud de référence
|
||||
* @param fifo_cc Pointeur sur la file a remplir
|
||||
*/
|
||||
|
||||
void store_fill_cc_from_node(Store_t * store, nodeindex_t from, Fifo_t * fifo_cc ){
|
||||
/* on oblige a avoir défini les degrés */
|
||||
assert(store->_mod_degree == STORE_MODIF_END);
|
||||
|
||||
// on ré-initialise le store
|
||||
store_reset (store, STORE_RESET_REF);
|
||||
|
||||
store->_mod_ref = STORE_MODIF_BEGIN;
|
||||
|
||||
// on parcourt en profondeur le store a partir du noeud en question
|
||||
/* on cherche les noeuds visités et on les ajoute a la liste */
|
||||
store_visit_node (store, from, from, fifo_cc);
|
||||
|
||||
store->_mod_ref = STORE_MODIF_END;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Trouve la composante connexe a laquelle appartient le noeud donné.
|
||||
*
|
||||
* ATTENTION: utilise STORE_EXTRA_REF (ok)
|
||||
*
|
||||
* @param store Pointeur sur l'objet Store_t manipulé
|
||||
* @param node Noeud dont on cherche la composante connexe
|
||||
* @return L'index du noeud de référence de la composante connexe
|
||||
*/
|
||||
|
||||
nodeindex_t store_find_cc_of_node(Store_t * store, nodeindex_t node){
|
||||
/* on oblige a avoir défini les références */
|
||||
assert(store->_mod_ref == STORE_MODIF_END);
|
||||
|
||||
// on remonte de référence en référence...
|
||||
pDEBUG("find cc of node %ld\n", node);
|
||||
while(node != store_get_ref(store, node)){
|
||||
node = store_get_ref(store, node);
|
||||
}
|
||||
pDEBUG("cc is %ld\n", node);
|
||||
return node;
|
||||
}
|
||||
|
||||
#undef DEBUG
|
|
@ -0,0 +1,91 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#ifndef _GYR_STORE_H
|
||||
#define _GYR_STORE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
|
||||
|
||||
#include "units.h"
|
||||
#include "config.h"
|
||||
#include "degree.h"
|
||||
#include "fifo.h"
|
||||
|
||||
typedef enum {
|
||||
STORE_RESET_DEGREE = 1,
|
||||
STORE_RESET_VALUE = 2,
|
||||
STORE_RESET_VALUE2 = 4,
|
||||
STORE_RESET_REF = 8,
|
||||
STORE_RESET_ALL = 15
|
||||
} store_reset_t;
|
||||
|
||||
typedef enum {
|
||||
STORE_MODIF_UNDEF = 0,
|
||||
STORE_MODIF_RESET = 1,
|
||||
STORE_MODIF_BEGIN = 2,
|
||||
STORE_MODIF_END = 3
|
||||
} store_modif_t;
|
||||
|
||||
typedef struct {
|
||||
Config_io_t * _io;
|
||||
|
||||
nodeindex_t ** _refs;
|
||||
nodeindex_t * _thetable;
|
||||
nodeindex_t _size;
|
||||
|
||||
store_modif_t _mod_degree;
|
||||
store_modif_t _mod_value;
|
||||
store_modif_t _mod_value2;
|
||||
store_modif_t _mod_ref;
|
||||
|
||||
bool _show_output;
|
||||
} Store_t;
|
||||
|
||||
|
||||
Store_t * store_create(Config_io_t * io, nodeindex_t size);
|
||||
|
||||
void store_destroy(Store_t * store);
|
||||
|
||||
void store_fill(Store_t * store);
|
||||
|
||||
void store_set_output(Store_t * store, bool output);
|
||||
|
||||
void store_add_adjacent(Store_t * store, nodeindex_t from, nodeindex_t to);
|
||||
|
||||
nodeindex_t store_get_degree(Store_t * store, nodeindex_t from);
|
||||
|
||||
nodeindex_t store_get_adjacent(Store_t * store, nodeindex_t from, nodeindex_t index);
|
||||
|
||||
void store_set_value(Store_t * store, nodeindex_t from, nodeindex_t val);
|
||||
|
||||
void store_set_value_2(Store_t * store, nodeindex_t from, nodeindex_t val);
|
||||
|
||||
void store_init_from_degrees (Store_t * store, Degree_t * degree);
|
||||
|
||||
void store_fill_from_random_degree (Store_t * store, nodeindex_t edge_count);
|
||||
|
||||
nodeindex_t store_get_ref(Store_t * store, nodeindex_t from);
|
||||
|
||||
nodeindex_t store_get_value(Store_t * store, nodeindex_t from);
|
||||
|
||||
nodeindex_t store_get_value_2(Store_t * store, nodeindex_t from);
|
||||
|
||||
void store_del_node (Store_t * store, nodeindex_t from);
|
||||
|
||||
void store_set_ref(Store_t * store, nodeindex_t from, nodeindex_t val);
|
||||
|
||||
bool store_is_visit_done(Store_t * store, nodeindex_t index);
|
||||
|
||||
bool store_is_visit_undone(Store_t * store, nodeindex_t index);
|
||||
|
||||
void store_visit_node(Store_t * store, nodeindex_t index, nodeindex_t reference, Fifo_t * fifo_cc);
|
||||
|
||||
void store_connexity(Store_t * store, Fifo_t * fifo_indexes);
|
||||
void store_reset(Store_t * store, store_reset_t mode);
|
||||
|
||||
void store_fill_cc_from_node(Store_t * store, nodeindex_t from, Fifo_t * fifo_cc );
|
||||
|
||||
#endif
|
|
@ -0,0 +1 @@
|
|||
./alobe -N -i by_hand.0.10 -c 10 -r 3 -n 1 -o -
|
|
@ -0,0 +1 @@
|
|||
./alobe -N -i by_hand.0.11 -c 11 -r 0 -n 1 -o -
|
|
@ -0,0 +1 @@
|
|||
./alobe -N -i by_hand.0.9 -c 9 -r 4 -n 1 -o -
|
|
@ -0,0 +1,72 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#include "fifo.h"
|
||||
|
||||
int main(){
|
||||
Fifo_t * fifo = fifo_create(20);
|
||||
Fifo_t * fifo2;
|
||||
|
||||
nodeindex_t i;
|
||||
nodeindex_t before, after;
|
||||
printf("\n************************************************************************\n");
|
||||
printf(" PHASE 1 (fill with 0..19)\n");
|
||||
printf("************************************************************************\n");
|
||||
|
||||
for (i=0; i<20; i++){
|
||||
before = fifo_get_size(fifo);
|
||||
fifo_push (fifo, i);
|
||||
after = fifo_get_size(fifo);
|
||||
printf("Pushed %ld\n", i);
|
||||
printf("Fifo size %ld -> %ld\n", before, after);
|
||||
}
|
||||
|
||||
fifo_display (fifo);
|
||||
|
||||
printf("\n************************************************************************\n");
|
||||
printf(" PHASE 2 (move 5 to back)\n");
|
||||
printf("************************************************************************\n");
|
||||
|
||||
for (i=0; i<5; i++){
|
||||
nodeindex_t tmp;
|
||||
tmp = fifo_pop(fifo);
|
||||
fifo_push(fifo, tmp);
|
||||
}
|
||||
|
||||
fifo_display (fifo);
|
||||
|
||||
printf("\n************************************************************************\n");
|
||||
printf(" PHASE 3 (reverse)\n");
|
||||
printf("************************************************************************\n");
|
||||
|
||||
fifo_reverse (fifo);
|
||||
fifo_display (fifo);
|
||||
|
||||
|
||||
printf("\n************************************************************************\n");
|
||||
printf(" PHASE 4 (copy)\n");
|
||||
printf("************************************************************************\n");
|
||||
|
||||
fifo2 = fifo_copy (fifo);
|
||||
fifo_destroy (fifo);
|
||||
fifo = fifo2;
|
||||
fifo2 = NULL;
|
||||
|
||||
fifo_display (fifo);
|
||||
|
||||
printf("\n************************************************************************\n");
|
||||
printf(" PHASE 5 (pop everything)\n");
|
||||
printf("************************************************************************\n");
|
||||
while (!fifo_is_empty(fifo)){
|
||||
before = fifo_get_size(fifo);
|
||||
nodeindex_t val = fifo_pop (fifo);
|
||||
after = fifo_get_size(fifo);
|
||||
printf("Popped %ld\n", val);
|
||||
printf("Fifo size %ld -> %ld\n", before, after);
|
||||
}
|
||||
|
||||
fifo_display (fifo);
|
||||
|
||||
fifo_destroy (fifo);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
/* vim: set sw=4 ts=4 si et: */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "list.h"
|
||||
|
||||
int * int_create(int value){
|
||||
int * var = ((int*) malloc (sizeof(int)));
|
||||
*var = value;
|
||||
return var;
|
||||
}
|
||||
|
||||
void int_destroy(void * daInt){
|
||||
int * truc = daInt;
|
||||
free(truc);
|
||||
}
|
||||
|
||||
int main(){
|
||||
List_t * list = list_create();
|
||||
int * value, * final;
|
||||
int z;
|
||||
|
||||
printf("************************************************************************\n");
|
||||
printf(" PHASE 1 - Creation and base test (push_back)\n");
|
||||
printf("************************************************************************\n");
|
||||
|
||||
assert(list_is_empty(list) == true);
|
||||
|
||||
value = int_create(1);
|
||||
printf ("Test push_back value %d\n",*value);
|
||||
list_push_back (list, value);
|
||||
|
||||
final = list_back(list);
|
||||
printf ("Test back (%d)\n",*final);
|
||||
assert ((*final) == 1);
|
||||
|
||||
final = list_pop_back(list);
|
||||
printf ("Test pop_back (%d)\n",*final);
|
||||
assert ((*final) == 1);
|
||||
int_destroy (final);
|
||||
|
||||
final = list_pop_back(list);
|
||||
printf ("Test pop_back on empty\n");
|
||||
assert (final == NULL);
|
||||
|
||||
printf("************************************************************************\n");
|
||||
printf(" PHASE 2 - Multiple (non-equal) push and pop\n");
|
||||
printf("************************************************************************\n");
|
||||
|
||||
for (z=0; z<100; z++){
|
||||
value = int_create(z);
|
||||
list_push_back (list, value);
|
||||
}
|
||||
for (z=0; z<100; z++){
|
||||
final = list_pop_back(list);
|
||||
int_destroy (final);
|
||||
}
|
||||
|
||||
final = list_pop_back(list);
|
||||
printf ("Test pop_back on empty\n");
|
||||
assert (final == NULL);
|
||||
|
||||
printf("************************************************************************\n");
|
||||
printf(" PHASE 3 - Empty destroy test\n");
|
||||
printf("************************************************************************\n");
|
||||
printf("Test destroy with data\n");
|
||||
list_destroy_with_data(list, int_destroy);
|
||||
|
||||
printf("************************************************************************\n");
|
||||
printf(" PHASE 4 - Creation and base test (push_front)\n");
|
||||
printf("************************************************************************\n");
|
||||
list = list_create();
|
||||
value = int_create(1);
|
||||
printf ("Test push_front value %d\n",*value);
|
||||
list_push_front (list, value);
|
||||
value = int_create(2);
|
||||
list_push_front (list, value);
|
||||
|
||||
final = list_front(list);
|
||||
printf ("Test front (%d)\n",*final);
|
||||
assert ((*final) == 2);
|
||||
|
||||
final = list_back(list);
|
||||
printf ("Test back (%d)\n",*final);
|
||||
assert ((*final) == 1);
|
||||
|
||||
final = list_pop_front(list);
|
||||
printf ("Test pop_front (%d)\n",*final);
|
||||
assert ((*final) == 2);
|
||||
int_destroy (final);
|
||||
|
||||
// FIXME: on ne devrait pouvoir dire rien d'intéressant ici, le null n'est pas
|
||||
// obligatoire...
|
||||
//final = list_pop_front(list);
|
||||
//printf ("Test pop_front on empty\n");
|
||||
//assert (final == NULL);
|
||||
|
||||
printf("************************************************************************\n");
|
||||
printf("PHASE 5 - ...\n");
|
||||
printf("************************************************************************\n");
|
||||
|
||||
for (z=0; z<100; z++){
|
||||
value = int_create(z);
|
||||
list_push_front (list, value);
|
||||
}
|
||||
for (z=0; z<100; z++){
|
||||
final = list_pop_front(list);
|
||||
int_destroy (final);
|
||||
}
|
||||
|
||||
/*
|
||||
printf ("Test pop_front on empty\n");
|
||||
final = list_pop_front(list);
|
||||
assert (final == NULL);
|
||||
*/
|
||||
|
||||
printf("Test destroy with data\n");
|
||||
list_destroy_with_data(list, int_destroy);
|
||||
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
# Filter the file 1
|
||||
# filter the file 2
|
||||
|
||||
INPUT=$1
|
||||
OUTPUT=$2
|
||||
|
||||
TMP_FILE_INF=/tmp/plot.inf.$$.$RANDOM
|
||||
TMP_FILE_AVG=/tmp/plot.avg.$$.$RANDOM
|
||||
TMP_FILE_SUP=/tmp/plot.sup.$$.$RANDOM
|
||||
TMP_FILE_PLOT=/tmp/plot.plot.$$.$RANDOM
|
||||
|
||||
|
||||
if [ -f "$INPUT" ]; then
|
||||
echo $TMP_FILE_INF
|
||||
echo $TMP_FILE_SUP
|
||||
echo $TMP_FILE_AVG
|
||||
echo $TMP_FILE_PLOT
|
||||
|
||||
cat $INPUT | grep inf | sed 's/inf //' > $TMP_FILE_INF
|
||||
cat $INPUT | grep avg | sed 's/avg //' > $TMP_FILE_AVG
|
||||
cat $INPUT | grep sup | sed 's/sup //' > $TMP_FILE_SUP
|
||||
|
||||
echo "plot \"$TMP_FILE_INF\" title \"Borne Inferieure\" w lines, \\" > $TMP_FILE_PLOT
|
||||
echo " \"$TMP_FILE_AVG\" title \"Distance Moyenne\" w steps, \\" >> $TMP_FILE_PLOT
|
||||
echo " \"$TMP_FILE_SUP\" title \"Borne Superieure\" w linespoints" >> $TMP_FILE_PLOT
|
||||
|
||||
if [ "$OUTPUT" != "" ]; then
|
||||
echo "set out \"$OUTPUT\"" >> $TMP_FILE_PLOT
|
||||
echo "set terminal postscript \\" >> $TMP_FILE_PLOT
|
||||
echo " landscape enhanced color lw 2 \"Helvetica\" 14" >> $TMP_FILE_PLOT
|
||||
echo "replot" >> $TMP_FILE_PLOT
|
||||
fi
|
||||
|
||||
|
||||
gnuplot -persist $TMP_FILE_PLOT
|
||||
|
||||
rm -f $TMP_FILE_INF
|
||||
rm -f $TMP_FILE_AVG
|
||||
rm -f $TMP_FILE_SUP
|
||||
rm -f $TMP_FILE_PLOT
|
||||
|
||||
else
|
||||
echo "Usage : defiplot defi.plot [output.ps]"
|
||||
fi
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/bash
|
||||
echo "plot \"$1\" with lines" | gnuplot -persist
|
|
@ -0,0 +1 @@
|
|||
sort -k1,1n -k2,2n
|
|
@ -0,0 +1,555 @@
|
|||
0 1
|
||||
0 2
|
||||
1 3
|
||||
1 4
|
||||
1 5
|
||||
1 6
|
||||
1 7
|
||||
1 8
|
||||
1 9
|
||||
1 10
|
||||
1 11
|
||||
1 12
|
||||
1 13
|
||||
1 14
|
||||
1 15
|
||||
1 16
|
||||
1 17
|
||||
1 18
|
||||
1 19
|
||||
1 20
|
||||
1 21
|
||||
1 22
|
||||
1 23
|
||||
1 24
|
||||
1 25
|
||||
1 26
|
||||
1 27
|
||||
1 28
|
||||
1 29
|
||||
1 30
|
||||
27 31
|
||||
27 32
|
||||
27 33
|
||||
27 34
|
||||
27 35
|
||||
27 36
|
||||
27 37
|
||||
27 38
|
||||
27 39
|
||||
27 40
|
||||
27 41
|
||||
27 42
|
||||
27 43
|
||||
27 44
|
||||
27 45
|
||||
27 46
|
||||
27 47
|
||||
27 48
|
||||
9 49
|
||||
9 50
|
||||
9 51
|
||||
2 52
|
||||
2 53
|
||||
2 54
|
||||
2 55
|
||||
2 56
|
||||
2 57
|
||||
2 58
|
||||
2 59
|
||||
2 60
|
||||
2 61
|
||||
2 62
|
||||
2 63
|
||||
2 64
|
||||
2 65
|
||||
2 66
|
||||
2 67
|
||||
2 68
|
||||
2 69
|
||||
2 70
|
||||
2 71
|
||||
2 72
|
||||
2 73
|
||||
2 74
|
||||
2 75
|
||||
2 76
|
||||
2 77
|
||||
2 78
|
||||
2 79
|
||||
2 80
|
||||
2 81
|
||||
2 82
|
||||
2 83
|
||||
2 84
|
||||
2 85
|
||||
2 86
|
||||
2 87
|
||||
2 88
|
||||
2 89
|
||||
2 90
|
||||
2 91
|
||||
2 92
|
||||
2 93
|
||||
2 94
|
||||
2 95
|
||||
2 96
|
||||
2 97
|
||||
2 98
|
||||
2 99
|
||||
2 100
|
||||
2 101
|
||||
2 102
|
||||
2 103
|
||||
2 104
|
||||
2 105
|
||||
2 106
|
||||
2 107
|
||||
2 108
|
||||
2 109
|
||||
2 110
|
||||
2 111
|
||||
2 112
|
||||
2 113
|
||||
2 114
|
||||
2 115
|
||||
2 116
|
||||
2 117
|
||||
2 118
|
||||
2 119
|
||||
2 120
|
||||
2 121
|
||||
2 122
|
||||
2 123
|
||||
2 124
|
||||
2 125
|
||||
2 126
|
||||
2 127
|
||||
56 128
|
||||
56 129
|
||||
54 130
|
||||
54 131
|
||||
54 132
|
||||
52 133
|
||||
52 134
|
||||
63 135
|
||||
63 136
|
||||
63 137
|
||||
3 4
|
||||
3 5
|
||||
3 6
|
||||
3 7
|
||||
3 8
|
||||
3 138
|
||||
3 24
|
||||
3 25
|
||||
3 26
|
||||
3 139
|
||||
3 17
|
||||
3 140
|
||||
3 14
|
||||
3 13
|
||||
3 10
|
||||
3 141
|
||||
3 142
|
||||
3 143
|
||||
65 144
|
||||
65 145
|
||||
65 146
|
||||
65 147
|
||||
53 148
|
||||
53 149
|
||||
53 150
|
||||
53 151
|
||||
72 152
|
||||
72 153
|
||||
72 154
|
||||
72 155
|
||||
72 156
|
||||
72 157
|
||||
72 158
|
||||
72 159
|
||||
72 160
|
||||
72 161
|
||||
64 152
|
||||
64 162
|
||||
64 163
|
||||
64 164
|
||||
64 165
|
||||
64 166
|
||||
64 167
|
||||
75 168
|
||||
75 169
|
||||
75 170
|
||||
75 171
|
||||
75 172
|
||||
75 173
|
||||
75 174
|
||||
75 175
|
||||
75 176
|
||||
66 177
|
||||
66 178
|
||||
66 179
|
||||
89 180
|
||||
89 152
|
||||
89 154
|
||||
89 181
|
||||
89 182
|
||||
89 183
|
||||
89 184
|
||||
89 185
|
||||
89 186
|
||||
89 187
|
||||
71 188
|
||||
71 189
|
||||
71 190
|
||||
71 191
|
||||
71 192
|
||||
71 193
|
||||
71 194
|
||||
71 195
|
||||
71 196
|
||||
71 152
|
||||
71 197
|
||||
93 198
|
||||
93 199
|
||||
88 155
|
||||
88 152
|
||||
79 152
|
||||
91 152
|
||||
95 152
|
||||
95 168
|
||||
95 1
|
||||
94 152
|
||||
92 124
|
||||
96 152
|
||||
97 152
|
||||
97 1
|
||||
82 152
|
||||
106 152
|
||||
103 152
|
||||
103 1
|
||||
125 152
|
||||
90 152
|
||||
111 152
|
||||
87 152
|
||||
112 152
|
||||
121 152
|
||||
59 1
|
||||
59 152
|
||||
98 152
|
||||
16 3
|
||||
16 4
|
||||
16 5
|
||||
16 6
|
||||
16 7
|
||||
16 8
|
||||
16 24
|
||||
16 25
|
||||
16 26
|
||||
16 143
|
||||
49 51
|
||||
58 152
|
||||
62 152
|
||||
80 152
|
||||
198 199
|
||||
180 152
|
||||
180 154
|
||||
180 187
|
||||
156 155
|
||||
156 154
|
||||
156 153
|
||||
133 152
|
||||
69 152
|
||||
120 152
|
||||
4 5
|
||||
4 6
|
||||
4 7
|
||||
4 8
|
||||
4 24
|
||||
4 25
|
||||
4 26
|
||||
4 15
|
||||
4 143
|
||||
162 152
|
||||
31 24
|
||||
31 33
|
||||
31 34
|
||||
31 35
|
||||
31 36
|
||||
31 44
|
||||
31 45
|
||||
31 46
|
||||
31 47
|
||||
31 48
|
||||
31 1
|
||||
31 43
|
||||
50 51
|
||||
134 152
|
||||
5 6
|
||||
5 7
|
||||
5 8
|
||||
5 24
|
||||
5 25
|
||||
5 26
|
||||
5 19
|
||||
5 18
|
||||
5 20
|
||||
5 139
|
||||
5 143
|
||||
32 31
|
||||
32 33
|
||||
32 34
|
||||
32 35
|
||||
32 36
|
||||
32 43
|
||||
32 44
|
||||
32 45
|
||||
32 46
|
||||
32 47
|
||||
32 48
|
||||
6 7
|
||||
6 8
|
||||
6 24
|
||||
6 25
|
||||
6 26
|
||||
6 143
|
||||
33 34
|
||||
33 35
|
||||
33 36
|
||||
33 43
|
||||
33 44
|
||||
33 45
|
||||
33 46
|
||||
33 47
|
||||
33 48
|
||||
147 146
|
||||
7 8
|
||||
7 24
|
||||
7 25
|
||||
7 26
|
||||
7 22
|
||||
7 21
|
||||
7 19
|
||||
7 18
|
||||
7 17
|
||||
7 143
|
||||
34 35
|
||||
34 36
|
||||
34 43
|
||||
34 44
|
||||
34 45
|
||||
34 46
|
||||
34 47
|
||||
34 48
|
||||
35 36
|
||||
35 1
|
||||
35 43
|
||||
35 44
|
||||
35 45
|
||||
35 46
|
||||
35 47
|
||||
35 48
|
||||
8 24
|
||||
8 25
|
||||
8 26
|
||||
8 143
|
||||
10 4
|
||||
10 5
|
||||
10 6
|
||||
10 7
|
||||
10 8
|
||||
10 24
|
||||
10 25
|
||||
10 26
|
||||
10 139
|
||||
10 17
|
||||
10 140
|
||||
10 143
|
||||
36 23
|
||||
36 43
|
||||
167 166
|
||||
176 169
|
||||
176 95
|
||||
176 171
|
||||
176 170
|
||||
176 173
|
||||
176 174
|
||||
11 59
|
||||
11 143
|
||||
12 59
|
||||
38 39
|
||||
38 40
|
||||
39 40
|
||||
39 1
|
||||
13 4
|
||||
13 5
|
||||
13 6
|
||||
13 7
|
||||
13 8
|
||||
13 24
|
||||
13 25
|
||||
13 26
|
||||
13 14
|
||||
13 143
|
||||
14 4
|
||||
14 5
|
||||
14 6
|
||||
14 7
|
||||
14 8
|
||||
14 24
|
||||
14 25
|
||||
14 26
|
||||
14 139
|
||||
14 17
|
||||
14 140
|
||||
14 143
|
||||
15 3
|
||||
15 5
|
||||
15 6
|
||||
15 7
|
||||
15 8
|
||||
15 24
|
||||
15 25
|
||||
15 26
|
||||
15 143
|
||||
17 4
|
||||
17 5
|
||||
17 6
|
||||
17 8
|
||||
17 24
|
||||
17 25
|
||||
17 26
|
||||
17 139
|
||||
17 140
|
||||
17 142
|
||||
17 143
|
||||
18 3
|
||||
18 4
|
||||
18 6
|
||||
18 8
|
||||
18 24
|
||||
18 25
|
||||
18 26
|
||||
18 19
|
||||
18 22
|
||||
18 143
|
||||
43 24
|
||||
43 1
|
||||
43 30
|
||||
43 44
|
||||
43 45
|
||||
43 46
|
||||
43 47
|
||||
43 48
|
||||
44 36
|
||||
44 3
|
||||
44 45
|
||||
44 46
|
||||
44 47
|
||||
44 48
|
||||
20 3
|
||||
20 4
|
||||
20 6
|
||||
20 7
|
||||
20 8
|
||||
20 24
|
||||
20 25
|
||||
20 26
|
||||
20 143
|
||||
45 36
|
||||
45 46
|
||||
45 47
|
||||
45 48
|
||||
46 36
|
||||
46 47
|
||||
46 48
|
||||
22 3
|
||||
22 4
|
||||
22 5
|
||||
22 6
|
||||
22 143
|
||||
22 8
|
||||
22 24
|
||||
22 25
|
||||
22 26
|
||||
22 19
|
||||
22 21
|
||||
47 36
|
||||
47 1
|
||||
47 48
|
||||
23 138
|
||||
23 18
|
||||
23 21
|
||||
23 143
|
||||
23 30
|
||||
48 36
|
||||
24 25
|
||||
24 26
|
||||
24 28
|
||||
25 26
|
||||
25 28
|
||||
25 139
|
||||
25 140
|
||||
25 19
|
||||
25 143
|
||||
26 28
|
||||
26 143
|
||||
28 3
|
||||
28 4
|
||||
28 5
|
||||
28 6
|
||||
28 7
|
||||
28 8
|
||||
28 27
|
||||
28 143
|
||||
29 3
|
||||
29 4
|
||||
29 5
|
||||
29 6
|
||||
29 7
|
||||
29 8
|
||||
29 24
|
||||
29 25
|
||||
29 26
|
||||
29 28
|
||||
29 143
|
||||
139 4
|
||||
139 6
|
||||
139 7
|
||||
139 8
|
||||
139 24
|
||||
139 26
|
||||
139 140
|
||||
139 13
|
||||
139 143
|
||||
140 4
|
||||
140 5
|
||||
140 6
|
||||
140 7
|
||||
140 8
|
||||
140 24
|
||||
140 26
|
||||
140 9
|
||||
140 143
|
||||
141 4
|
||||
141 5
|
||||
141 6
|
||||
141 7
|
||||
141 8
|
||||
141 24
|
||||
141 25
|
||||
141 26
|
||||
141 14
|
||||
141 143
|
||||
142 4
|
||||
142 5
|
||||
142 6
|
||||
142 7
|
||||
142 8
|
||||
142 24
|
||||
142 25
|
||||
142 26
|
||||
142 139
|
||||
142 140
|
||||
142 143
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -0,0 +1,21 @@
|
|||
0 0
|
||||
1 7787
|
||||
2 34612
|
||||
3 78012
|
||||
4 118064
|
||||
5 132409
|
||||
6 119996
|
||||
7 90643
|
||||
8 58481
|
||||
9 32729
|
||||
10 16671
|
||||
11 7486
|
||||
12 3037
|
||||
13 1128
|
||||
14 418
|
||||
15 126
|
||||
16 42
|
||||
17 12
|
||||
18 0
|
||||
19 0
|
||||
20 1
|
|
@ -0,0 +1,100 @@
|
|||
0 1
|
||||
10 12
|
||||
20 22
|
||||
30 33
|
||||
40 43
|
||||
50 53
|
||||
60 66
|
||||
70 78
|
||||
80 88
|
||||
90 99
|
||||
100 109
|
||||
110 119
|
||||
120 129
|
||||
130 140
|
||||
140 150
|
||||
150 160
|
||||
160 170
|
||||
170 181
|
||||
180 191
|
||||
190 201
|
||||
200 212
|
||||
210 222
|
||||
220 232
|
||||
230 242
|
||||
240 252
|
||||
250 263
|
||||
260 274
|
||||
270 285
|
||||
280 295
|
||||
290 305
|
||||
300 315
|
||||
310 326
|
||||
320 337
|
||||
330 347
|
||||
340 357
|
||||
350 368
|
||||
360 378
|
||||
370 388
|
||||
380 398
|
||||
390 409
|
||||
400 419
|
||||
410 430
|
||||
420 440
|
||||
430 450
|
||||
440 460
|
||||
450 470
|
||||
460 480
|
||||
470 490
|
||||
480 500
|
||||
490 511
|
||||
500 521
|
||||
510 531
|
||||
520 542
|
||||
530 553
|
||||
540 564
|
||||
550 575
|
||||
560 586
|
||||
570 596
|
||||
580 606
|
||||
590 616
|
||||
600 627
|
||||
610 637
|
||||
620 648
|
||||
630 658
|
||||
640 668
|
||||
650 678
|
||||
660 688
|
||||
670 700
|
||||
680 711
|
||||
690 722
|
||||
700 734
|
||||
710 745
|
||||
720 756
|
||||
730 766
|
||||
740 776
|
||||
750 786
|
||||
760 796
|
||||
770 806
|
||||
780 816
|
||||
790 826
|
||||
800 836
|
||||
810 847
|
||||
820 857
|
||||
830 867
|
||||
840 877
|
||||
850 888
|
||||
860 899
|
||||
870 909
|
||||
880 919
|
||||
890 929
|
||||
900 939
|
||||
910 950
|
||||
920 960
|
||||
930 970
|
||||
940 980
|
||||
950 990
|
||||
960 1000
|
||||
970 1010
|
||||
980 1020
|
||||
990 1031
|
|
@ -0,0 +1,100 @@
|
|||
0 970
|
||||
10 1058
|
||||
20 1116
|
||||
30 1148
|
||||
40 1186
|
||||
50 3164
|
||||
60 3181
|
||||
70 5589
|
||||
80 5666
|
||||
90 5693
|
||||
100 6307
|
||||
110 7543
|
||||
120 7559
|
||||
130 9436
|
||||
140 10780
|
||||
150 11432
|
||||
160 11523
|
||||
170 12103
|
||||
180 13031
|
||||
190 13073
|
||||
200 13101
|
||||
210 13622
|
||||
220 15476
|
||||
230 15524
|
||||
240 16375
|
||||
250 16807
|
||||
260 16829
|
||||
270 17246
|
||||
280 17567
|
||||
290 18388
|
||||
300 20095
|
||||
310 20488
|
||||
320 20560
|
||||
330 21052
|
||||
340 21445
|
||||
350 22525
|
||||
360 23259
|
||||
370 23474
|
||||
380 23825
|
||||
390 24074
|
||||
400 24132
|
||||
410 24243
|
||||
420 24319
|
||||
430 25663
|
||||
440 26289
|
||||
450 26585
|
||||
460 26867
|
||||
470 26905
|
||||
480 27424
|
||||
490 27947
|
||||
500 29720
|
||||
510 30353
|
||||
520 31274
|
||||
530 32002
|
||||
540 33204
|
||||
550 33792
|
||||
560 33809
|
||||
570 34350
|
||||
580 35203
|
||||
590 35723
|
||||
600 36534
|
||||
610 37216
|
||||
620 38241
|
||||
630 38533
|
||||
640 38923
|
||||
650 39661
|
||||
660 39918
|
||||
670 40431
|
||||
680 40707
|
||||
690 40962
|
||||
700 41220
|
||||
710 41936
|
||||
720 42637
|
||||
730 43116
|
||||
740 43383
|
||||
750 43603
|
||||
760 43614
|
||||
770 43862
|
||||
780 44082
|
||||
790 44422
|
||||
800 44538
|
||||
810 44715
|
||||
820 45058
|
||||
830 45648
|
||||
840 45878
|
||||
850 46149
|
||||
860 46351
|
||||
870 47336
|
||||
880 47988
|
||||
890 48116
|
||||
900 48477
|
||||
910 48593
|
||||
920 48968
|
||||
930 49382
|
||||
940 50015
|
||||
950 50543
|
||||
960 51422
|
||||
970 51956
|
||||
980 52362
|
||||
990 53035
|
|
@ -0,0 +1,58 @@
|
|||
#ifndef _GYR_UNITS_H
|
||||
#define _GYR_UNITS_H
|
||||
|
||||
#define bool short
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
typedef long nodeindex_t;
|
||||
|
||||
/* place 0 = degree
|
||||
* place 1 = current subnode visit index
|
||||
* place 2 = node reference
|
||||
*/
|
||||
|
||||
#define COLOR_RED "\x1B[31m"
|
||||
#define COLOR_GREEN "\x1B[32m"
|
||||
#define COLOR_YELLOW "\x1B[33m"
|
||||
#define COLOR_NORMAL "\x1B[0m"
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Quelques macros
|
||||
*/
|
||||
|
||||
#define MAX(x, y) ( (x) > (y) ? (x) : (y) )
|
||||
|
||||
#define MIN(x, y) ( (x) > (y) ? (y) : (x) )
|
||||
|
||||
#define pDEBUG(...) if (DEBUG){ \
|
||||
fprintf(stderr, "%s%s%s at %s:%d -- %s",\
|
||||
COLOR_GREEN,\
|
||||
__func__,\
|
||||
COLOR_NORMAL,\
|
||||
__FILE__,\
|
||||
__LINE__,\
|
||||
COLOR_YELLOW); \
|
||||
fprintf(stderr,__VA_ARGS__); \
|
||||
fprintf(stderr,"%s",COLOR_NORMAL); fflush(stderr); }
|
||||
|
||||
#define pnDEBUG(...) if (DEBUG){ \
|
||||
fprintf(stderr,"%s",COLOR_YELLOW); \
|
||||
fprintf(stderr,__VA_ARGS__); \
|
||||
fprintf(stderr,"%s",COLOR_NORMAL); \
|
||||
fflush(stderr); }
|
||||
|
||||
#define STORE_EXTRAPLACE 4
|
||||
#define STORE_EXTRA_DEGREE 0
|
||||
#define STORE_EXTRA_VALUE 1
|
||||
#define STORE_EXTRA_VALUE2 2
|
||||
#define STORE_EXTRA_REF 3
|
||||
|
||||
#define NODEINDEX_UNDEF -1
|
||||
#define NODEINDEX_ROOT -2
|
||||
#define NODEINDEX_RANDOM -2
|
||||
#define NODEINDEX_MAX_CC -3
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue