Skip to content
Snippets Groups Projects
Commit 6ebea867 authored by agnon.kurteshi's avatar agnon.kurteshi
Browse files

99.9%

parent 1b7b2ff1
No related branches found
No related tags found
No related merge requests found
#include "fourmi.h" #include "fourmi.h"
frmi create_fourmi() frmi create_fourmi(int nb_sommet)
{ {
frmi fr = malloc(sizeof(f)); frmi fr = malloc(sizeof(f));
fr->path = malloc(sizeof(stack)); fr->path = malloc(sizeof(stack));
stack_init(fr->path, 100); stack_init(fr->path, nb_sommet);
fr->distance = 0; fr->distance = 0;
fr->ttl = 7; fr->ttl = nb_sommet;
return fr; return fr;
} }
......
...@@ -19,7 +19,7 @@ typedef struct _fourmi ...@@ -19,7 +19,7 @@ typedef struct _fourmi
typedef f *frmi; typedef f *frmi;
frmi create_fourmi(); frmi create_fourmi(int nb_sommet);
void destroy_fourmi(frmi f); void destroy_fourmi(frmi f);
......
8 0 7
0 1 2.0
1 2 5.0
2 1 5.0
1 3 2.0
3 1 1.0
1 5 2.0
2 3 1.0
2 6 4.0
3 4 4.0
3 5 2.0
3 6 3.0
3 7 4.0
4 7 2.0
6 7 2.0
...@@ -17,12 +17,13 @@ graph create_graph(int num, int fourmiliere, int nourriture) ...@@ -17,12 +17,13 @@ graph create_graph(int num, int fourmiliere, int nourriture)
matrix *mat2 = malloc(sizeof(matrix)); matrix *mat2 = malloc(sizeof(matrix));
matrix_init(mat2, num, num, 1); matrix_init(mat2, num, num, 1);
gr->pheromone = mat2; gr->pheromone = mat2;
//initialisation des variables de la matrice
gr->foumiliere = fourmiliere; gr->foumiliere = fourmiliere;
gr->nourriture = nourriture; gr->nourriture = nourriture;
return gr; return gr;
} }
int has_edge(graph g, int from_node, int to_node) int has_edge(graph g, int from_node, int to_node) //permet de contrôle s'il y a une arête entre deux sommets
{ {
assert(g != NULL); assert(g != NULL);
assert(from_node < g->num); assert(from_node < g->num);
...@@ -30,7 +31,7 @@ int has_edge(graph g, int from_node, int to_node) ...@@ -30,7 +31,7 @@ int has_edge(graph g, int from_node, int to_node)
return g->edges->data[from_node][to_node]; return g->edges->data[from_node][to_node];
} }
void add_edge(graph g, int from_node, int to_node, double distance) void add_edge(graph g, int from_node, int to_node, double distance) //permet d'ajouter une arête entre deux sommets
{ {
assert(g != NULL); assert(g != NULL);
assert(from_node < g->num); assert(from_node < g->num);
...@@ -43,54 +44,65 @@ void add_edge(graph g, int from_node, int to_node, double distance) ...@@ -43,54 +44,65 @@ void add_edge(graph g, int from_node, int to_node, double distance)
g->edges->data[from_node][to_node] = distance; g->edges->data[from_node][to_node] = distance;
} }
int nb_voisin(graph g, int noeud) graph main_create_graph(char *filename) //crée la matrice à partir d'un fichier csv
{ {
int nb_noeud = 0; graph g;
for (int i = 0; i < g->num; i++) FILE *fp;
{ char buffer[100];
if (has_edge(g, noeud, i))
fp = fopen(filename, "r"); //ouverture fichier
//contrôle ouverture fichier
if (fp == NULL)
{ {
nb_noeud++; printf("non ouvert\n");
}
}
return nb_noeud;
} }
double ph_x_dist(graph g, int from, int to) int line_counter = 0;
while (fgets(buffer, 100, fp) != NULL)
{ {
double ph_x_dst = g->pheromone->data[from][to] * (1 / g->edges->data[from][to]);
return ph_x_dst;
}
stack ants_path(stack frmi, int path) int a, b;
int c_int;
double c;
//récupérer les données de la première ligne qui indique les informations de la matrice
if (line_counter == 0)
{ {
stack_push(&frmi, path); sscanf(buffer, "%d %d %d", &a, &b, &c_int);
return frmi; g = create_graph(a, b, c_int);
} }
void pheromone_dissipation(graph g, int rho) else //récupère les données pour créer les arêtes en les sommets
{ {
for (int from = 0; from < g->num; from++) sscanf(buffer, "%d %d %lf", &a, &b, &c);
{ add_edge(g, a, b, c);
for (int to = 0; to < g->num; to++)
{
g->pheromone->data[from][to] = (1 - rho) * g->pheromone->data[from][to];
} }
line_counter++;
} }
fclose(fp);
return g;
}
//afin d'alléger le code la fonction ci-dessous permet de calculer [phéromone * (1/arête)]
double ph_x_dist(graph g, int from, int to)
{
double ph_x_dst = g->pheromone->data[from][to] * (1 / g->edges->data[from][to]);
return ph_x_dst;
} }
int path_probability_taken(graph g, int noeud) int path_probability_taken(graph g, int noeud)
{ {
// initialisation des tableaux à 0
double tab[g->num]; double tab[g->num];
double tab_cumul[g->num]; double tab_cumul[g->num];
// initialisation des tableaux à 0
for (int k = 0; k < g->num; k++) for (int k = 0; k < g->num; k++)
{ {
tab[k] = 0; tab[k] = 0;
tab_cumul[k] = 0; tab_cumul[k] = 0;
} }
// mettre les phéromones aux places du tableau pour le choix de l'indicee // mettre les phéromones aux places du tableau pour le choix de l'indicee
//cette partie du code va créer un double qui sera le dénominateur pour nos calculs du chemin
double somme_pour_proba = 0; double somme_pour_proba = 0;
for (int r = 0; r < g->num; r++) for (int r = 0; r < g->num; r++)
{ {
...@@ -99,14 +111,20 @@ int path_probability_taken(graph g, int noeud) ...@@ -99,14 +111,20 @@ int path_probability_taken(graph g, int noeud)
somme_pour_proba += ph_x_dist(g, noeud, r); somme_pour_proba += ph_x_dist(g, noeud, r);
} }
} }
//si la fourmi ne trouve pas de chemin, il y a une division par 0, mais surtout, elle ne peut choisir aucun chemin
//donc on retourne directement le noeud
if (somme_pour_proba == 0) if (somme_pour_proba == 0)
{ {
return noeud; return noeud;
} }
//A partir de là, le tableau qui stocke
for (int i = 0; i < g->num; i++) for (int i = 0; i < g->num; i++)
{ {
if (has_edge(g, noeud, i)) if (has_edge(g, noeud, i))
{ {
//calcul qui fait [(phéromone * (1/arête))]
// [-----------------------] //fraction
// [ 2 ]
tab[i] = (g->pheromone->data[noeud][i] * (1.0 / g->edges->data[noeud][i])) / somme_pour_proba; tab[i] = (g->pheromone->data[noeud][i] * (1.0 / g->edges->data[noeud][i])) / somme_pour_proba;
} }
} }
...@@ -126,10 +144,10 @@ int path_probability_taken(graph g, int noeud) ...@@ -126,10 +144,10 @@ int path_probability_taken(graph g, int noeud)
} }
// calcul de la probabilité // calcul de la probabilité
double chemin_probabiliste = (double)rand() / (double)RAND_MAX; // nb entre 0 et 1 double chemin_probabiliste = (double)rand() / (double)RAND_MAX; // nb entre 0 et 1 pour choisir le chemin à prendre
for (int z = 0; z < g->num; z++) for (int z = 0; z < g->num; z++) //tester toutes les cases du tablea
{ {
if (chemin_probabiliste <= tab_cumul[z]) if (chemin_probabiliste <= tab_cumul[z]) //si le nombre probabilite est plus petit que la case du tableau, on retourne la case
{ {
return z; return z;
} }
...@@ -139,7 +157,7 @@ int path_probability_taken(graph g, int noeud) ...@@ -139,7 +157,7 @@ int path_probability_taken(graph g, int noeud)
double pheromone_depose(double distance) double pheromone_depose(double distance)
{ {
return 1.0000 / distance; return 1.0000 / distance; //la phéromone est déposée en fonction de la longueur parcourue
} }
int launch_colonization(graph g, int nb_fourmi, double rho) int launch_colonization(graph g, int nb_fourmi, double rho)
...@@ -147,61 +165,52 @@ int launch_colonization(graph g, int nb_fourmi, double rho) ...@@ -147,61 +165,52 @@ int launch_colonization(graph g, int nb_fourmi, double rho)
int nb_fourmi_perdue = 0; int nb_fourmi_perdue = 0;
for (int i = 0; i < nb_fourmi; i++) for (int i = 0; i < nb_fourmi; i++)
{ {
frmi f = create_fourmi(); frmi f = create_fourmi(g->num); //crée la fourmi
nb_fourmi_perdue += random_path(g, 0, rho, f); nb_fourmi_perdue += random_path(g, 0, rho, f); //appel la fonction principal à l'algorithme
destroy_fourmi(f); destroy_fourmi(f); //détruit la fourmi
} }
//retourne le nombre de fourmi perdu
return nb_fourmi_perdue; return nb_fourmi_perdue;
} }
int random_path(graph g, int noeud, double rho, frmi f) int random_path(graph g, int noeud, double rho, frmi f)
{ {
// f->ttl--;
// condition d'arret si on arrive au noeud final ou si le ttl est à 0 // condition d'arret si on arrive au noeud final ou si le ttl est à 0
if (noeud == g->nourriture) if (noeud == g->nourriture)
{ {
f->depose_pheromone = 1; f->depose_pheromone = 1;
return 0; return 0;
} }
////////////////////////////////////////////////////////////////////////
// calcul chemin aléatoire et renvoi l'indice du chemin à prendre // calcul chemin aléatoire et renvoi l'indice du chemin à prendre
int chemin_aleatoire; int chemin_aleatoire;
// do
// {
chemin_aleatoire = path_probability_taken(g, noeud); chemin_aleatoire = path_probability_taken(g, noeud);
//si le noeud retourné par le chemin est le même que celui par lequel il est rentré, c'est que le chemin n'as pas de sortie
if (chemin_aleatoire == noeud) if (chemin_aleatoire == noeud)
{ {
f->depose_pheromone = 0; f->depose_pheromone = 0;
return 1; return 1;
} }
// } while (!has_edge(g, noeud, chemin_aleatoire));
//-----------------------------------------------------------------
// stocke la distance parcourue dans la fourmi // stocke la distance parcourue dans la fourmi
f->distance += g->edges->data[noeud][chemin_aleatoire]; f->distance += g->edges->data[noeud][chemin_aleatoire];
// push le chemin parcouru dans la stack de la fourmi // push le chemin parcouru dans la stack de la fourmi
stack_push(f->path, noeud); stack_push(f->path, noeud);
stack_push(f->path, chemin_aleatoire); stack_push(f->path, chemin_aleatoire);
// la récursivité de l'algorithme (parcours graphe en profondeur) // la récursivité de l'algorithme (parcours graphe en profondeur)
//récursivité de l'algorithme
int fourmi_perdu; int fourmi_perdu;
fourmi_perdu = random_path(g, chemin_aleatoire, rho, f); fourmi_perdu = random_path(g, chemin_aleatoire, rho, f);
// if(f->ttl == 0)
// {
// return;
// }
if (f->depose_pheromone) if (f->depose_pheromone)
{ {
g->pheromone->data[noeud][chemin_aleatoire] = ((1 - rho) * g->pheromone->data[noeud][chemin_aleatoire]) + pheromone_depose(f->distance); g->pheromone->data[noeud][chemin_aleatoire] = ((1 - rho) * g->pheromone->data[noeud][chemin_aleatoire]) + pheromone_depose(f->distance);
} }
// print_stack(*f->path); //permet le calcul du nombre de fourmi perdu récursivement
// if(noeud == 0)
// {
// pheromone_dissipation(g);
// }
if (fourmi_perdu) if (fourmi_perdu)
{ {
return 1; return 1;
} }
//si la fourmi n'est pas perdu
return 0; return 0;
} }
...@@ -229,7 +238,8 @@ void create_graph_vis(graph g) ...@@ -229,7 +238,8 @@ void create_graph_vis(graph g)
void shortest_path(graph g, frmi f, int noeud) void shortest_path(graph g, frmi f, int noeud)
{ {
if (noeud == g->nourriture) f->ttl--;
if (noeud == g->nourriture || f->ttl == 0)
{ {
stack_push(f->path, noeud); stack_push(f->path, noeud);
return; return;
...@@ -238,8 +248,7 @@ void shortest_path(graph g, frmi f, int noeud) ...@@ -238,8 +248,7 @@ void shortest_path(graph g, frmi f, int noeud)
int index = 0; int index = 0;
for (int i = 0; i < g->num; i++) for (int i = 0; i < g->num; i++)
{ {
if (g->pheromone->data[noeud][i] > bigger && g->pheromone->data[noeud][i] != 1.0)
if (g->pheromone->data[noeud][i] > bigger || g->pheromone->data[noeud][i] != 1.0)
{ {
bigger = g->pheromone->data[noeud][i]; bigger = g->pheromone->data[noeud][i];
index = i; index = i;
...@@ -252,9 +261,39 @@ void shortest_path(graph g, frmi f, int noeud) ...@@ -252,9 +261,39 @@ void shortest_path(graph g, frmi f, int noeud)
} }
} }
void display_graph_vis() void export_shortest_path(graph g1, char *filename)
{
int ecrit_chemin = 0;
int trash;
FILE *file = fopen(filename, "w");
fprintf(file, "the shortest path is \n");
frmi eclaireuse = create_fourmi(g1->num);
shortest_path(g1, eclaireuse, 0);
if (eclaireuse->path->top == g1->num - 1)
{
destroy_fourmi(eclaireuse);
printf("Aucun chemin ne peut être défini\n");
return;
}
printf("shortest path is : ");
print_stack(*eclaireuse->path);
while (!stack_is_empty(*eclaireuse->path))
{ {
stack_pop(eclaireuse->path, &trash);
fprintf(file, "[%d]", eclaireuse->path->data[ecrit_chemin]);
ecrit_chemin++;
}
printf("\n");
destroy_fourmi(eclaireuse);
fclose(file);
}
void display_graph_vis()
{
//appel système pour lancer graphviz
system("dot -Tpng -O test2.dot"); system("dot -Tpng -O test2.dot");
system("xdg-open test2.dot.png"); system("xdg-open test2.dot.png");
} }
......
#include <stdio.h> #include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h>
#include <time.h> #include <time.h>
#include "../matrix/matrix.h" #include "../matrix/matrix.h"
#include "../stack/stack.h" #include "../stack/stack.h"
...@@ -24,12 +25,16 @@ int has_edge(graph g, int from_node, int to_node); ...@@ -24,12 +25,16 @@ int has_edge(graph g, int from_node, int to_node);
void add_edge(graph g, int from_node, int to_node, double distance); void add_edge(graph g, int from_node, int to_node, double distance);
void export_shortest_path(graph g1, char *filename);
int nb_voisin(graph g, int noeud); int nb_voisin(graph g, int noeud);
int random_path(graph g, int noeud, double rho, frmi f); int random_path(graph g, int noeud, double rho, frmi f);
int launch_colonization(graph g, int nb_fourmi, double rho); int launch_colonization(graph g, int nb_fourmi, double rho);
graph main_create_graph(char *filename);
void shortest_path(graph g, frmi f, int noeud); void shortest_path(graph g, frmi f, int noeud);
// void first_walk(graph g, int index, stack *s); // void first_walk(graph g, int index, stack *s);
......
the shortest path is
[0][1][3][7]
\ No newline at end of file
#include "graphe/graphe.h" #include "graphe/graphe.h"
// #include "stack/stack.h"
int main() int main()
{ {
//initialisation
srand(time(NULL)); srand(time(NULL));
graph g1 = create_graph(8, 0, 7);
stack stack;
stack_init(&stack, 50);
// printf("\n");
// matrix_print(*g1->pheromone);
// printf("\nadded edge\n\n");
add_edge(g1, 0, 1, 2.0);
add_edge(g1, 1, 2, 5.0);
add_edge(g1, 1, 3, 2.0);
add_edge(g1, 1, 5, 2.0);
add_edge(g1, 2, 3, 1.0);
add_edge(g1, 3, 1, 1.0);
add_edge(g1, 2, 6, 4.0);
add_edge(g1, 3, 4, 4.0);
add_edge(g1, 3, 5, 2.0);
add_edge(g1, 3, 6, 3.0);
add_edge(g1, 3, 7, 4.0);
add_edge(g1, 4, 7, 2.0);
add_edge(g1, 6, 7, 2.0);
int nb_fourmi_perdu = 0; int nb_fourmi_perdu = 0;
nb_fourmi_perdu = launch_colonization(g1, 1000000, 0.05); //création du graphe à partir d'un csv
graph g1 = main_create_graph("graphe.csv");
//lancement de la colonisation des fourmis
nb_fourmi_perdu = launch_colonization(g1, 100000, 0.0001);
//impression de la matrice des phéromones et des arêtes
printf("\n length path matrix \n"); printf("\n length path matrix \n");
matrix_print(*g1->edges); matrix_print(*g1->edges);
printf("\npheromone matrix \n"); printf("\npheromone matrix \n");
matrix_print(*g1->pheromone); matrix_print(*g1->pheromone);
printf("number of ants lost : %d\n", nb_fourmi_perdu); printf("number of ants lost : %d\n", nb_fourmi_perdu);
// printf("\npheromone changed\n\n"); //détermine le plus court chemin avec une fourmi éclaireuse et sort le chemin dans un txt
// pheromone_dissipation(g1); export_shortest_path(g1, "le_plus_court_chemin.txt");
// matrix_print(*g1->pheromone); //affichage du graphe dynamique avec l'utilisation de graphviz
// algorithme_des_fourmils(1, 3, g1);
create_graph_vis(g1); create_graph_vis(g1);
display_graph_vis(); display_graph_vis();
frmi eclaireuse = create_fourmi(); //libération de la mémoire
shortest_path(g1, eclaireuse, 0);
printf("shortest path is : ");
print_stack(*eclaireuse->path);
printf("\n");
destroy_fourmi(eclaireuse);
destroy_graph(g1); destroy_graph(g1);
stack_destroy(&stack);
return 0; return 0;
} }
\ No newline at end of file
...@@ -35,14 +35,18 @@ error_code matrix_init(matrix *mat, int li, int co, double val) ...@@ -35,14 +35,18 @@ error_code matrix_init(matrix *mat, int li, int co, double val)
error_code matrix_print(const matrix mat) error_code matrix_print(const matrix mat)
{ {
printf(" 0 1 2 3 4 5 6\n"); printf(" ");
printf(" - - - - -\n"); for(int i = 0; i < mat.cols; i++)
{
printf("%d ", i);
}
printf("\n - - - - -\n");
for(int row = 0; row < mat.rows; row++) for(int row = 0; row < mat.rows; row++)
{ {
printf("%d | ", row); printf("%d | ", row);
for(int col = 0; col < mat.cols; col++) for(int col = 0; col < mat.cols; col++)
{ {
printf("%f ", mat.data[row][col]); printf("%0.2lf ", mat.data[row][col]);
} }
printf("\n"); printf("\n");
} }
...@@ -62,122 +66,3 @@ error_code matrix_destroy(matrix *mat) ...@@ -62,122 +66,3 @@ error_code matrix_destroy(matrix *mat)
free(mat); free(mat);
return ok; return ok;
} }
\ No newline at end of file
// error_code matrix_init_from_array(matrix *mat, int li, int co, int data[], int s) //data [0] = mat->data[0][0] data[3] = mat->data[1][1]
// {
// if(s != li*co)
// {
// return err;
// }
// for(int row = 0; row < li; row++)
// {
// for(int col = 0; col < co; col++)
// {
// mat->data[row][col] = data[col + (row * li)];
// }
// }
// return ok;
// }
// error_code matrix_clone(matrix *cloned, const matrix mat)
// {
// for(int row = 0; row < mat.rows; row++)
// {
// for(int col = 0; col < mat.cols; col++)
// {
// cloned->data[row][col] = mat.data[row][col];
// }
// }
// return ok;
// }
// error_code matrix_transpose(matrix *transposed, const matrix mat)
// {
// for(int row = 0; row < mat.rows; row++)
// {
// for(int col = 0; col < mat.cols; col++)
// {
// transposed->data[col][row] = mat.data[row][col];
// }
// }
// return ok;
// }
// error_code matrix_extract_submatrix(matrix *sub, const matrix mat,int li0, int li1, int co0, int co1)
// {
// int row = li1 - li0;
// int col = co1 - co0;
// if(row < sub->rows || col < sub->cols || row > sub->rows || col > sub->cols)
// {
// return err;
// }
// for(int i = li0; i < li1; i++)
// {
// for(int j = co0; j < co1; j++)
// {
// sub->data[i-li0][j-co0] = mat.data[i][j];
// }
// }
// return ok;
// }
// bool matrix_is_equal(matrix mat1, matrix mat2)
// {
// int estVrai = 1;
// assert(estVrai == 1);
// if(mat1.rows != mat2.rows)
// {
// return false;
// }
// else if(mat1.cols != mat2.cols)
// {
// return false;
// }
// else
// {
// for(int row = 0; row < mat1.rows; row++)
// {
// for(int col = 0; col < mat1.cols; col++)
// {
// if(mat1.data[row][col] != mat2.data[row][col])
// {
// estVrai = 0;
// }
// }
// }
// if(estVrai == 1)
// {
// return true;
// }
// else
// {
// return false;
// }
// }
// }
// error_code matrix_get(int *elem, const matrix mat, int ix, int iy)
// {
// if(ix >= mat.rows || iy >= mat.cols)
// {
// return err;
// }
// else
// {
// *elem = mat.data[ix][iy];
// return ok;
// }
// }
// error_code matrix_set(matrix *mat, int ix, int iy, int elem)
// {
// if(ix >= mat->cols || iy >= mat->cols)
// {
// return err;
// }
// else
// {
// mat->data[ix][iy] = elem;
// return ok;
// }
// }
\ No newline at end of file
...@@ -28,7 +28,7 @@ void stack_push(stack *s, int value) ...@@ -28,7 +28,7 @@ void stack_push(stack *s, int value)
{ {
if(s->top == s->size-1) if(s->top == s->size-1)
{ {
printf("stack full\n"); // printf("stack full\n");
return; return;
} }
else else
......
...@@ -3,6 +3,7 @@ digraph Test { ...@@ -3,6 +3,7 @@ digraph Test {
1->2[penwidth=2, label= 5.000000] 1->2[penwidth=2, label= 5.000000]
1->3[penwidth=2, label= 2.000000] 1->3[penwidth=2, label= 2.000000]
1->5[penwidth=2, label= 2.000000] 1->5[penwidth=2, label= 2.000000]
2->1[penwidth=2, label= 5.000000]
2->3[penwidth=2, label= 1.000000] 2->3[penwidth=2, label= 1.000000]
2->6[penwidth=2, label= 4.000000] 2->6[penwidth=2, label= 4.000000]
3->1[penwidth=2, label= 1.000000] 3->1[penwidth=2, label= 1.000000]
......
test2.dot.png

47.3 KiB | W: | H:

test2.dot.png

49.8 KiB | W: | H:

test2.dot.png
test2.dot.png
test2.dot.png
test2.dot.png
  • 2-up
  • Swipe
  • Onion skin
No preview for this file type
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment