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:
glenux 2009-05-02 07:36:25 +00:00
commit 5ca782e8b1
73 changed files with 732341 additions and 0 deletions

0
AUTHORS Normal file
View File

1
COPYING Symbolic link
View File

@ -0,0 +1 @@
/usr/share/automake-1.7/COPYING

0
ChangeLog Normal file
View File

1118
Doxyfile Normal file

File diff suppressed because it is too large Load Diff

1
INSTALL Symbolic link
View File

@ -0,0 +1 @@
/usr/share/automake-1.7/INSTALL

5
Makefile.am Normal file
View File

@ -0,0 +1,5 @@
SUBDIRS = src
EXTRA_DIST = doc INSTALL README Doxyfile autogen.sh

0
NEWS Normal file
View File

0
README Normal file
View File

11
autogen.sh Executable file
View File

@ -0,0 +1,11 @@
echo "libtoolize..."
libtoolize
echo "aclocal..."
aclocal
echo "autoheader..."
autoheader
echo "autoconf..."
autoconf
echo "automake..."
automake -a
echo "ok."

218
configure.in Normal file
View File

@ -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

10
doc/enonce.txt Normal file
View File

@ -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

33
doc/index.css Normal file
View File

@ -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;
}

357
doc/tp1.html Normal file
View File

@ -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&eacute;</title>
<meta content="Glenn ROLLAND" name="author">
</head>
<body style="direction: ltr;">
<div style="text-align: justify;" class="page">
<h1>Alob&eacute;</h1>
<h2><a name="1._Description"></a>1.
<a name="Description"></a>Description</h2>
<p>Alob&eacute; est
un&nbsp;logiciel libres permettant de manipuler de grands graphes
non-orient&eacute;s d&eacute;crits par la liste de leurs
arr&ecirc;tes. Il poss&egrave;de les
caract&eacute;ristiques
suivantes :</p>
<ul>
<li>Il est distribu&eacute;
sous la licence&nbsp;<a href="http://www.gnu.org/copyleft/gpl.html">GNU
General Public License</a></li>
<li>Il&nbsp;est
&eacute;crit en C (bien qu'&eacute;crit au d&eacute;part en
C++, comme en t&eacute;moigne le d&eacute;p&ocirc;t
subversion) et poss&egrave;de une interface en ligne
de
commande,</li>
<li>Il impl&eacute;mente le
filtrage du graphe pour l'extraction d'un&nbsp;sous-ensemble
(exercice 2).</li>
<li>Il impl&eacute;mente le
calcul des degr&eacute;s (exercice 3)</li>
<li>Il impl&eacute;mente les
statistiques sur le calcul des degr&eacute;s (degr&eacute;
moyen, degr&eacute; maximum, densit&eacute; du graphe)
(exercice 5)</li>
<li>Il impl&eacute;mente le
stockage des donn&eacute;es de fa&ccedil;on contig&uuml;e
en m&eacute;moire (en un unique tableau) (exercice 4).</li>
<li>Il impl&eacute;mente le
calcul des composantes connexes de fa&ccedil;on efficace (exercice
5).&nbsp;</li>
<li>Il impl&eacute;mente une
m&eacute;thode de calcul alternatif des composantes connexes
(exercice 6 - d&eacute;fi).</li>
</ul>
<h3>1.1.
Auteurs</h3>
<p>Alob&eacute; a
&eacute;t&eacute; enti&egrave;rement
r&eacute;alis&eacute; par Glenn ROLLAND &lt;<a
href="mailto:glenux@fr.st">glenux@fr.st</a>&gt;
&agrave; l'occasion de travaux pratiques du cours de <span
style="font-style: italic;">Grand R&eacute;seaux</span>
du Master 2 Ing&eacute;nierie Informatique
-
Syst&egrave;mes, R&eacute;seaux et Internet.</p>
<h2><a99 name="2._Pr&eacute;-requis">2.
Pr&eacute;-requis</a99></h2>
<p>Alob&eacute;
ne&nbsp;n&eacute;cessite pas de biblioth&egrave;ques de
fonctions
particuli&egrave;res pour fonctionnner.</p>
<h2>3.
Se procurer Alob&eacute;</h2>
Vous
pouvez t&eacute;l&eacute;charger la derni&egrave;re archive
des
sources, ou bien directement la version la plus r&eacute;cente du
projet sur le d&eacute;p&ocirc;t Subversion du projet.<br>
<h3>3.1. L'archive des sources</h3>
Elle est disponible &agrave; 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&eacute;p&ocirc;t Subversion</h3>
<p>Afin d'obtenir les sources les
plus &agrave; jour, vous pouvez utiliser le logiciel de
contr&ocirc;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&eacute;e" pour l'utilisateur "anonymous", si ce dernier vous
est
demand&eacute;.</p>
<h2><a name="4._Utiliser_Alob&eacute;"></a>4.
Utiliser Alob&eacute;</h2>
<h3><a name="4.1._Compilation"></a>4.1.
Compilation</h3>
<p>Commencez par
d&eacute;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'&ecirc;tre cr&eacute;&eacute; lors de
la d&eacute;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>&nbsp;<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&eacute; doivent &ecirc;tre appel&eacute;s
avec la syntaxe suivante:<br>
</div>
<p class="code">Usage:
alobe &lt;commande&gt; &lt;parametres_obligatoires&gt;
[options]<br>
</p>
<p>Les commandes&nbsp;sont
les suivants:</p>
<dl>
<dt>-F, --filter</dt>
<dd>Filtrage du fichier
d'entr&eacute;e pour extraire un sous-graphe.</dd>
<dt> -D, --degree </dt>
<dd>Calcul du degr&eacute;
des noeuds du graphe pris en entr&eacute;e.</dd>
<dt>-S, --store</dt>
<dd>Stockage et remplissage du
tableau repr&eacute;sentant le graphe en m&eacute;moire.</dd>
<dt>-A, --average</dt>
<dd>Calcul des statistiques sur
les noeuds du graphe d'entr&eacute;e (degr&eacute; moyen,
degr&eacute; max, densit&eacute;).</dd>
<dt>-C, --connexity</dt>
<dd>Calcul des composantes
connexes par la m&eacute;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&egrave;tres
obligatoires sont les suivants:</p>
<dl>
<dt>-c, --count &lt;entier&gt; <fichier>
</fichier></dt>
<dd>Nombre de noeuds du fichier d'entr&eacute;e.</dd>
<dt>-s, --size &lt;entier&gt;</dt>
<dd>Taille du filtre</dd>
<dt>-t, --offset &lt;entier&gt;</dt>
<dd>Offset du filtre</dd>
</dl>
<p>Les parames optionnels sont les
suivants:</p>
<dl>
<dt>-i, --input
&lt;fichier&gt;</dt>
<dd> Le fichier
d'entr&eacute;e, "-" d&eacute;signant l'entr&eacute;e
standard,</dd>
<dt>-o, --output
&lt;fichier&gt;</dt>
<dd>Le fichier de sorftie, "-"
d&eacute;signant la sortie standard.</dd>
<dt>-v, --verbose</dt>
<dd> Passe l'affichage en mode
verbeux.e
num&eacute;ro du noeud &agrave; lire et afficher &agrave; partir du
fichier
compress&eacute;</dd>
</dl>
<h2><a name="5._Documentation"></a>5.
Documentation</h2>
<h3>5.1. Code</h3>
<p>Vous pouvez trouver la
documentation de Alob&eacute; 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&eacute;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&eacute;e pour extraire un sous ensemble de noeuds de
la fa&ccedil;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 -&gt; FILTER<br>
Offset -&gt; 0<br>
Size -&gt; 30<br>
Input Data -&gt; ../web.data.gz<br>
Input Index -&gt; 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 &lt;= x &lt; 30 )</p>
<h4>5.2.3. Exercice 3</h4>
<p>Le calcul du degr&eacute; des noeuds se fait par la commande
suivante :</p>
<p class="code">./src/alobe -D&nbsp;-i ../web.data.gz -c 701654</p>
<p class="">Ce qui produit (en premi&egrave;re colone l'index du noeud
et en seconde le degr&eacute;):</p>
<p class="code">Command -&gt; DEGREE<br>
Input Data -&gt; ../web.data.gz<br>
Input Index -&gt; 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&eacute; est effectu&eacute; dans un
tableau de <span style="font-weight: bold;">sizeof(long) * N</span>
(o&ugrave; N est le nombre de noeuds), initialis&eacute; &agrave;
z&eacute;ro, et o&ugrave; les valeurs des cases sont
incr&eacute;ment&eacute;es &agrave; la lecture des arcs.<br>
</p>
<h4>5.2.4. Exercice 4</h4>
<p>Le simple stockage du graphe en m&eacute;moire ne produit pas de
sortie visible, mais s'execute en tapant :</p>
<p class="code">./src/alobe&nbsp;-S -i ../web.data.gz -c 701654</p>
Le programme commence par calculer les degr&eacute;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&ugrave; M est la somme des degr&eacute;s des
noeuds) destin&eacute; &agrave; contenir les arcs de chaque noeud. Les
3 cases suppl&eacute;mentaires ne servent qu'au calcul des composates
connexes et seront d&eacute;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&ccedil;on suivante:</p>
<p class="code">./src/alobe&nbsp;-A -i ../web.data.gz -c 701654</p>
<p class="code">Command -&gt; AVERAGE<br>
Input Data -&gt; ../web.data.gz<br>
Input Index -&gt; 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&eacute;utilise la structure de
donn&eacute;es l'&eacute;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&ccedil;on
suivante :</p>
<p class="code">./src/alobe&nbsp;-C -i ../web.data.gz -c 701654</p>
<p class="code">Command -&gt; CONNEXITY<br>
Input Data -&gt; ../web.data.gz<br>
Input Index -&gt; 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 -&gt; CONNEXITY<br>
Input Data -&gt; /home/warbrain/Films/IP.data.gz<br>
Input Index -&gt; 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 &agrave; ma disposition ne poss&eacute;daient pas
suffisament de m&eacute;moire...</p>
<p class="">Le calcul des composantes connexes utilise le m&ecirc;me
tableau que l'exercice 4. Le calcul se fait dans les 3 cases
suppl&eacute;mentaires :<br>
</p>
<ul>
<li>une case pour le degr&eacute; du noeud</li>
<li>une case pour l'offset du noeud trait&eacute;</li>
<li>une case pour le noeud "p&egrave;re" dans le parcours en
profondeur.</li>
</ul>
<p class="">Lorsqu'on parcours un noeud x en provenance de y, on
inscrit la r&eacute;f&eacute;rence du noeud p&egrave;re dans la case 3,
puis pour&nbsp;chaque noeud adjacent non visit&eacute;, on indique le
noeud adjacent parcouru actuellement puis on parcourt
r&eacute;cursivement le noeud adjacent.</p>
<p class="">Remarque: jusque l&agrave; le TP &eacute;tait
programm&eacute; en C++, et pour un &eacute;venteuel gain de
performances il fut r&eacute;&eacute;crit enti&egrave;rement (en
conservant les structures de donn&eacute;es) en C. Cependant seules 0.3
secondes furent gagn&eacute;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&eacute;fi</h4>
<p class="">On suppose que dans le graphe du web, les noeud adjacents
ont de fortes chances d'appartenir &agrave; la m&ecirc;me composante
connexe.&nbsp;<br>
Ainsi, pour d&eacute;crire en m&eacute;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&eacute;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&eacute;cessitent de
nombreuses recopies de donn&eacute;es&nbsp;et d'allocations de
m&eacute;moire. L'algorithme s'en trouve par cons&eacute;quent fort
ralenti...</p>
<p class="">On peut lancer le d&eacute;fi en tapant :</p>
<p class="code">./src/alobe&nbsp;-E -i ../web.data.gz -c 701654</p>
<p class="">..et admirer les r&eacute;sultats (s'il apparaissent, car
il y a encore pas mal de soucis de pointeurs se baladant librement...)</p>
</div>
</body>
</html>

360
doc/tp2.html Normal file
View File

@ -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&eacute;</title>
<meta content="Glenn ROLLAND" name="author">
</head>
<body style="direction: ltr;">
<div style="text-align: justify;" class="page">
<h1>Alob&eacute; (TP2)</h1>
<h2><a name="1._Description"></a>1.
<a name="Description"></a>Description</h2>
<p>Alob&eacute; est
un&nbsp;logiciel libre permettant de manipuler de grands graphes
non-orient&eacute;s d&eacute;crits par la liste de leurs
arr&ecirc;tes. Il poss&egrave;de les
caract&eacute;ristiques
suivantes :</p>
<ul>
<li>Il est distribu&eacute;
sous la licence&nbsp;<a href="http://www.gnu.org/copyleft/gpl.html">GNU
General Public License</a></li>
<li>Il&nbsp;est
&eacute;crit en C (bien qu'&eacute;crit au d&eacute;part en
C++, comme en t&eacute;moigne le d&eacute;p&ocirc;t
subversion) et poss&egrave;de une interface en ligne
de
commande,</li>
<li>Il impl&eacute;mente le
calcul de la distance d'un noeud &agrave; tous les autres
(exercice 1).</li>
<li>Il fournit en sortie des
donn&eacute;es permettant de tracer la
distribution des distance &agrave; un noeud donn&eacute;
(exercice 2)</li>
<li>Il fournit en sortie les
donn&eacute;es permettant de tracer
l'&eacute;volution de l'estimation de la distance moyenne en
fonction
du nombre de parcours effectu&eacute;s.
(exercice 3)</li>
<li>Il impl&eacute;mente le
calcul de la borne inf&eacute;rieure du
diam&egrave;tre, en prenant la distance maximale d'un noeud
donn&eacute; &agrave; tous les autres (exercice 4).</li>
<li>Il impl&eacute;mente le
calcul de la borne sup&eacute;rieure du diam&egrave;tre, en
prenant la
distance maximale dans l'arbre du parcours en largeur (exercice
5).&nbsp;</li>
<li>Il fournit en sortie des
donn&eacute;es permettant de tracer les
courbes des meilleurs bornes inf&eacute;rieures et
sup&eacute;rieure en
fonction du nombre de parcours effectu&eacute;s.
(exercice 6 - d&eacute;fi).</li>
</ul>
<h3>1.1.
Auteurs</h3>
<p>Alob&eacute; a
&eacute;t&eacute; enti&egrave;rement
r&eacute;alis&eacute; par Glenn ROLLAND &lt;<a
href="mailto:glenux@fr.st">glenux@fr.st</a>&gt;
&agrave; l'occasion de travaux pratiques du cours de <span
style="font-style: italic;">Grand R&eacute;seaux</span>
du Master 2 Ing&eacute;nierie Informatique
-
Syst&egrave;mes, R&eacute;seaux et Internet.</p>
<h2><a99 name="2._Pr&eacute;-requis">2.
Pr&eacute;-requis</a99></h2>
<p>Alob&eacute;
ne&nbsp;n&eacute;cessite pas de biblioth&egrave;ques de
fonctions
particuli&egrave;res pour fonctionnner.</p>
<h2>3.
Se procurer Alob&eacute;</h2>
Vous
pouvez t&eacute;l&eacute;charger la derni&egrave;re archive
des
sources, ou bien directement la version la plus r&eacute;cente du
projet sur le d&eacute;p&ocirc;t Subversion du projet.<br>
<h3>3.1. L'archive des sources</h3>
Elle est disponible &agrave; 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&eacute;p&ocirc;t Subversion</h3>
<p>Afin d'obtenir les sources les
plus &agrave; jour, vous pouvez utiliser le logiciel de
contr&ocirc;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&eacute;e" pour l'utilisateur "anonymous", si ce dernier vous
est
demand&eacute;.</p>
<h2><a name="4._Utiliser_Alob&eacute;"></a>4.
Utiliser Alob&eacute;</h2>
<h3><a name="4.1._Compilation"></a>4.1.
Compilation</h3>
<p>Commencez par
d&eacute;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'&ecirc;tre cr&eacute;&eacute; lors de
la d&eacute;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>&nbsp;<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&eacute; doivent &ecirc;tre appel&eacute;s
avec la syntaxe suivante:<br>
</div>
<p class="code">Usage:
alobe &lt;commande&gt; &lt;parametres_obligatoires&gt;
[options]<br>
</p>
<p>Les commandes&nbsp;sont
les suivants:</p>
<dl>
<dt>-I, --tp2distance</dt>
<dd>Calcule les distances
&agrave; partir du noeud donn&eacute;.</dd>
<dt> -J, --tp2distanceplot </dt>
<dd>Donne la distribution des
distances &agrave; partir du noeud donn&eacute;.</dd>
<dt>-L, --tp2distevolution</dt>
<dd>Donne l'&eacute;volution
de l'estimation de la distance moyenne.pour un noeud donn&eacute;,
ou au hasard, en fonction du nombre d'it&eacute;rations.</dd>
<dt>-M, --tp2limitinf</dt>
<dd>Calcule la borne
inf&eacute;rieure du diam&egrave;tre pour un noeud
donn&eacute; ou au hasard, en fonction du nombre
d'it&eacute;rations.</dd>
<dt>-N, --tp2limitsup</dt>
<dd>Calcule la borne
sup&eacute;rieure du diam&egrave;tre pour un noeud
donn&eacute; ou au hasard, en fonction du nombre
d'it&eacute;rations.</dd>
<dt>-O, --tp2defi</dt>
<dd>Fournit les
donn&eacute;es permettant de tracer les courbes de meilleures
bornes inf&eacute;rieures et sup&eacute;rieures du
diam&egrave;tre en fonction du nombre d'it&eacute;ration.</dd>
</dl>
<ul>
</ul>
<p>Les param&egrave;tres
obligatoires sont les suivants:</p>
<dl>
<dt>-c, --count
&lt;entier&gt; <fichier> </fichier></dt>
<dd>Nombre de noeuds du fichier
d'entr&eacute;e.</dd>
</dl>
<p>Les parames optionnels sont les
suivants:</p>
<dl>
<dt>-i, --input
&lt;fichier&gt;</dt>
<dd> Le fichier
d'entr&eacute;e, "-" d&eacute;signant l'entr&eacute;e
standard,</dd>
<dt>-o, --output
&lt;fichier&gt;</dt>
<dd>Le fichier de sorftie, "-"
d&eacute;signant la sortie standard.</dd>
<dt>-v, --verbose</dt>
<dd> Passe l'affichage en mode
verbeux.e
num&eacute;ro du noeud &agrave; lire et afficher &agrave;
partir du
fichier
compress&eacute;</dd>
<dt>-r, --root
&lt;entier&gt;</dt>
<dd>Noeur servant de racine
&agrave; la premi&egrave;re it&eacute;ration.</dd>
<dt>-n, --iterations
&lt;entier&gt;</dt>
<dd>Nombre
d'it&eacute;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&eacute; 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&eacute;rents exercices</h3>
<h4>5.2.1. Exercice 1</h4>
<p>On calcule la distance d'un
noeud (le 24 par exemple) &agrave; tous les autres, ainsi que la
moyenne de toutes ses distances, par la commande suivante:</p>
<p class="code">&nbsp;./alobe
-I -i&nbsp;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&eacute; (le 24 par exemple) de la
fa&ccedil;on suivante:</p>
<p class="code">$ ./alobe
-J -i&nbsp;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'&eacute;volution
de l'estimation de la distance moyenne (en fonction du nombre
d'it&eacute;ration) par la commande suivante:</p>
<p class="code">&nbsp;./alobe
-L -i&nbsp;web.data.gz -o result.txt -c 701654 -n 100 -r 24<br>
</p>
<p class="">Ce qui produit
en sortie:&nbsp;</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&eacute;rieure, on fera:</p>
<p class="code">./alobe -M
-i&nbsp;web.data.gz -o result.txt -c 701654 -n 5 -r 24</p>
<p class="code">Iteration 0
-- choosing root 24<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- borne inf&eacute;rieure 17<br>
Iteration 1 -- choosing root 60401<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- borne inf&eacute;rieure 18<br>
Iteration 2 -- choosing root 700018<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- borne inf&eacute;rieure 24<br>
Iteration 3 -- choosing root 77852<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- borne inf&eacute;rieure 24<br>
Iteration 4 -- choosing root 45944<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- borne inf&eacute;rieure 24<br>
</p>
<br>
<h4>5.2.5. Exercice 5</h4>
<p>Pour le calcul de la borne
sup&eacute;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>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- borne sup&eacute;rieure 33<br>
Iteration 1 -- choosing root 96542<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- borne sup&eacute;rieure 33<br>
Iteration 2 -- choosing root 49208<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- borne sup&eacute;rieure 33<br>
Iteration 3 -- choosing root 436498<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- borne sup&eacute;rieure 33<br>
Iteration 4 -- choosing root 309990<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- borne sup&eacute;rieure 32<br>
Iteration 5 -- choosing root 538890<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- borne sup&eacute;rieure 32<br>
Iteration 6 -- choosing root 266656<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- borne sup&eacute;rieure 32<br>
Iteration 7 -- choosing root 529998<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- borne sup&eacute;rieure 32<br>
Iteration 8 -- choosing root 140145<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- borne sup&eacute;rieure 32<br>
Iteration 9 -- choosing root 640316<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- borne sup&eacute;rieure 32<br>
<br>
</p>
<h4>5.2.6. Exercice 6 - D&eacute;fi</h4>
<p>Le cumul des courbes
pr&eacute;c&eacute;dentes&nbsp;se fait par :</p>
<p class="code">$ ./alobe
-O -i&nbsp;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&eacute;fi, il aurait fallu en plus utiliser une
heuristique de choix des noeuds permettant de faire converger les deux
courbes bornant le diam&egrave;tre au plus vite. Par exemple,
choisir les noeuds par degr&eacute; d&eacute;croissant dans la
composante connexe, en supposant qu'un noeud a fort degr&eacute;
comme racine donne un arbre plus plat et donc la borne
supp&eacute;rieure par la m&ecirc;me occasion...</p>
<br>
</div>
</body>
</html>

2643
grind/callgrind.out.15895 Normal file

File diff suppressed because it is too large Load Diff

3529
grind/callgrind.out.15896 Normal file

File diff suppressed because it is too large Load Diff

84
src/Makefile.am Normal file
View File

@ -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

279
src/alobe.c Normal file
View File

@ -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;
}

2
src/alobe.h Normal file
View File

@ -0,0 +1,2 @@
/* vim: set sw=4 ts=4 si et: */

13
src/by_hand.0.10 Normal file
View File

@ -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

10
src/by_hand.0.11 Normal file
View File

@ -0,0 +1,10 @@
0 1
0 2
1 3
1 4
3 5
4 6
5 7
5 8
6 9
9 10

12
src/by_hand.0.9 Normal file
View File

@ -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

345
src/config.c Normal file
View File

@ -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");
}

62
src/config.h Normal file
View File

@ -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

91
src/config.h.in Normal file
View File

@ -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

262
src/connexcomponent.c Normal file
View File

@ -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

69
src/connexcomponent.h Normal file
View File

@ -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

64
src/console.c Normal file
View File

@ -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

54
src/console.h Normal file
View File

@ -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 */

55
src/defi.c Normal file
View File

@ -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

36
src/defi.h Normal file
View File

@ -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

96
src/degenerator.c Normal file
View File

@ -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

51
src/degenerator.h Normal file
View File

@ -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

233
src/degree.c Normal file
View File

@ -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

54
src/degree.h Normal file
View File

@ -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

560
src/distance.c Normal file
View File

@ -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&eacute;
*/
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&ecirc;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

59
src/distance.h Normal file
View File

@ -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

235
src/fifo.c Normal file
View File

@ -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

40
src/fifo.h Normal file
View File

@ -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

50
src/filter.c Normal file
View File

@ -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");
}

25
src/filter.h Normal file
View File

@ -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

150
src/generator.c Normal file
View File

@ -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

24
src/generator.h Normal file
View File

@ -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

274
src/list.c Normal file
View File

@ -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);
}

68
src/list.h Normal file
View File

@ -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 */

66
src/mini.0.20 Normal file
View File

@ -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

246
src/mini.0.60 Normal file
View File

@ -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

359
src/nodeset.c Normal file
View File

@ -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

70
src/nodeset.h Normal file
View File

@ -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

7
src/note.txt Normal file
View File

@ -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...

21
src/progressindicator.c Normal file
View File

@ -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;
}

13
src/progressindicator.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef _PROGESS_INDICATOR_H
#define _PROGESS_INDICATOR_H
static char* progress_indicator_table[] = {
"[|]",
"[/]",
"[-]",
"[\\]"
};
char * progress_indicator();
#endif

758
src/store.c Normal file
View File

@ -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;
}
/**
* -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 é 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 é faite
*
* ATTENTION: utilise STORE_EXTRA_REF (ok)
*
* @param store Pointeur sur l'objet Store_t manipulé
* @return bool TRUE si le noeud a é 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

91
src/store.h Normal file
View File

@ -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

1
src/test.0.10 Executable file
View File

@ -0,0 +1 @@
./alobe -N -i by_hand.0.10 -c 10 -r 3 -n 1 -o -

1
src/test.0.11 Executable file
View File

@ -0,0 +1 @@
./alobe -N -i by_hand.0.11 -c 11 -r 0 -n 1 -o -

1
src/test.0.9 Executable file
View File

@ -0,0 +1 @@
./alobe -N -i by_hand.0.9 -c 9 -r 4 -n 1 -o -

72
src/testfifo.c Normal file
View File

@ -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;
}

124
src/testlist.c Normal file
View File

@ -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;
}

45
src/tool_defi2plot.sh Executable file
View File

@ -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

2
src/tool_plot.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash
echo "plot \"$1\" with lines" | gnuplot -persist

1
src/tool_sortgraph.sh Normal file
View File

@ -0,0 +1 @@
sort -k1,1n -k2,2n

555
src/tp1_ex2_web.0.200 Normal file
View File

@ -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

701654
src/tp1_ex3_web Normal file

File diff suppressed because it is too large Load Diff

0
src/tp1_ex4_web Normal file
View File

5332
src/tp3_ex1_web Normal file

File diff suppressed because it is too large Load Diff

1000
src/tp3_ex2_web Normal file

File diff suppressed because it is too large Load Diff

10000
src/tp3_ex2_web.2 Normal file

File diff suppressed because it is too large Load Diff

BIN
src/tp3_ex3.gz Normal file

Binary file not shown.

21
src/tp3_ex4 Normal file
View File

@ -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

100
src/tp3_ex7_gen Normal file
View File

@ -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

100
src/tp3_ex7_web Normal file
View File

@ -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

58
src/units.h Normal file
View File

@ -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