diff --git a/include/db.h b/include/db.h new file mode 100644 index 0000000000000000000000000000000000000000..c4a0157965486762021e1b9c034fa14b4cbceff9 --- /dev/null +++ b/include/db.h @@ -0,0 +1,22 @@ +#pragma once + +#include "list.h" + +/* file mode : text or binary */ +typedef enum file_mode { TEXT, BINARY } file_mode_t; + +/** + * @brief read a list from a text or binary file acording to the mode + * @param mode : TEXT or BIN + * @param data_read_fct : ptr to fct that reads datum from file fd ; fct's parameters : (fd, mode) + * @param del_fct : ptr to fct that deallocate datum's memory, ; fct's parameter (datum) + */ +list_t * read_list ( file_mode_t mode, void * (*read_fct) (), void (*del_fct) () ); + + +/** + * @brief write a list into a text or binary file acording to the mode + * @param mode : TEXT or BIN + * @param data_write_fct : ptr to fct that writes datum into file fd ; fct's parameters : (datum, fd, mode) + */ +void write_list ( list_t * L, file_mode_t mode, void (*write_fct) () ); \ No newline at end of file diff --git a/include/job.h b/include/job.h new file mode 100644 index 0000000000000000000000000000000000000000..a3bbc2b114cb92c6687a2d6d9ceccee5f6dd5374 --- /dev/null +++ b/include/job.h @@ -0,0 +1,48 @@ +#pragma once + +#include "list.h" +#include <stdbool.h> + +#define UNDEF -2 + +/** Des redondances possibles avec d'autres TAs ! */ +typedef struct { + char * title; // Nom de la tâche + double life; // Durée de la tâche + int input_degree; // Son degré de dépendance + int output_degree; // Les tâches qui en dépendent + int rank; // Rang de la tâche + int dyn_input_degree; // Facilité de prog + list_t * precedence; // Les tâches précédentes + list_t * posteriority; // Les tâches ultérieures + double au_plus_tot; // Date au plus tôt + double au_plus_tard; // Date au plus tard + double marge_totale; // Marge totale + double marge_libre; // Marge libre + bool critique; // Une tâche critique ? +} job_t; + +job_t * new_empty_job(); +job_t * new_job(char * title); +void free_job(job_t ** ptrJ); +void view_job ( job_t * J ); +char * get_job_title(job_t * J); +void set_job_title(job_t * J, char * title); +double get_job_life(job_t * J); +void set_job_life(job_t * J, double life); +int get_job_iDegree(job_t * J); +void set_job_iDegree(job_t * J, int iDegree); +void incr_job_iDegree(job_t * J); +void decr_job_iDegree(job_t * J); + +int get_job_oDegree(job_t * J); +void set_job_oDegree(job_t * J, int oDegree); +void incr_job_oDegree(job_t * J); +void decr_job_oDegree(job_t * J); +int get_job_rank(job_t * J); +void set_rank(job_t * J, int rank); +int titleJobCmp(job_t * J1, job_t * J2); +int iDegreeJobCmp(job_t * J1, job_t * J2); +int oDegreeJobCmp(job_t * J1, job_t * J2); +int rangJobCmp(job_t * J1, job_t * J2); + diff --git a/include/list.h b/include/list.h new file mode 100644 index 0000000000000000000000000000000000000000..f843d10bb956cb20e37e5af99f31ca144aece881 --- /dev/null +++ b/include/list.h @@ -0,0 +1,33 @@ +#pragma once + +#include <stdbool.h> +#include "list_elm.h" + +typedef struct list { + list_elm_t * head; + list_elm_t* tail; + int numelm; +} list_t; + +list_t * new_list(); +void del_list ( list_t * * L, void (*ptrf) () ); +bool empty_list ( list_t * L ); + +list_elm_t * get_head ( list_t * L ); +list_elm_t * get_tail ( list_t * L ); +void view_list ( list_t * L, void (*ptrf)() ); + +void cons ( list_t * L, void * data ); +void queue ( list_t * L, void * data ); +void ordered_insert ( list_t * L, void * data, int (*cmpFct)() ); + +int get_numelm(list_t * L); + +// void take_out(struct list_t * L, void * D); +void quick_sort(list_t * L, int (*cmpFct)()); +void find(list_t * L, void ** ptrKey, int (*cmpFct)(), void (*delFct)()); +void del_list(list_t ** ptrL, void (*ptrf) ()); +void clean(list_t * L); +bool is_empty(list_t * L); + + diff --git a/include/list_elm.h b/include/list_elm.h new file mode 100644 index 0000000000000000000000000000000000000000..621dd3228dcc74a6159166ec3c348991527dc1b6 --- /dev/null +++ b/include/list_elm.h @@ -0,0 +1,24 @@ +#pragma once + +typedef struct list_elm { + void * data; + struct list_elm * suc, * pred; +} list_elm_t; + +list_elm_t * new_list_elm ( void * data ); +/** + * @brief delete the list element E and optionnaly its datum + * @param ptrf : a ptr to fct that deallocates datum's memory ; + * if ptrf is NULL, datum is not freed + */ +void del_list_elm( list_elm_t * * E, void (*ptrf)() ); + +list_elm_t * get_suc ( list_elm_t * E ); +list_elm_t * get_pred ( list_elm_t * E ); +void * get_data ( list_elm_t * E ); + +void set_suc ( list_elm_t * E, list_elm_t * S ); +void set_pred ( list_elm_t * E, list_elm_t * P ); +void set_data ( list_elm_t * E, void * data ); + +void view_list_elm ( list_elm_t * E, void (*ptrf)() ); diff --git a/include/outils.h b/include/outils.h new file mode 100644 index 0000000000000000000000000000000000000000..79f54e3f28be988e287dc41050e54cee63b19905 --- /dev/null +++ b/include/outils.h @@ -0,0 +1,9 @@ +#pragma once + +#define EPSILON 0.00000001// ε = 10^{-8} + +/** Integer comparaison */ +int int_cmp ( int * a, int * b ); + +/** Double comparaison */ +int double_cmp ( double * a, double * b ); \ No newline at end of file diff --git a/include/rank.h b/include/rank.h new file mode 100644 index 0000000000000000000000000000000000000000..9ba383b24053103aa527f09ea8211159fc5249cb --- /dev/null +++ b/include/rank.h @@ -0,0 +1,10 @@ +#pragma once + +#include "list.h" + + +void ranking(list_t * G); +void prune(list_t * G); + +void marges(list_t * G); + diff --git a/makefile b/makefile new file mode 100644 index 0000000000000000000000000000000000000000..8d48e778bd0e09ecba2dbe7ccc818215b82d12eb --- /dev/null +++ b/makefile @@ -0,0 +1,38 @@ +BDIR = bin +IDIR = include +ODIR = obj +SDIR = src + +CC = gcc +# Le déboggage en toutes circonstances grâce à :: -D _DEBUG_ +# que l'on peutarêter à tout moment grâce à :: -U _DEBUG_ +CFLAGS = -Wall -I$(IDIR) -g -c +LFLAGS = -lm + +PROG = $(BDIR)/mpm + +_DEPS = job.h list.h list_elm.h outils.h #rank.h +DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS)) + +_OBJS = db.o io.o job.o list.o list_elm.o main.o outils.o #rank.o +OBJS = $(patsubst %,$(ODIR)/%,$(_OBJS)) + +.PHONY : run all dirs clean delete + +run : all + ./$(PROG) + +all : dirs $(OBJS) + $(CC) -o $(PROG) $(OBJS) $(LFLAGS) + +dirs : + mkdir -p $(ODIR) $(BDIR) + +$(ODIR)/%.o : $(SDIR)/%.c $(DEPS) + $(CC) $(CFLAGS) -o $@ $< + +clean : + rm -rf $(ODIR) + +delete : clean + rm -rf $(BDIR) \ No newline at end of file diff --git a/obj/db.o b/obj/db.o new file mode 100644 index 0000000000000000000000000000000000000000..02a8690f0be0218bc1f329379cdd0383219ac9fd Binary files /dev/null and b/obj/db.o differ diff --git a/obj/io.o b/obj/io.o new file mode 100644 index 0000000000000000000000000000000000000000..10bee52ae486bc83610bea63e627baa252d403ca Binary files /dev/null and b/obj/io.o differ diff --git a/readme.md b/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/db.c b/src/db.c new file mode 100644 index 0000000000000000000000000000000000000000..b26b108f88d3de9266f593a5df1baf651a47eb7d --- /dev/null +++ b/src/db.c @@ -0,0 +1,74 @@ +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include "db.h" +#include "list.h" +#include "list_elm.h" + +list_t * read_list( file_mode_t mode, void * (*read_fct) (), void (*del_fct) () ) { + FILE * fd; + char fname[20]; + list_t * L = new_list(); + + if (mode == TEXT) {// Open file in TEXT mode + printf( "\t\tRead list from text file (.txt)\n\tfile name :" ); + scanf( "%s", fname ); + fd = fopen( fname, "rt" ); + } + else {// open file in BIN mode + printf( "\t\tRead list from binary file (.bin)\n\tfile name :" ); + scanf( "%s", fname ); + fd = fopen( fname, "rb" ); + } + //todo + void * datum; + while ((datum = read_fct(fd, mode)) != NULL) { + queue(L, datum); + } + + + list_elm_t * E = get_tail(L); + if (E != NULL && empty_list(E->data)) { + list_elm_t * T = get_pred(E); + if (T != NULL) { + set_suc(T, NULL); + L->tail = T; + } else { + L->head = L->tail = NULL; + } + del_list_elm(&E, del_fct); + } + + /** TODO parcourir le fichier pour y collecter les formulaires et les ranger dans la L + ATTENTION : + il est **possible** que vous créiez un élément de trop (un formulaire vide) en fin de liste. + Il faut alors penser à le supprimer grâce au code suivant : + E = get_tail (L); + struct elmlist * T = getPred(E); + set_suc(T, NULL); + L->tail = T; + del_elmlist(E, ptr_del); + */ + + + fclose(fd); + return L; + } +void write_list( list_t * L, file_mode_t mode, void (*write_fct) () ) { + FILE * fd; + char fname[20]; + if (mode == TEXT) { + printf( "\t\tWrite list to text file (.txt)\n\tfile name :"), scanf( "%s", fname ); + fd = fopen( fname, "wt" ); + } else { + printf("\t\tWrite list to binary file (.bin)\n\tfile name :"), scanf( "%s", fname ); + fd = fopen(fname, "wb" ); + } + + for (list_elm_t * elm = get_head(L); elm != NULL; elm = elm->suc){ + write_fct(elm->data, mode, fd); + } + /// @todo Parcourir L et écrire les formulaires grâce à data_write_fct + fclose(fd); +} + diff --git a/src/io.c b/src/io.c new file mode 100644 index 0000000000000000000000000000000000000000..aafeda62a9a41ca88b3ba9f9d4967632e3076d27 --- /dev/null +++ b/src/io.c @@ -0,0 +1,141 @@ +#include "list.h" +#include "list_elm.h" +#include "job.h" +#include "list.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +list_t * read_graph ( char * filename ) { + FILE * fd = fopen ( filename, "rt" ); + list_t * G = new_list ( ); + assert ( fd && G ); + char job_name [ BUFSIZ ]; + + while ( !feof ( fd ) ) { + + fscanf ( fd, " %s", job_name); + if ( !strcmp (job_name, "NIL" ) ) continue; + + job_t * J = new_job ( job_name ); + + /** @note + À l'appel J pointe sur le job que l'on vient de créer. + + FIND retrouve le job J dans la liste G des jobs grâce à la fonction titleJobCmp. + Si ce job n'est pas dans la liste G alors + le job pointé par J est enregistré dans G + Si ce job est déjà dans G alors + le job pointé par J est supprimé grâce à free_job + puis le pointeur de J est réassigné sur le job trouvé dans G + */ + find ( G, ( void ** ) &J, &titleJobCmp, &free_job ); + + fscanf ( fd, "%lf", &(J->life) ); + + /** @note + Enregistrement des préséances + */ + job_t * predJ; + fscanf( fd, " %s", job_name ); + while ( strcmp ( job_name, "NIL" ) ) { + predJ = new_job ( job_name ); + //SOUVIENS SI &TITTLEJOBCMP = &SETJOBTITLE + find ( G, (void **) &predJ, &titleJobCmp, &free_job ); + + ordered_insert ( predJ->posteriority, J, &titleJobCmp ); + incr_job_oDegree ( predJ ); + + ordered_insert ( J->precedence, predJ, &titleJobCmp ); + incr_job_iDegree ( J ); + + fscanf ( fd, " %s", job_name ); + } + + /** @note valeurs par défaut des autres champs */ + J->dyn_input_degree = J->input_degree; + J->rank = UNDEF; + J->au_plus_tard = UNDEF; + J->au_plus_tot = UNDEF; + J->marge_totale = UNDEF; + J->critique = false; + } + + view_list(G,&view_job); + return G; +} + +static void partition(list_t * L, elmlist_t * pivot, list_t * val_inf, list_t * val_sup, int (*cmpFct)(void*, void*)) { + for (elmlist_t * cur = L->head; cur != NULL; cur = cur->suc) { + if (cmpFct(get_data(cur), get_data(pivot)) < 0) + queue(val_inf, get_data(cur)); + else + queue(val_sup, get_data(cur)); + } +} + +void quick_sort(list_t * L, int (*cmpFct)(void*, void*)) { + assert(L && cmpFct); + + if (L->numelm > 1) { + //CONFIRMER LE STRUCT + struct list_elm_t * pivot = get_head(L); + L->head = get_suc(pivot); + pivot->pred = NULL; + pivot->suc = NULL; + + + /** @note + * La listes des données inférieures à pivot + * La listes des données supérieures à pivot + */ + list_t * val_inf_pivot = new_list(); + list_t * val_sup_pivot = new_list(); + + /** @note Déplacement des données de L dans val_inf_pivot et val_sup_pivot */ + partition(L,pivot,val_inf_pivot,val_sup_pivot,cmpFct); + + /** @note On supprimer les éléments de L sans supprimer ni L ni les jobs */ + // elmlist_t * S; + // for(elmlist_t * E = L->head; E; E = S){ + // S = E->suc; + // free(E); + // } + + /** @note + * Si la partie inf est vide alors L commence par le pivot + * Sinon on tri grâce à cmpFct la partie inf puis on ajoute en queue le pivot + */ + + + if (is_empty(val_inf_pivot)) { + L->head = pivot; + L->tail = pivot; + L->numelm = 1; + } else { + quick_sort(val_inf_pivot, cmpFct); + L->head = val_inf_pivot->head; + L->tail = val_inf_pivot->tail; + L->numelm = val_inf_pivot->numelm; + pivot->pred = L->tail; + L->tail->suc = pivot; + L->tail = pivot; + L->numelm += 1; + } + /** @note + * Si la partie sup n'est pas vide alors + * On la trie puis on la concatène à la partie inf + */ + if (!is_empty(val_sup_pivot)) { + quick_sort(val_sup_pivot, cmpFct); + val_sup_pivot->head->pred = pivot; + set_suc(pivot, val_sup_pivot->head); + L->tail = val_sup_pivot->tail; + L->numelm += val_sup_pivot->numelm; + } + free(val_inf_pivot); + free(val_sup_pivot); + } +} \ No newline at end of file diff --git a/src/job.c b/src/job.c new file mode 100644 index 0000000000000000000000000000000000000000..dc5002cc6077faf394d4d51de9d51c15c954ea54 --- /dev/null +++ b/src/job.c @@ -0,0 +1,55 @@ +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include <string.h> +#include "job.h" +#include "list.h" + +job_t * new_empty_job ( ) { + job_t * J = calloc ( 1, sizeof (job_t ) ); + assert( J ); + J->precedence = new_list ( ); + J->posteriority = new_list ( ); + J->rank = UNDEF; + J->au_plus_tard = UNDEF; + J->au_plus_tot = UNDEF; + J->marge_totale = UNDEF; + J->critique = false; + return J; +} +job_t * new_job ( char * title ) { + job_t * J = new_empty_job ( ); + J->title = strdup ( title ); + return J; +} +void free_job(job_t ** ptrJ ) { + assert ( ptrJ && *ptrJ ); + if( (*ptrJ)->title ) free ( (*ptrJ)->title ); + free ( *ptrJ ); + *ptrJ = NULL; +} + +void view_job ( job_t * J ) { + printf ( "JOB %s\n\tpreceeded by [", get_job_tilte ( J ) ); + for(elmlist_t * E = get_head ( J->precedence ); E; E = get_suc ( E ) ) { + printf ( " %s", get_job_tilte ( get_data ( E ) ) ); + } + printf ( " ]\n" ); + // if ( !get_numelm ( J->posteriority ) ) printf ( "\t" ); + printf ( "\tfollowed by [" ); + for(elmlist_t * E = get_head(J->posteriority); E; E = get_suc(E)){ + printf(" %s", get_job_tilte(get_data(E))); + } + printf ( " ]\n" ); + printf ( "\tiDeg=%d\toDeg=%d\tlife=%2.2lf", J->input_degree, J->output_degree, J->life ); + printf ( "\trank=" ); + if ( J->rank == UNDEF ) printf ( "U" ); else printf ( "%d", J->rank ); + printf ( "\tearly=" ); + if(J->au_plus_tot == UNDEF ) printf("U"); else printf ( "%2.2lf",J->au_plus_tot ); + printf ( "\tlate=" ); + if(J->au_plus_tard == UNDEF ) printf("U"); else printf ( "%2.2lf",J->au_plus_tard ); + printf ( "\ttotale= " ); + if ( J->marge_totale == UNDEF ) printf("U"); else printf ( "%2.2lf", J->marge_totale ); + printf ( "\tcritical= " ); + if ( J->critique ) printf("Y\n"); else printf ( "N\n" ); +} diff --git a/src/job_2.c b/src/job_2.c new file mode 100644 index 0000000000000000000000000000000000000000..76c8897c629fe8bdff813c648b4eab6e91f69d3c --- /dev/null +++ b/src/job_2.c @@ -0,0 +1,111 @@ +#include "job.h" +#include "list.h" +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +job_t * new_empty_job(){ + job_t * J = calloc ( 1, sizeof (job_t ) ); + assert( J ); + J->precedence = new_list ( ); + J->posteriority = new_list ( ); + J->rank = UNDEF; + J->au_plus_tard = UNDEF; + J->au_plus_tot = UNDEF; + J->marge_totale = UNDEF; + J->critique = false; + return J; +} + +job_t * new_job(char * title){ + job_t * J = new_empty_job ( ); + J->title = strdup ( title ); + return J; +} + +void free_job(job_t ** ptrJ){ + assert ( ptrJ && *ptrJ ); + if( (*ptrJ)->title ) free ( (*ptrJ)->title ); + free ( *ptrJ ); + *ptrJ = NULL; +} + +void view_job ( job_t * J ) { + printf ( "JOB %s\n\tpreceeded by [", get_job_tilte ( J ) ); + for(elmlist_t * E = get_head ( J->precedence ); E; E = get_suc ( E ) ) { + printf ( " %s", get_job_tilte ( get_data ( E ) ) ); + } + printf ( " ]\n" ); + // if ( !get_numelm ( J->posteriority ) ) printf ( "\t" ); + printf ( "\tfollowed by [" ); + for(elmlist_t * E = get_head(J->posteriority); E; E = get_suc(E)){ + printf(" %s", get_job_tilte(get_data(E))); + } + printf ( " ]\n" ); + printf ( "\tiDeg=%d\toDeg=%d\tlife=%2.2lf", J->input_degree, J->output_degree, J->life ); + printf ( "\trank=" ); + if ( J->rank == UNDEF ) printf ( "U" ); else printf ( "%d", J->rank ); + printf ( "\tearly=" ); + if(J->au_plus_tot == UNDEF ) printf("U"); else printf ( "%2.2lf",J->au_plus_tot ); + printf ( "\tlate=" ); + if(J->au_plus_tard == UNDEF ) printf("U"); else printf ( "%2.2lf",J->au_plus_tard ); + printf ( "\ttotale= " ); + if ( J->marge_totale == UNDEF ) printf("U"); else printf ( "%2.2lf", J->marge_totale ); + printf ( "\tcritical= " ); + if ( J->critique ) printf("Y\n"); else printf ( "N\n" ); +} + +char * get_job_title(job_t * J) { + assert(J); + return J->title; +} + +void titleJobCmp(job_t * J, char * title){ + + + +} + +void set_job_title(job_t * J, char * title) { + assert(J && title); + if(J->title) + free(J->title); + J->title = strdup(title); +} + + +double get_job_life(job_t * J) { + assert(J); + return J->life; +} + + +void set_job_life(job_t * J, double life) { + assert(J); + J->life = life; +} + + +int get_job_iDegree(job_t * J) { + assert(J); + return J->input_degree; +} + + +void set_job_iDegree(job_t * J, int iDegree) { + assert(J); + J->input_degree = iDegree; +} + + +void incr_job_iDegree(job_t * J) { + assert(J); + J->input_degree++; +} + + +void decr_job_iDegree(job_t * J) { + assert(J); + J->input_degree--; +} \ No newline at end of file diff --git a/src/job_3.c b/src/job_3.c new file mode 100644 index 0000000000000000000000000000000000000000..6ac6944036af9438a4d02686609d6536ca115c44 --- /dev/null +++ b/src/job_3.c @@ -0,0 +1,55 @@ +#include "job.h" +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +//TOUS EST CHANGee +int get_job_oDegree(job_t * J) { + assert(J); + return J->output_degree; +} + +void set_job_oDegree(job_t * J, int oDegree) { + assert(J); + J->output_degree = oDegree; +} + +void incr_job_oDegree(job_t * J) { + assert(J); + J->output_degree++; +} + +void decr_job_oDegree(job_t * J) { + assert(J); + J->output_degree--; +} + +int get_job_rank(job_t * J) { + assert(J); + return J->rank; +} + +void set_rank(job_t * J, int rank) { + assert(J); + J->rank = rank; +} + +int titleJobCmp(job_t * J1, job_t * J2) { + assert(J1 && J2); + return strcmp(J1->title, J2->title); +} + +int iDegreeJobCmp(job_t * J1, job_t * J2) { + assert(J1 && J2); + return J1->input_degree - J2->input_degree; +} + +int oDegreeJobCmp(job_t * J1, job_t * J2) { + assert(J1 && J2); + return J1->output_degree - J2->output_degree; +} + +int rangJobCmp(job_t * J1, job_t * J2) { + assert(J1 && J2); + return J1->rank - J2->rank; +} diff --git a/src/list.c b/src/list.c new file mode 100644 index 0000000000000000000000000000000000000000..7032f0b3d1614b7d525cfd25a625e16e40eeca66 --- /dev/null +++ b/src/list.c @@ -0,0 +1,103 @@ +#include <stdlib.h> +#include <assert.h> +#include "list.h" +#include "list_elm.h" + +list_t * new_list() { + list_t * L = calloc(1, sizeof(list_t)); + assert(L); + L->head = NULL; + L->tail = NULL; + L->numelm = 0; + return L; +} + +void del_list(list_t ** L, void (*ptr_del)(void *)) { + assert(L && *L); + list_t * list = *L; + list_elm_t * E = list->head; + while (E) { + list_elm_t * temp = E; + E = E->suc; + if(ptr_del) { + ptr_del(temp->data); + } + free(temp); + } + free(*L); + *L = NULL; +} + +bool empty_list(list_t * L) { + assert(L); + return L->numelm == 0; +} + +list_elm_t * get_head(list_t * L) { + assert(L); + return L->head; +} + +list_elm_t * get_tail(list_t * L) { + assert(L); + return L->tail; +} + +void view_list(list_t * L, void (*ptr_view)(void *)) { + assert(L && ptr_view); + for (list_elm_t * E = L->head; E != NULL; E = get_suc(E)) { + ptr_view(E->data); + } +} + +void cons(list_t * L, void * data) { + list_elm_t * E = new_list_elm(data); + E->suc = L->head; + if (L->head != NULL) { + L->head->pred = E; + } + L->head = E; + if (L->tail == NULL) { + L->tail = E; + } + L->numelm++; +} + +void queue(list_t * L, void * data) { + list_elm_t * E = new_list_elm(data); + if(empty_list(L)) { + L->head = E; + L->tail = E; + } else { + L->tail->suc = E; + E->pred = L->tail; + L->tail = E; + } + L->numelm++; +} + +void insert_after(list_t * L, void * data, list_elm_t * elm) { + if(elm == NULL) return; + list_elm_t * E = new_list_elm(data); + E->suc = elm->suc; + E->pred = elm; + if(elm->suc != NULL) { + elm->suc->pred = E; + } else { + L->tail = E; + } + elm->suc = E; + L->numelm++; +} + +void ordered_insert(list_t * L, void * data, int (*cmpFct)(void*, void*)) { + if(empty_list(L) || cmpFct(L->head->data, data) > 0) { + cons(L, data); + } else { + list_elm_t * current = L->head; + while(get_suc(current) != NULL && cmpFct(get_suc(current)->data, data) <= 0) { + current = get_suc(current); + } + insert_after(L, data, current); + } +} diff --git a/src/list_1 (1).c b/src/list_1 (1).c new file mode 100644 index 0000000000000000000000000000000000000000..ef9df30293f795e48da03e19b70ddab29d65bed9 --- /dev/null +++ b/src/list_1 (1).c @@ -0,0 +1,74 @@ +#include "list_1 (1).h" +#include "list" +#include <stdlib.h> +#include <stdbool.h> +#include <stdio.h> +#include <assert.h> + +typedef struct{ + elmlist_t * head; + elmlist_t * tail; + int numelm; + } list_t ; + // Create an empty list + list_t * new_list(){ + list_t * t = calloc(1, sizeof(list_t)); + assert(t); + return t; + } + // Delete list, its elements and possibly the data + //DOIT CONFIRMER LE STRUCT + void del_list(list_t ** ptrL, void (*ptrf) ()){ + assert(ptrL && *ptrL); + list_t * L = *ptrL; + if(ptrf){ + for(elmlist_t * E = L->head; E; ){ + elmlist_t * T = E; + E = E->suc; + (*ptrf)(T->data); + free(T); + } + } + } else { + for(elmlist_t * E = L->head; E ; ){ + elmlist_t * T = E; + E = E->suc; + free(T); + } + free(*ptrL); + (*ptrL) = NULL; +} + // Clean list; delete its elments but keep data and the list + void clean(list_t * L){ + assert(L); + elmlist_t *curr = L->head; + while (curr != NULL) { + elmlist_t *temp = curr; + curr = curr->suc; + free(temp); + } + L->head = NULL; + L->tail = NULL; + L->numelm = 0; +} + // Is list L empty ? + bool is_empty(list_t * L){ + assert(L); + if (L->numelm == 0) return true; + return false; + } + + elmlist_t * get_head(list_t * L){ + assert(L); + L = L->head; + return L; + } + + elmlist_t * get_tail(list_t * L){ + assert(L); + L = L->tail; + return L; + } + + + \ No newline at end of file diff --git a/src/list_2.c b/src/list_2.c new file mode 100644 index 0000000000000000000000000000000000000000..ed867d3c8d7217ea6321afb1404c48dbfb069be8 --- /dev/null +++ b/src/list_2.c @@ -0,0 +1,226 @@ +#include "list_1 (1).h" +#include "list.h" +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> + +// Gimme the number of elements of L +int get_numelm(struct list_t * L){ + assert(L); + return L->numelm; +} +// Take out the data D of the list L if it is present +void take_out(struct list_t * L, void * D){ + assert(L); + elmlist_t * current = L->head; + while (current != NULL) { + if (get_data(current) == D) { + elmlist_t * p = get_pred(current); + elmlist_t * s = get_suc(current); + // Update predecessor’s successor + if (p) set_suc(p, s); + else L->head = s; // current was head + // Update successor’s predecessor + if (s) set_pred(s, p); + else L->tail = p; // current was tail + free(current); + L->numelm--; + return; + } + current = get_suc(current); + } +} + +// Add a element holding data to the head of L +void cons(struct list_t * L, void * data){ + elmlist_t * E = calloc(1, sizeof(elmlist_t)); + assert(L && E); + set_data(E, data); + set_suc(E, L->head); + set_head(L, E); + if(is_empty(L)) L->tail = E; + L->numelm += 1; + } + + + + +// Add a element holding data to the tail of L +void queue(struct list_t * L, void * data){ + assert(L); + elmlist_t * E = calloc(1, sizeof(elmlist_t)); + assert(E); + set_data(E, data); + E->suc = NULL; + if (is_empty(L)) { + E->pred = NULL; + L->head = E; + L->tail = E; + } else { + E->pred = L->tail; + L->tail->suc = E; + L->tail = E; + } + L->numelm++; + } +// Insert in L a element holding data wrt order given by cmp_ptrf +void ordered_insert(struct list_t * L, void * data, int (*cmp_ptrf)()){ + assert(L && cmp_ptrf); + elmlist_t * E = calloc(1, sizeof(elmlist_t)); + assert(E); + set_data(E, data); + // if list is empty, simply add the element + if (is_empty(L)) { + E->pred = E->suc = NULL; + L->head = L->tail = E; + L->numelm++; + return; + } +} + +// Elements qui sont moins = val_inf et le reste val_sup. +static void partition(list_t * L, elmlist_t * pivot, list_t * val_inf, list_t * val_sup, int (*cmpFct)(void*, void*)) { + for (elmlist_t * cur = L->head; cur != NULL; cur = cur->suc) { + if (cmpFct(get_data(cur), get_data(pivot)) < 0) + queue(val_inf, get_data(cur)); + else + queue(val_sup, get_data(cur)); + } +} + +void quick_sort(list_t * L, int (*cmpFct)(void*, void*)) { + assert(L && cmpFct); + + if (L->numelm > 1) { + + elmlist_t * pivot = get_head(L); + L->head = get_suc(pivot); + pivot->pred = NULL; + pivot->suc = NULL; + + + /** @note + * La listes des données inférieures à pivot + * La listes des données supérieures à pivot + */ + list_t * val_inf_pivot = new_list(); + list_t * val_sup_pivot = new_list(); + + /** @note Déplacement des données de L dans val_inf_pivot et val_sup_pivot */ + partition(L,pivot,val_inf_pivot,val_sup_pivot,cmpFct); + + /** @note On supprimer les éléments de L sans supprimer ni L ni les jobs */ + // elmlist_t * S; + // for(elmlist_t * E = L->head; E; E = S){ + // S = E->suc; + // free(E); + // } + + /** @note + * Si la partie inf est vide alors L commence par le pivot + * Sinon on tri grâce à cmpFct la partie inf puis on ajoute en queue le pivot + */ + + + if (is_empty(val_inf_pivot)) { + L->head = pivot; + L->tail = pivot; + L->numelm = 1; + } else { + quick_sort(val_inf_pivot, cmpFct); + L->head = val_inf_pivot->head; + L->tail = val_inf_pivot->tail; + L->numelm = val_inf_pivot->numelm; + pivot->pred = L->tail; + L->tail->suc = pivot; + L->tail = pivot; + L->numelm += 1; + } + /** @note + * Si la partie sup n'est pas vide alors + * On la trie puis on la concatène à la partie inf + */ + if (!is_empty(val_sup_pivot)) { + quick_sort(val_sup_pivot, cmpFct); + val_sup_pivot->head->pred = pivot; + pivot->suc = val_sup_pivot->head; + L->tail = val_sup_pivot->tail; + L->numelm += val_sup_pivot->numelm; + } + free(val_inf_pivot); + free(val_sup_pivot); + } +} + +// void quick_sort(list_t * L, int (*cmpFct)()){ + +// if (L == NULL || L->numelm < 2) +// return; + + +// elmlist_t * pivotNode = L->head; +// void * pivotData = pivotNode->data; + + +// list_t * less = new_list(); +// list_t * greater = new_list(); + + +// for (elmlist_t * cur = L->head; cur != NULL; cur = cur->suc) { + +// if (cur == pivotNode) +// continue; + +// if (cmpFct(cur->data, pivotData) < 0) +// queue(less, cur->data); +// else +// queue(greater, cur->data); +// } + + +// clean(L); + + +// quick_sort(less, cmpFct); +// quick_sort(greater, cmpFct); + +// for (elmlist_t * node = less->head; node != NULL; node = node->suc) +// queue(L, node->data); + + +// queue(L, pivotData); + +// for (elmlist_t * node = greater->head; node != NULL; node = node->suc) +// queue(L, node->data); + +// free(less); +// free(greater); +// } + + + + + +void view_list(list_t * L, void (*ptrf)()) { + assert(L && ptrf); + elmlist_t * curr = L->head; + while (curr) { + ptrf(get_data(curr)); + curr = curr->suc; + } + +} +// Return un ptr vers element else NULL +void find(list_t * L, void ** ptrKey, int (*cmpFct)(), void (*delFct)()) { + assert(L && ptrKey && cmpFct); + elmlist_t * curr = L->head; + while (curr) { + if (cmpFct(get_data(curr), *ptrKey) == 0) { + if (delFct) + delFct(ptrKey); + *ptrKey = get_data(curr); + return; + } + curr = curr->suc; + } +} diff --git a/src/list_elm.c b/src/list_elm.c new file mode 100644 index 0000000000000000000000000000000000000000..aa173dfff979ad64483a740e38fcb96bc7977d6b --- /dev/null +++ b/src/list_elm.c @@ -0,0 +1,52 @@ +#include <stdlib.h> +#include <assert.h> +#include "list_elm.h" + +list_elm_t * new_list_elm ( void * data ){ + list_elm_t * E = calloc(1,sizeof(list_elm_t)); + assert(E); + E->data = data; + return E; +} + +void del_list_elm( list_elm_t * * E, void (*ptrf)() ){ + assert(E && *E); + if (ptrf) { + ptrf((*E)->data); + } + free(*E); + *E = NULL; +} + +list_elm_t * get_suc ( list_elm_t * E ){ + assert(E); + return E->suc; +} +list_elm_t * get_pred ( list_elm_t * E ); +void * get_data ( list_elm_t * E ){ + assert(E); + return E->data; +} + +void set_suc ( list_elm_t * E, list_elm_t * S ){ + assert(E); + E->suc = S; +} + +void set_pred ( list_elm_t * E, list_elm_t * P ){ + assert(E); + E->pred = P; +} + +void set_data ( list_elm_t * E, void * data ){ + assert(E); + E->data = data; +} + +void view_list_elm ( list_elm_t * E, void (*ptrf)() ){ + assert(E && ptrf); + for(elmlist_t * courant = E->head; courant; courant = get_suc(E)){ + void * data = E->data; + (*ptrf)(data); + } +} \ No newline at end of file diff --git a/src/main (1).c b/src/main (1).c new file mode 100644 index 0000000000000000000000000000000000000000..5bb714ba220f0f322ccdfd5505a945425a638a11 --- /dev/null +++ b/src/main (1).c @@ -0,0 +1,32 @@ +#include <stdio.h> +#include <stdlib.h> + +#include "job.h" +#include "list.h" +#include "list_elm.h" + + +int main(int argc, char ** argv){ + if(argc < 2) exit(-1); + + list_t * G = read_graph(argv[1]); + printf("Liste des tâches lue\n"); + view_list(G, &view_job); + + printf("Liste des tâches triée par degré d'entrée croissant\n"); + quick_sort(G, &iDegreeJobCmp); + view_list(G,&view_job); + + printf("Liste des tâches triée par rang croissant\n"); + ranking(G); + view_list(G,&view_job); + + printf("Prune edges\n"); + prune(G); + view_list(G,&view_job); + + printf("\nMarges totales des tâches\n"); + marges(G); + view_list(G,&view_job); + return 0; +} diff --git a/src/outils.c b/src/outils.c new file mode 100644 index 0000000000000000000000000000000000000000..99f432bab42df93f3d155dcc5895506e8cd65ec4 --- /dev/null +++ b/src/outils.c @@ -0,0 +1,13 @@ +#include "outils.h" + + + +/** Integer comparaison */ +int int_cmp(int * a, int * b){ + return *a - *b; +} + +/** Double comparaison */ +int double_cmp(double * a, double * b){ + return ((*a - *b) < -EPSILON) ? -1 : ((*a -*b) > +EPSILON) ? +1 : 0; +} diff --git a/src/rank.c b/src/rank.c new file mode 100644 index 0000000000000000000000000000000000000000..1d1438c50d0035f3b9bfc0ed377f7f0d82cbb2ac --- /dev/null +++ b/src/rank.c @@ -0,0 +1,19 @@ +#include "rank.h" +#include "list_1 (1).h" +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> + + +void ranking(list_t * G){ + +} +void prune(list_t * G){ +assert(G); + +} + +void marges(list_t * G){ +assert(G); + +} \ No newline at end of file