remastered version
git-svn-id: http://cregut.svn.enseeiht.fr/2020/1sn/pim/projets/GH-05@213630 e13453a9-b01f-0410-a051-f404c4f0c485
This commit is contained in:
parent
d3dfa4a10e
commit
9b63ae9ba3
4
Makefile
4
Makefile
|
@ -1,11 +1,11 @@
|
|||
make:
|
||||
make clean && \
|
||||
cd build/ && \
|
||||
gnat make -gnatwa -gnata -g ../src/*.adb
|
||||
|
||||
clean:
|
||||
cd build/ && \
|
||||
gnat clean ../src/*.adb
|
||||
gnat clean ../src/*.adb && \
|
||||
rm ../fichiers_test/*/*_GH05*
|
||||
|
||||
test:
|
||||
bash test_pagerank.bash
|
|
@ -26,8 +26,8 @@ $ make test
|
|||
├── src \
|
||||
│ ├── google_creux.adb \
|
||||
│ ├── google_creux.ads \
|
||||
│ ├── google_naive.adb \
|
||||
│ ├── google_naive.ads \
|
||||
│ ├── google_Naif.adb \
|
||||
│ ├── google_Naif.ads \
|
||||
│ ├── pagerank.adb \
|
||||
│ ├── vector.adb \
|
||||
│ └── vector.ads \
|
||||
|
|
|
@ -59,11 +59,11 @@ De même, pour stocker le réseau nous choisissons la structure d'une matrice de
|
|||
###### afficher extrait de network
|
||||
|
||||
Pour stocker G, la matrice de Google, nous avons 2 choix:
|
||||
- Une Matrice naive
|
||||
- Une Matrice Naif
|
||||
- Une Matrice creuse
|
||||
|
||||
# Implémentation Naive
|
||||
Le premier choix consiste à stocker la matrice très naivement, c'est-à-dire en stockant l'ensemble de ses valeurs dans une matrice de taille NxN.
|
||||
# Implémentation Naif
|
||||
Le premier choix consiste à stocker la matrice très Naifment, c'est-à-dire en stockant l'ensemble de ses valeurs dans une matrice de taille NxN.
|
||||
|
||||
L'avantage principale de cette structure est que sa construction et sa manipulation (produit vecteur/matrice) est simple.
|
||||
Pour la construire à partir du réseau nous assignons à chaque lien une valeur dans la matrice. De même celle-ci à l'avantage d'être robuste par défaut à la présence de doublons dans le réseau.
|
||||
|
@ -79,9 +79,9 @@ Cependant nous pouvons aller encore plus loin en compressant G via un algorithme
|
|||
|
||||
De cette manière nous ne gardons que les informations qui sont essentielles.
|
||||
|
||||
L'inconvénient de cette méthode est que la création de ce type de matrice et son utilisation est plus compliqué que pour une matrice naive.
|
||||
L'inconvénient de cette méthode est que la création de ce type de matrice et son utilisation est plus compliqué que pour une matrice Naif.
|
||||
|
||||
Mais l'avantage de cette structure de donnée est son gain d'espace non négligeable ainsi que la rapidité qu'elle propose puisque nous n'effectuons plus que N_Links opérations lors du produit vecteur/matrice, au lieu de N^2 pour la version naive.
|
||||
Mais l'avantage de cette structure de donnée est son gain d'espace non négligeable ainsi que la rapidité qu'elle propose puisque nous n'effectuons plus que N_Links opérations lors du produit vecteur/matrice, au lieu de N^2 pour la version Naif.
|
||||
|
||||
# Performance
|
||||
|
||||
|
@ -89,7 +89,7 @@ Mais l'avantage de cette structure de donnée est son gain d'espace non néglige
|
|||
|
||||
# Conclusion
|
||||
|
||||
On remaque facilement la supériorité temporelle et spatiale de la version creuse contre la version naive.
|
||||
On remaque facilement la supériorité temporelle et spatiale de la version creuse contre la version Naif.
|
||||
|
||||
## Améliorations encore possible:
|
||||
Lors de l'implémentation de la matrice compressé, nous avons choisis de compressé les lignes puisque celle-ci peuvent parfois être entièrement vide, cela est bénéfique d'un point de vu espace. Cepedant ils serait aussi intéressant de compresser G selon les colonnes puisque, bien que l'on perde en espace mémoire, on gagnerait en efficacité temporelle grâce au nombre réduit d'accès mémoire que l'on effecturait par rapport à la compression par ligne.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Ce raffinage décrit l'implémentation de l'algorithme de PageRank dans le cas d'une implémentation de matrice naives.
|
||||
Ce raffinage décrit l'implémentation de l'algorithme de PageRank dans le cas d'une implémentation de matrice Naifs.
|
||||
|
||||
R0: Calculer le PageRank et le poids de chaque nœud d'un réseau
|
||||
|
||||
|
|
166
src/pagerank.adb
166
src/pagerank.adb
|
@ -5,8 +5,8 @@ with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
|
|||
with Ada.Text_IO.Text_Streams;
|
||||
|
||||
with Vector;
|
||||
with Google_Naive;
|
||||
with Google_Creux;
|
||||
with Google;
|
||||
with Quicksort;
|
||||
|
||||
procedure pageRank is
|
||||
|
||||
|
@ -18,12 +18,12 @@ procedure pageRank is
|
|||
INFO_tips: Exception;
|
||||
INFO_help: Exception;
|
||||
|
||||
-- définition du type T_Double
|
||||
Type T_Double is digits 18;
|
||||
-- on utilise le module générique Float_IO pour pouvoir afficher T_Double directement
|
||||
package Text_T_Double is
|
||||
new Ada.Text_IO.Float_IO(Num => T_Double);
|
||||
use Text_T_Double;
|
||||
-- définition du type T_Reel
|
||||
Type T_Reel is digits 18;
|
||||
-- on utilise le module générique Float_IO pour pouvoir afficher T_Reel directement
|
||||
package Text_T_Reel is
|
||||
new Ada.Text_IO.Float_IO(Num => T_Reel);
|
||||
use Text_T_Reel;
|
||||
|
||||
-- permet de faire un retour chariot pour écrire plusieurs fois sur la même ligne, pas possible avec un put
|
||||
stdout: constant Ada.Text_IO.File_Type := Ada.Text_IO.Standard_Output;
|
||||
|
@ -35,7 +35,7 @@ procedure pageRank is
|
|||
-- procédure pour récupérer les arguments de la ligne de commande
|
||||
procedure get_args(filename: in out Unbounded_String;
|
||||
ite_max: in out Natural;
|
||||
alpha: in out T_Double;
|
||||
alpha: in out T_Reel;
|
||||
naif: in out Boolean) is
|
||||
i: Natural := 1;
|
||||
begin
|
||||
|
@ -66,7 +66,7 @@ procedure pageRank is
|
|||
put_line("parsed naif");
|
||||
|
||||
elsif Argument(i) = "-a" or Argument(i) = "--alpha" then
|
||||
alpha := T_Double'Value(Argument(i+1));
|
||||
alpha := T_Reel'Value(Argument(i+1));
|
||||
if alpha < 0.0 or alpha > 1.0 then
|
||||
raise ERROR_alpha;
|
||||
end if;
|
||||
|
@ -81,7 +81,7 @@ procedure pageRank is
|
|||
i := i + 2;
|
||||
put_line("parsed ite_max");
|
||||
|
||||
elsif Argument(i)'Length > 3 and then Argument(i)(Argument(i)'Last-3 .. Argument(i)'Last) = ".net" then
|
||||
elsif Argument(i)'Length > 4 and then Argument(i)(Argument(i)'Last-3 .. Argument(i)'Last) = ".net" then
|
||||
filename := To_Unbounded_String(Argument(i)(Argument(i)'First .. Argument(i)'Last-4));
|
||||
i := i + 1;
|
||||
put_line("parsed filename");
|
||||
|
@ -106,11 +106,10 @@ procedure pageRank is
|
|||
end if;
|
||||
|
||||
new_line;
|
||||
put("alpha = "); put(alpha, Fore=>1, Aft=>10); new_line;
|
||||
put("alpha = "); put(alpha, 1); new_line;
|
||||
put("naif = "); put(Boolean'Pos(naif), 1); new_line;
|
||||
put("ite_max = "); put(ite_max, 1); new_line;
|
||||
put("filename = "); put_line(To_String(filename));
|
||||
new_line;
|
||||
|
||||
exception
|
||||
|
||||
|
@ -134,7 +133,7 @@ procedure pageRank is
|
|||
filename: Unbounded_String;
|
||||
ite_max: Natural := 150;
|
||||
naif: Boolean := False;
|
||||
alpha: T_Double := 0.85;
|
||||
alpha: T_Reel := 0.85;
|
||||
|
||||
-- définition des variables pour créer les matices/vecteurs
|
||||
N: Positive;
|
||||
|
@ -145,7 +144,7 @@ begin
|
|||
|
||||
-- on récupère les arguments de la ligne de commande
|
||||
get_args(filename, ite_max, alpha, naif);
|
||||
put_line("parsed successfully arguments");
|
||||
put_line("parsed successfully arguments"); new_line;
|
||||
|
||||
-- on ouvre le fichier .net
|
||||
open(file, In_File, To_String(filename & ".net"));
|
||||
|
@ -162,68 +161,40 @@ begin
|
|||
end loop;
|
||||
put("N_links = "); put(N_links, 1); new_line;
|
||||
|
||||
-- on calcule la densité
|
||||
put("densité = "); put(T_Reel(N_Links)/T_Reel(N)**2, 1); new_line;
|
||||
|
||||
new_line;
|
||||
|
||||
-- on renvient au début du fichier
|
||||
reset(file, In_File);
|
||||
-- au saute la première ligne pour s'apprêter à lire le réseau
|
||||
skip_line(file);
|
||||
|
||||
|
||||
-- explication: Nous avons choisis d'utiliser des "declare" plutot que des sous-procédures dont on ferait l'appelle
|
||||
-- puisque cela permet d'avoir un lecture plus linéaire du code.
|
||||
|
||||
-- on peut maintenant créer nos vecteurs
|
||||
declare
|
||||
-- on peut maintenant créer nos vecteurs
|
||||
package Vector_Entier is
|
||||
new Vector.Entier(Capacite => N);
|
||||
package Vector_Double is
|
||||
new Vector.Digit(T_Digit => T_Double,
|
||||
Capacite => N,
|
||||
Vector_Entier => Vector_Entier);
|
||||
package Vector_Link is
|
||||
new Vector.Link(Capacite => N_links);
|
||||
new Vector.Entier(T_Entier => Natural, Capacite => N);
|
||||
package Vector_Reel is
|
||||
new Vector.Reel(T_Reel => T_Reel, Capacite => N);
|
||||
|
||||
use Vector_Double;
|
||||
use Vector_Entier;
|
||||
use Vector_Link;
|
||||
use Vector_Reel;
|
||||
|
||||
|
||||
|
||||
network: Vector_Link.T_Vecteur;
|
||||
row, col: Natural;
|
||||
|
||||
sorted: Boolean;
|
||||
dupe: Natural;
|
||||
|
||||
pi: Vector_Double.T_Vecteur;
|
||||
pi: Vector_Reel.T_Vecteur;
|
||||
pi_index: Vector_Entier.T_Vecteur;
|
||||
|
||||
-- on instancie aussi l'algorithme QuickSort
|
||||
package Quicksort_Reel_Entier is
|
||||
new Quicksort(Vector_Index => Vector_Entier,
|
||||
Vector_Element => Vector_Reel);
|
||||
|
||||
use Quicksort_Reel_Entier;
|
||||
|
||||
begin
|
||||
|
||||
new_line;
|
||||
-- on charge le réseau en mémoire
|
||||
for i in 0..N_links-1 loop
|
||||
get(file, row);
|
||||
get(file, col);
|
||||
network(i) := T_Link'(row, col);
|
||||
end loop;
|
||||
close(file);
|
||||
put_line("loaded in memory the network");
|
||||
|
||||
-- on trie le réseau, si besoin
|
||||
is_sorted_and_uniq(network, dupe, sorted);
|
||||
if not naif then
|
||||
if not sorted then
|
||||
put_line("network is not sorted");
|
||||
quicksort(network);
|
||||
put_line("sorted the network");
|
||||
end if;
|
||||
if dupe > 0 then
|
||||
put_line("deleted the duplicates ####### TODO #######");
|
||||
end if;
|
||||
end if;
|
||||
|
||||
new_line;
|
||||
|
||||
initialize(pi, 1.0/T_Double(N));
|
||||
put_line("initialized pi");
|
||||
initialize(pi, 1.0/T_Reel(N));
|
||||
put_line("initialized pi to 1/N");
|
||||
-- put(pi); new_line;
|
||||
|
||||
identity(pi_index);
|
||||
|
@ -233,37 +204,26 @@ begin
|
|||
if naif then
|
||||
declare
|
||||
-- on instancie le module générique Naif de Google
|
||||
package Google is
|
||||
new Google_Naive(T_Element => T_Double,
|
||||
N => N,
|
||||
package Google_Naif is
|
||||
new Google.Naif(N => N,
|
||||
N_links => N_links,
|
||||
Vector_Natural => Vector_Entier,
|
||||
Vector_Element => Vector_Double,
|
||||
Vector_Link => Vector_Link);
|
||||
use Google;
|
||||
Vector_Element => Vector_Reel);
|
||||
use Google_Naif;
|
||||
|
||||
-- définition de la matrice Google
|
||||
G: T_Google;
|
||||
begin
|
||||
|
||||
initialize(G);
|
||||
put_line("initialized G");
|
||||
initialize(G, 0.0);
|
||||
put_line("initialized G to zeros");
|
||||
-- put(G); new_line;
|
||||
|
||||
new_line;
|
||||
|
||||
create_H(G, network);
|
||||
put_line("created H");
|
||||
-- put(G); new_line;
|
||||
|
||||
create_S(G);
|
||||
put_line("created S");
|
||||
-- put(G); new_line;
|
||||
|
||||
create_G(G, alpha);
|
||||
create_Google(G, alpha, file);
|
||||
put_line("created G");
|
||||
-- put(G); new_line;
|
||||
|
||||
close(file);
|
||||
put("closed "); put(To_String(filename & ".net")); new_line;
|
||||
new_line;
|
||||
|
||||
-- on applique l'algorithme itératif
|
||||
|
@ -281,28 +241,32 @@ begin
|
|||
else -- not naif
|
||||
declare
|
||||
-- on instancie le module générique Creux de Google
|
||||
package Google is
|
||||
new Google_Creux(T_Element => T_Double,
|
||||
N => N,
|
||||
package Google_Creux is
|
||||
new Google.Creux(N => N,
|
||||
N_links => N_links,
|
||||
Vector_Natural => Vector_Entier,
|
||||
Vector_Element => Vector_Double,
|
||||
Vector_Link => Vector_Link);
|
||||
use Google;
|
||||
Vector_Element => Vector_Reel);
|
||||
use Google_Creux;
|
||||
|
||||
-- définition de la matrice Google
|
||||
H: T_Google;
|
||||
G: T_Google;
|
||||
begin
|
||||
|
||||
create_H(H, network);
|
||||
put_line("created H");
|
||||
-- put(H); new_line; new_line;
|
||||
create_Google(G, file);
|
||||
put_line("created G");
|
||||
|
||||
-- new_line; new_line;
|
||||
-- put(G);
|
||||
-- new_line; new_line;
|
||||
|
||||
close(file);
|
||||
put("closed "); put(To_String(filename & ".net")); new_line;
|
||||
new_line;
|
||||
|
||||
new_line;
|
||||
|
||||
-- on applique l'algorithme itératif
|
||||
for i in 1..ite_max loop
|
||||
pi := calcul(pi, H, alpha);
|
||||
pi := calcul(pi, G, alpha);
|
||||
String'Write(Ada.Text_IO.Text_Streams.Stream(stdout),
|
||||
ASCII.CR & "ite:" & Integer'Image(i) & " /" & Integer'Image(ite_max));
|
||||
end loop; new_line;
|
||||
|
@ -316,7 +280,7 @@ begin
|
|||
new_line;
|
||||
|
||||
-- on trie pi avec ses indices
|
||||
quicksort(pi, pi_index);
|
||||
sort(pi, pi_index);
|
||||
put_line("sorted pi and pi_index");
|
||||
flip(pi);
|
||||
put_line("reversed pi");
|
||||
|
@ -346,7 +310,7 @@ exception
|
|||
when ERROR_args =>
|
||||
new_line;
|
||||
put_line("Erreur lors de la saisi de la commande.");
|
||||
put_line("Usage: pagerank [-P] [-i max_iterations] [-a alpha] [-h] fichier_reseau.net");
|
||||
put_line("Usage: pagerank [-n] [-i max_iterations] [-a alpha] [-h] fichier_reseau.net");
|
||||
|
||||
when ERROR_alpha =>
|
||||
new_line;
|
||||
|
@ -361,7 +325,7 @@ exception
|
|||
when ERROR_filename =>
|
||||
new_line;
|
||||
put_line("Erreur lors de la saisi du fichier réseau.");
|
||||
put_line("Veuillez rentrer un nom valide.");
|
||||
put_line("Veuillez rentrer un fichier existant.");
|
||||
|
||||
when INFO_tips =>
|
||||
put_line("Essayez 'pagerank --help' pour plus d'informations.");
|
||||
|
@ -372,7 +336,7 @@ exception
|
|||
put_line("Calcule le pagerank d'un réseau à partir de son réseau.net");
|
||||
new_line;
|
||||
put_line("Options:");
|
||||
put_line(" -P, --naif specifies which type of matrix to use");
|
||||
put_line(" -n, --naif specifies which type of matrix to use");
|
||||
put_line(" -a, --alpha specifies the alpha constant (alpha ∈ [0, 1])");
|
||||
put_line(" -i, --ite-max specifies the maximum number of iterations (ite_max ∈ ⟦0, 150⟧)");
|
||||
put_line(" -h, --help display this help message and exit");
|
||||
|
|
258
src/vector.adb
258
src/vector.adb
|
@ -1,10 +1,8 @@
|
|||
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
|
||||
|
||||
package body Vector is
|
||||
|
||||
package body Entier is
|
||||
|
||||
procedure initialize(vec: in out T_Vecteur; value: in Natural) is
|
||||
procedure initialize(vec: in out T_Vecteur; value: in T_Entier) is
|
||||
begin
|
||||
for i in 0..Capacite-1 loop
|
||||
vec(i) := value;
|
||||
|
@ -14,12 +12,19 @@ package body Vector is
|
|||
procedure identity(vec: in out T_Vecteur) is
|
||||
begin
|
||||
for i in 0..Capacite-1 loop
|
||||
vec(i) := i;
|
||||
vec(i) := T_Entier(i);
|
||||
end loop;
|
||||
end identity;
|
||||
|
||||
procedure repartition(vec: in out T_Vecteur) is
|
||||
begin
|
||||
for i in 1..Capacite-1 loop
|
||||
vec(i) := vec(i-1) + vec(i);
|
||||
end loop;
|
||||
end repartition;
|
||||
|
||||
procedure flip(vec: in out T_Vecteur) is
|
||||
tmp: Natural;
|
||||
tmp: T_Entier;
|
||||
begin
|
||||
for i in 0..Capacite/2-1 loop
|
||||
tmp := vec(i);
|
||||
|
@ -31,77 +36,31 @@ package body Vector is
|
|||
procedure put(vec: in T_Vecteur) is
|
||||
begin
|
||||
for i in 0..Capacite-1 loop
|
||||
put(vec(i)); new_line;
|
||||
put(vec(i), 1); new_line;
|
||||
end loop;
|
||||
end put;
|
||||
|
||||
procedure put(file: in out Ada.Text_IO.File_Type; vec: in T_Vecteur) is
|
||||
procedure put(file: in Ada.Text_IO.File_Type; vec: in T_Vecteur) is
|
||||
begin
|
||||
for i in 0..Capacite-1 loop
|
||||
put(file, vec(i), 0);
|
||||
put(file, vec(i), 1);
|
||||
new_line(file);
|
||||
end loop;
|
||||
end put;
|
||||
|
||||
procedure quicksort(vec: in out T_Vecteur; low: Natural := 0; high: Natural := Capacite-1) is
|
||||
|
||||
procedure swap(left, right: Natural) is
|
||||
tmp : constant Natural := vec(left);
|
||||
begin
|
||||
vec(left) := vec(right);
|
||||
vec(right) := tmp;
|
||||
end swap;
|
||||
|
||||
pivot : constant Natural := vec(low);
|
||||
right : Natural := high;
|
||||
left : Natural := low;
|
||||
|
||||
begin
|
||||
if high - low > 0 then
|
||||
loop
|
||||
while left < right and pivot >= vec(left) loop
|
||||
left := left + 1;
|
||||
end loop;
|
||||
while pivot < vec(right) loop
|
||||
right := right - 1;
|
||||
end loop;
|
||||
|
||||
exit when right <= left;
|
||||
|
||||
swap(left, right);
|
||||
left := left + 1;
|
||||
right := right - 1;
|
||||
end loop;
|
||||
|
||||
if right = high then
|
||||
right := right - 1;
|
||||
swap(low, high);
|
||||
end if;
|
||||
|
||||
if left = low then
|
||||
left := left - 1;
|
||||
end if;
|
||||
|
||||
quicksort(vec, low, right);
|
||||
quicksort(vec, left, high);
|
||||
end if;
|
||||
end quicksort;
|
||||
|
||||
end Entier;
|
||||
|
||||
package body Reel is
|
||||
|
||||
|
||||
package body Digit is
|
||||
|
||||
procedure initialize(vec: in out T_Vecteur; value: in T_Digit) is
|
||||
procedure initialize(vec: in out T_Vecteur; value: in T_Reel) is
|
||||
begin
|
||||
for i in 0..Capacite-1 loop
|
||||
vec(i) := value;
|
||||
end loop;
|
||||
end initialize;
|
||||
|
||||
function sum(vec: in T_Vecteur) return T_Digit is
|
||||
s: T_Digit := 0.0;
|
||||
function sum(vec: in T_Vecteur) return T_Reel is
|
||||
s: T_Reel := 0.0;
|
||||
begin
|
||||
for i in 0..Capacite-1 loop
|
||||
s := s + vec(i);
|
||||
|
@ -110,7 +69,7 @@ package body Vector is
|
|||
end sum;
|
||||
|
||||
procedure flip(vec: in out T_Vecteur) is
|
||||
tmp: T_Digit;
|
||||
tmp: T_Reel;
|
||||
begin
|
||||
for i in 0..Capacite/2-1 loop
|
||||
tmp := vec(i);
|
||||
|
@ -122,11 +81,11 @@ package body Vector is
|
|||
procedure put(vec: in T_Vecteur) is
|
||||
begin
|
||||
for i in 0..Capacite-1 loop
|
||||
put(vec(i)); new_line;
|
||||
put(vec(i), Fore=>1, Aft=>10); new_line;
|
||||
end loop;
|
||||
end put;
|
||||
|
||||
procedure put(file: in out Ada.Text_IO.File_Type; vec: in T_Vecteur) is
|
||||
procedure put(file: in Ada.Text_IO.File_Type; vec: in T_Vecteur) is
|
||||
begin
|
||||
for i in 0..Capacite-1 loop
|
||||
put(file, vec(i), Fore=>1, Aft=>10);
|
||||
|
@ -134,181 +93,6 @@ package body Vector is
|
|||
end loop;
|
||||
end put;
|
||||
|
||||
procedure quicksort(vec: in out T_Vecteur; low: Natural := 0; high: Natural := Capacite-1) is
|
||||
|
||||
procedure swap(left, right: Natural) is
|
||||
tmp : constant T_Digit := vec(left);
|
||||
begin
|
||||
vec(left) := vec(right);
|
||||
vec(right) := tmp;
|
||||
end swap;
|
||||
|
||||
pivot : constant T_Digit := vec(low);
|
||||
right : Natural := high;
|
||||
left : Natural := low;
|
||||
|
||||
begin
|
||||
if high - low > 0 then
|
||||
loop
|
||||
while left < right and pivot >= vec(left) loop
|
||||
left := left + 1;
|
||||
end loop;
|
||||
while pivot < vec(right) loop
|
||||
right := right - 1;
|
||||
end loop;
|
||||
|
||||
exit when right <= left;
|
||||
|
||||
swap(left, right);
|
||||
left := left + 1;
|
||||
right := right - 1;
|
||||
end loop;
|
||||
|
||||
if right = high then
|
||||
right := right - 1;
|
||||
swap(low, high);
|
||||
end if;
|
||||
|
||||
if left = low then
|
||||
left := left - 1;
|
||||
end if;
|
||||
|
||||
quicksort(vec, low, right);
|
||||
quicksort(vec, left, high);
|
||||
end if;
|
||||
end quicksort;
|
||||
|
||||
procedure quicksort(vec: in out T_Vecteur; vec_index: in out Vector_Entier.T_Vecteur;
|
||||
low: Natural := 0; high: Natural := Capacite-1) is
|
||||
|
||||
procedure swap(left, right: Natural) is
|
||||
tmp : constant T_Digit := vec(left);
|
||||
tmp_index : constant Natural := vec_index(left);
|
||||
begin
|
||||
vec(left) := vec(right);
|
||||
vec(right) := tmp;
|
||||
vec_index(left) := vec_index(right);
|
||||
vec_index(right) := tmp_index;
|
||||
end swap;
|
||||
|
||||
pivot : constant T_Digit := vec(low);
|
||||
right : Natural := high;
|
||||
left : Natural := low;
|
||||
|
||||
begin
|
||||
if high - low > 0 then
|
||||
loop
|
||||
while left < right and pivot >= vec(left) loop
|
||||
left := left + 1;
|
||||
end loop;
|
||||
while pivot < vec(right) loop
|
||||
right := right - 1;
|
||||
end loop;
|
||||
|
||||
exit when right <= left;
|
||||
|
||||
swap(left, right);
|
||||
left := left + 1;
|
||||
right := right - 1;
|
||||
end loop;
|
||||
|
||||
if right = high then
|
||||
right := right - 1;
|
||||
swap(low, high);
|
||||
end if;
|
||||
|
||||
if left = low then
|
||||
left := left - 1;
|
||||
end if;
|
||||
|
||||
quicksort(vec, vec_index, low, right);
|
||||
quicksort(vec, vec_index, left, high);
|
||||
end if;
|
||||
end quicksort;
|
||||
|
||||
end Digit;
|
||||
|
||||
package body Link is
|
||||
|
||||
procedure put(vec: in T_Vecteur) is
|
||||
begin
|
||||
for i in 0..Capacite-1 loop
|
||||
put(vec(i).from); put(" -> "); put(vec(i).to); new_line;
|
||||
end loop;
|
||||
end put;
|
||||
|
||||
procedure is_sorted_and_uniq(vec: in T_Vecteur; dupe: out Natural; sorted: out Boolean) is
|
||||
last: T_Link := vec(0);
|
||||
begin
|
||||
sorted := True;
|
||||
dupe := 0;
|
||||
for i in 1..Capacite-1 loop
|
||||
if vec(i) < last then
|
||||
sorted := False;
|
||||
elsif vec(i) = last then
|
||||
dupe := dupe + 1;
|
||||
end if;
|
||||
last := vec(i);
|
||||
end loop;
|
||||
end is_sorted_and_uniq;
|
||||
|
||||
function "<"(left, right: in T_Link) return Boolean is
|
||||
begin
|
||||
if left.from < right.from then
|
||||
return True;
|
||||
elsif left.from = right.from then
|
||||
return left.to < right.to;
|
||||
else
|
||||
return False;
|
||||
end if;
|
||||
end "<";
|
||||
|
||||
procedure quicksort(vec: in out T_Vecteur; low: Natural := 0; high: Natural := Capacite-1) is
|
||||
|
||||
procedure swap(left, right: Natural) is
|
||||
tmp : constant T_Link := T_Link'(vec(left).from, vec(left).to);
|
||||
begin
|
||||
vec(left).from := vec(right).from;
|
||||
vec(right).from := tmp.from;
|
||||
vec(left).to := vec(right).to;
|
||||
vec(right).to := tmp.to;
|
||||
end swap;
|
||||
|
||||
pivot : constant T_Link := T_Link'(vec(low).from, vec(low).to);
|
||||
left : Natural := low;
|
||||
right : Natural := high;
|
||||
|
||||
begin
|
||||
if high > low then
|
||||
loop
|
||||
while left < right and not(pivot < vec(left)) loop
|
||||
left := left + 1;
|
||||
end loop;
|
||||
while pivot < vec(right) loop
|
||||
right := right - 1;
|
||||
end loop;
|
||||
|
||||
exit when right <= left;
|
||||
|
||||
swap(left, right);
|
||||
left := left + 1;
|
||||
right := right - 1;
|
||||
end loop;
|
||||
|
||||
if right = high then
|
||||
right := right - 1;
|
||||
swap(low, high);
|
||||
end if;
|
||||
|
||||
if left = low then
|
||||
left := left - 1;
|
||||
end if;
|
||||
|
||||
quicksort(vec, low, right);
|
||||
quicksort(vec, left, high);
|
||||
end if;
|
||||
end quicksort;
|
||||
|
||||
end Link;
|
||||
end Reel;
|
||||
|
||||
end Vector;
|
||||
|
|
|
@ -2,35 +2,39 @@ with Ada.Text_IO; use Ada.Text_IO;
|
|||
|
||||
package Vector is
|
||||
|
||||
-- explication:
|
||||
-- Nous avons choisit de créer des sous-modules simplement pour pouvoir tout regroupe dans un seul fichier
|
||||
-- Nous avons aussi séparé les vecteurs d'entiers des vecteurs de flottant, car créer un seul et unique module permettant
|
||||
-- la gestion d'entier ou de flottant était trop compliqué. Le code aurait été plus compliqué à lire.
|
||||
-- nous avons alors choiss de séparer comme ceci le code, bien que cela produise du code un peu redondant.
|
||||
-- on crée 2 sous modules pour chaque type de base
|
||||
-- créer un seul et même module pour les deux types à la fois est compliqué à réaliser.
|
||||
|
||||
generic
|
||||
|
||||
type T_Entier is range <>;
|
||||
Capacite: Positive;
|
||||
|
||||
package Entier is
|
||||
|
||||
type T_Vecteur is array (0..Capacite-1) of Natural;
|
||||
-- on permet l'affichage direct des T_Entier
|
||||
package Text_T_Entier is
|
||||
new Ada.Text_IO.Integer_IO(Num => T_Entier);
|
||||
use Text_T_Entier;
|
||||
|
||||
type T_Vecteur is array (0..Capacite-1) of T_Entier;
|
||||
|
||||
-- permet d'initialiser le vecteur avec pour tout i, vec[i] = value
|
||||
procedure initialize(vec: in out T_Vecteur; value: in Natural);
|
||||
procedure initialize(vec: in out T_Vecteur; value: in T_Entier);
|
||||
|
||||
-- permet d'initialiser le vecteur avec pour tout i, vec[i] = i
|
||||
procedure identity(vec: in out T_Vecteur);
|
||||
|
||||
-- comme en proba, on calcule "la fonction de répartition" du vecteur
|
||||
procedure repartition(vec: in out T_Vecteur);
|
||||
|
||||
-- permet de renverser le vecteur, équivalent vec[::-1] en python
|
||||
procedure flip(vec: in out T_Vecteur);
|
||||
|
||||
-- procédure permettant d'afficher les vecteurs et d'écrire dans des fichiers
|
||||
-- print to console
|
||||
procedure put(vec: in T_Vecteur);
|
||||
procedure put(file: in out Ada.Text_IO.File_Type; vec: in T_Vecteur);
|
||||
|
||||
-- procédure permettant de trier le vecteur selon l'algorithme de quicksort
|
||||
procedure quicksort(vec: in out T_Vecteur; low: Natural := 0; high: Natural := Capacite-1);
|
||||
-- print to file
|
||||
procedure put(file: in Ada.Text_IO.File_Type; vec: in T_Vecteur);
|
||||
|
||||
end Entier;
|
||||
|
||||
|
@ -38,62 +42,32 @@ package Vector is
|
|||
|
||||
generic
|
||||
|
||||
type T_Digit is digits <>;
|
||||
type T_Reel is digits <>;
|
||||
Capacite: Positive;
|
||||
with package Vector_Entier is new Vector.Entier(Capacite => Capacite);
|
||||
|
||||
package Digit is
|
||||
package Reel is
|
||||
|
||||
-- on permet l'affichage direct des T_Digit
|
||||
package Text_T_Element is
|
||||
new Ada.Text_IO.Float_IO(Num => T_Digit);
|
||||
use Text_T_Element;
|
||||
-- on permet l'affichage direct des T_Reel
|
||||
package Text_T_Reel is
|
||||
new Ada.Text_IO.Float_IO(Num => T_Reel);
|
||||
use Text_T_Reel;
|
||||
|
||||
type T_Vecteur is array (0..Capacite-1) of T_Digit;
|
||||
type T_Vecteur is array (0..Capacite-1) of T_Reel;
|
||||
|
||||
procedure initialize(vec: in out T_Vecteur; value: in T_Digit);
|
||||
|
||||
--
|
||||
function sum(vec: in T_Vecteur) return T_Digit;
|
||||
-- permet d'initialiser le vecteur avec pour tout i, vec[i] = value
|
||||
procedure initialize(vec: in out T_Vecteur; value: in T_Reel);
|
||||
|
||||
-- somme toutes les valeurs du vecteur
|
||||
function sum(vec: in T_Vecteur) return T_Reel;
|
||||
|
||||
-- permet de renverser le vecteur, équivalent vec[::-1] en python
|
||||
procedure flip(vec: in out T_Vecteur);
|
||||
|
||||
-- print to console
|
||||
procedure put(vec: in T_Vecteur);
|
||||
procedure put(file: in out Ada.Text_IO.File_Type; vec: in T_Vecteur);
|
||||
-- print to file
|
||||
procedure put(file: in Ada.Text_IO.File_Type; vec: in T_Vecteur);
|
||||
|
||||
procedure quicksort(vec: in out T_Vecteur; low: Natural := 0; high: Natural := Capacite-1);
|
||||
|
||||
-- procédure permettant de trier le vecteur selon l'algorithme quicksort et aussi de récupérer les indices triés.
|
||||
procedure quicksort(vec: in out T_Vecteur; vec_index: in out Vector_Entier.T_Vecteur;
|
||||
low: Natural := 0; high: Natural := Capacite-1);
|
||||
|
||||
end Digit;
|
||||
|
||||
|
||||
|
||||
-- nous avons choisis de modéliser le réseau via cette structure d'un vecteur d'enregistrement plutot que d'un matrice
|
||||
-- avec deux colonnes car de cette manière le trie du réseau est plus simple.
|
||||
|
||||
generic
|
||||
|
||||
Capacite: Positive;
|
||||
|
||||
package Link is
|
||||
|
||||
type T_Link is record
|
||||
from: Natural;
|
||||
to: Natural;
|
||||
end record;
|
||||
|
||||
type T_Vecteur is array (0..Capacite-1) of T_Link;
|
||||
|
||||
procedure put(vec: in T_Vecteur);
|
||||
|
||||
procedure is_sorted_and_uniq(vec: in T_Vecteur; dupe: out Natural; sorted: out Boolean);
|
||||
function "<"(left, right: in T_Link) return Boolean;
|
||||
procedure quicksort(vec: in out T_Vecteur; low: Natural := 0; high: Natural := Capacite-1);
|
||||
|
||||
end Link;
|
||||
end Reel;
|
||||
|
||||
end Vector;
|
||||
|
|
|
@ -2,13 +2,40 @@
|
|||
|
||||
ulimit -s unlimited
|
||||
|
||||
echo "$(tput setaf 2)command: make clean$(tput setaf 7)"
|
||||
make clean
|
||||
echo
|
||||
colormake
|
||||
echo "$(tput setaf 2)command: make$(tput setaf 7)"
|
||||
make
|
||||
echo
|
||||
|
||||
echo "$(tput setaf 2)command: build/pagerank -P fichiers_test/Exemple_sujet/exemple_sujet.net$(tput setaf 7)"
|
||||
build/pagerank -P fichiers_test/Exemple_sujet/exemple_sujet.net
|
||||
echo "$(tput setaf 2)command: build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net -h$(tput setaf 7)"
|
||||
build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net -h
|
||||
echo "$(tput setaf 2)command: build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net --help$(tput setaf 7)"
|
||||
build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net --help
|
||||
|
||||
echo "$(tput setaf 2)command: build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net -a 0.1$(tput setaf 7)"
|
||||
build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net -a 0.1
|
||||
echo "$(tput setaf 2)command: build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net --alpha 0.1$(tput setaf 7)"
|
||||
build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net --alpha 0.1
|
||||
|
||||
echo "$(tput setaf 2)command: build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net -i 100$(tput setaf 7)"
|
||||
build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net -i 100
|
||||
echo "$(tput setaf 2)command: build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net --ite-max 100$(tput setaf 7)"
|
||||
build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net --ite-max 100
|
||||
|
||||
echo "$(tput setaf 2)command: build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net -i abcd$(tput setaf 7)"
|
||||
build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net -i abcd
|
||||
echo "$(tput setaf 2)command: build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net -a abcd$(tput setaf 7)"
|
||||
build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net -a abcd
|
||||
echo "$(tput setaf 2)command: build/pagerank$(tput setaf 7)"
|
||||
build/pagerank
|
||||
echo "$(tput setaf 2)command: build/pagerank -i 100$(tput setaf 7)"
|
||||
build/pagerank -i 100
|
||||
|
||||
echo "$(tput setaf 2)command: build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net --naif$(tput setaf 7)"
|
||||
build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net --naif
|
||||
echo "$(tput setaf 2)command: build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net -n$(tput setaf 7)"
|
||||
build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net -n
|
||||
echo
|
||||
cmp --silent \
|
||||
fichiers_test/Exemple_sujet/exemple_sujet_GH05.ord \
|
||||
|
@ -20,8 +47,8 @@ cmp --silent \
|
|||
|| echo "$(tput setaf 1)exemple_sujet .p files are different$(tput setaf 7)"
|
||||
echo
|
||||
|
||||
echo "$(tput setaf 2)command: build/pagerank -P fichiers_test/Worm/worm.net$(tput setaf 7)"
|
||||
build/pagerank -P fichiers_test/Worm/worm.net
|
||||
echo "$(tput setaf 2)command: build/pagerank fichiers_test/Worm/worm.net -n$(tput setaf 7)"
|
||||
build/pagerank fichiers_test/Worm/worm.net -n
|
||||
echo
|
||||
cmp --silent \
|
||||
fichiers_test/Worm/worm_GH05.ord \
|
||||
|
@ -33,8 +60,8 @@ cmp --silent \
|
|||
|| echo "$(tput setaf 1)worm .p files are different$(tput setaf 7)"
|
||||
echo
|
||||
|
||||
echo "$(tput setaf 2)command: build/pagerank -P fichiers_test/Brainlinks/brainlinks.net$(tput setaf 7)"
|
||||
build/pagerank -P fichiers_test/Brainlinks/brainlinks.net
|
||||
echo "$(tput setaf 2)command: build/pagerank fichiers_test/Brainlinks/brainlinks.net -n$(tput setaf 7)"
|
||||
build/pagerank fichiers_test/Brainlinks/brainlinks.net -n
|
||||
echo
|
||||
cmp --silent \
|
||||
fichiers_test/Brainlinks/brainlinks_GH05.ord \
|
||||
|
@ -46,7 +73,48 @@ cmp --silent \
|
|||
|| echo "$(tput setaf 1)brainlinks .p files are different$(tput setaf 7)"
|
||||
echo
|
||||
|
||||
#build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net
|
||||
#build/pagerank fichiers_test/Worm/worm.net
|
||||
#build/pagerank fichiers_test/Brainlinks/brainlinks.net
|
||||
#build/pagerank fichiers_test/Linux26/Linux26.net
|
||||
|
||||
echo "$(tput setaf 2)command: build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net$(tput setaf 7)"
|
||||
build/pagerank fichiers_test/Exemple_sujet/exemple_sujet.net
|
||||
echo
|
||||
cmp --silent \
|
||||
fichiers_test/Exemple_sujet/exemple_sujet_GH05.ord \
|
||||
fichiers_test/Exemple_sujet/exemple_sujet.ord \
|
||||
|| echo "$(tput setaf 1)exemple_sujet .ord files are different$(tput setaf 7)"
|
||||
cmp --silent \
|
||||
fichiers_test/Exemple_sujet/exemple_sujet_GH05.p \
|
||||
fichiers_test/Exemple_sujet/exemple_sujet_P_6.p \
|
||||
|| echo "$(tput setaf 1)exemple_sujet .p files are different$(tput setaf 7)"
|
||||
echo
|
||||
|
||||
echo "$(tput setaf 2)command: build/pagerank fichiers_test/Worm/worm.net$(tput setaf 7)"
|
||||
build/pagerank fichiers_test/Worm/worm.net
|
||||
echo
|
||||
cmp --silent \
|
||||
fichiers_test/Worm/worm_GH05.ord \
|
||||
fichiers_test/Worm/worm.ord \
|
||||
|| echo "$(tput setaf 1)worm .ord files are different$(tput setaf 7)"
|
||||
cmp --silent \
|
||||
fichiers_test/Worm/worm_GH05.p \
|
||||
fichiers_test/Worm/worm_P_6.p \
|
||||
|| echo "$(tput setaf 1)worm .p files are different$(tput setaf 7)"
|
||||
echo
|
||||
|
||||
echo "$(tput setaf 2)command: build/pagerank fichiers_test/Brainlinks/brainlinks.net$(tput setaf 7)"
|
||||
build/pagerank fichiers_test/Brainlinks/brainlinks.net
|
||||
echo
|
||||
cmp --silent \
|
||||
fichiers_test/Brainlinks/brainlinks_GH05.ord \
|
||||
fichiers_test/Brainlinks/brainlinks.ord \
|
||||
|| echo "$(tput setaf 1)brainlinks .ord files are different$(tput setaf 7)"
|
||||
cmp --silent \
|
||||
fichiers_test/Brainlinks/brainlinks_GH05.p \
|
||||
fichiers_test/Brainlinks/brainlinks_P_6.p \
|
||||
|| echo "$(tput setaf 1)brainlinks .p files are different$(tput setaf 7)"
|
||||
echo
|
||||
|
||||
# echo "$(tput setaf 2)command: build/pagerank fichiers_test/Linux26/Linux26.net$(tput setaf 7)"
|
||||
# build/pagerank fichiers_test/Linux26/Linux26.net
|
||||
# echo
|
||||
|
||||
echo "$(tput setaf 2)TESTS OK$(tput setaf 7)"
|
||||
|
|
Loading…
Reference in a new issue