diff --git a/src/BRANCH_AND_BOUND/bb_affichages_traces.c b/src/BRANCH_AND_BOUND/bb_affichages_traces.c index ccfa8fb..0945090 100644 --- a/src/BRANCH_AND_BOUND/bb_affichages_traces.c +++ b/src/BRANCH_AND_BOUND/bb_affichages_traces.c @@ -41,6 +41,14 @@ int AverageG; int AverageI; int AverageK; char Tracer; int cpt; int i; int * pt1 ; char * pt2; # endif +callback_function call_back = (callback_function)Bb->callback; +// TODO else default +if (!call_back) +{ + call_back = SiriusDefaultCallback; +} +void *something_from_the_caller = Bb->something_from_the_caller; + if ( NoeudCourant == Bb->NoeudRacine ) { Bb->TempsDuDernierAffichage = 0; Bb->NombreDeProblemesDepuisLeDernierAffichage = 0; @@ -59,7 +67,9 @@ if ( Bb->NombreDeProblemesResolus > 0 ) { if ( Bb->TempsDexecutionMaximum > 0 ) { if ( TempsEcoule >= Bb->TempsDexecutionMaximum ) { Bb->ArreterLesCalculs = OUI; - if ( Bb->AffichageDesTraces == OUI ) printf("Stopping calculation because time limit reached.\n"); + if (Bb->AffichageDesTraces == OUI) + // is this a WARNING? + call_back(something_from_the_caller, "Stopping calculation because time limit reached.\n", 0, SIRIUS_WARN); } } @@ -74,17 +84,8 @@ if ( Bb->NombreDeProblemesResolus > 0 ) { if ( Bb->NombreDAffichages == 0 || Bb->NombreDAffichages >= CYCLE_DAFFICHAGE_LEGENDE ) { Bb->NombreDAffichages = 0; - printf(" "); - printf("| Nodes |"); - printf(" Depth (max) |"); - printf(" Active nodes |"); - printf(" Sol |"); - printf(" Best Sol. |"); - printf(" Best bound |"); - printf(" Gap %% |"); - printf(" Seconds |"); - printf(" Cuts: average in use (over) |"); - printf("\n"); + const char *msg = " | Nodes | Depth (max) | Active nodes | Sol | Best Sol. | Best bound | Gap %% | Seconds | Cuts: average in use (over) |\n"; + call_back(something_from_the_caller, msg, 0, SIRIUS_INFO); } Bb->NombreDAffichages++; diff --git a/src/BRANCH_AND_BOUND/bb_define.h b/src/BRANCH_AND_BOUND/bb_define.h index bd3040e..b716b2b 100644 --- a/src/BRANCH_AND_BOUND/bb_define.h +++ b/src/BRANCH_AND_BOUND/bb_define.h @@ -336,6 +336,8 @@ int AverageK; /* */ void * ProblemePneDuBb; +void *callback; +void *something_from_the_caller; } BB; /*******************************************************************************************/ diff --git a/src/CALLBACK/sirius_callback.c b/src/CALLBACK/sirius_callback.c new file mode 100644 index 0000000..5286bcb --- /dev/null +++ b/src/CALLBACK/sirius_callback.c @@ -0,0 +1,19 @@ + +#include "sirius_callback.h" +#include + +int SiriusDefaultCallback(void *something_from_the_caller, const char *sMsg, int nLen, SIRIUS_LOGLEVEL log_level) +{ + if (nLen <= 0) + { + return 0; + } + if (log_level == SIRIUS_ERROR) + { + fprintf(stderr, sMsg); + } + else + { + printf("%s", sMsg); + } +} diff --git a/src/CALLBACK/sirius_callback.h b/src/CALLBACK/sirius_callback.h new file mode 100644 index 0000000..f61cecc --- /dev/null +++ b/src/CALLBACK/sirius_callback.h @@ -0,0 +1,22 @@ +#ifdef __cplusplus +extern "C" +{ +#endif +#pragma once + +#define SIRIUS_CALLBACK_BUFFER_SIZE 1024 + typedef enum SIRIUS_LOGLEVEL + { + SIRIUS_TRACE, + SIRIUS_DEBUG, + SIRIUS_INFO, + SIRIUS_WARN, + SIRIUS_ERROR, + SIRIUS_FATAL + } SIRIUS_LOGLEVEL; + typedef int (*callback_function)(void *something_from_the_caller, const char *sMsg, int nLen, SIRIUS_LOGLEVEL log_level); + int SiriusDefaultCallback(void *something_from_the_caller, const char *sMsg, int nLen, SIRIUS_LOGLEVEL log_level); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c6e1e9a..171d8bf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,9 +16,9 @@ MESSAGE("CMAKE_SOURCE_DIR : ${CMAKE_SOURCE_DIR}") SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}) SET( LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}) -INCLUDE_DIRECTORIES(. ALLOCATEUR BRANCH_AND_BOUND POINT_INTERIEUR PRESOLVE SIMPLEXE SIMPLEXE/LU PNE SRS) +INCLUDE_DIRECTORIES(. CALLBACK ALLOCATEUR BRANCH_AND_BOUND POINT_INTERIEUR PRESOLVE SIMPLEXE SIMPLEXE/LU PNE SRS) -FILE(GLOB HEADERS ALLOCATEUR/*.h PRESOLVE/*.h BRANCH_AND_BOUND/*.h POINT_INTERIEUR/*.h SIMPLEXE/*.h SIMPLEXE/LU/*.h ./PNE/*.h ./SRS/*.h) +FILE(GLOB HEADERS ./CALLBACK/*.h ALLOCATEUR/*.h PRESOLVE/*.h BRANCH_AND_BOUND/*.h POINT_INTERIEUR/*.h SIMPLEXE/*.h SIMPLEXE/LU/*.h ./PNE/*.h ./SRS/*.h ) FILE(GLOB ALLOCATEUR_FILES ALLOCATEUR/*.c ALLOCATEUR/*.h) FILE(GLOB PRESOLVE_FILES PRESOLVE/*.c PRESOLVE/*.h) @@ -28,6 +28,7 @@ FILE(GLOB SIMPLEXE_FILES SIMPLEXE/*.c SIMPLEXE/*.h) FILE(GLOB LU_FILES SIMPLEXE/LU/*.c SIMPLEXE/LU/*.h) FILE(GLOB PNE_FILES PNE/*.c PNE/*.h) FILE(GLOB SRS_FILES SRS/*.c SRS/*.h) +FILE(GLOB CALLBACK_FILES CALLBACK/*.h CALLBACK/*.c ) GET_FILENAME_COMPONENT(FULL_PATH_TEST_CPP ${CMAKE_CURRENT_SOURCE_DIR}/PNE/pne_standalone.c ABSOLUTE) MESSAGE("REMOVING FROM SOURCE ${FULL_PATH_TEST_CPP}") @@ -35,8 +36,8 @@ MESSAGE("REMOVING FROM SOURCE ${FULL_PATH_TEST_CPP}") LIST(REMOVE_ITEM PNE_FILES ${FULL_PATH_TEST_CPP}) # MESSAGE("-- PNE_FILES : ${PNE_FILES}") -ADD_LIBRARY(sirius_solver_static STATIC ${ALLOCATEUR_FILES} ${PRESOLVE_FILES} ${BRANCH_AND_BOUND_FILES} ${POINT_INTERIEUR_FILES} ${SIMPLEXE_FILES} ${LU_FILES} ${PNE_FILES} ${SRS_FILES}) -ADD_LIBRARY(sirius_solver SHARED ${ALLOCATEUR_FILES} ${PRESOLVE_FILES} ${BRANCH_AND_BOUND_FILES} ${POINT_INTERIEUR_FILES} ${SIMPLEXE_FILES} ${LU_FILES} ${PNE_FILES} ${SRS_FILES}) +ADD_LIBRARY(sirius_solver_static STATIC ${CALLBACK_FILES} ${ALLOCATEUR_FILES} ${PRESOLVE_FILES} ${BRANCH_AND_BOUND_FILES} ${POINT_INTERIEUR_FILES} ${SIMPLEXE_FILES} ${LU_FILES} ${PNE_FILES} ${SRS_FILES} ) +ADD_LIBRARY(sirius_solver SHARED ${CALLBACK_FILES} ${ALLOCATEUR_FILES} ${PRESOLVE_FILES} ${BRANCH_AND_BOUND_FILES} ${POINT_INTERIEUR_FILES} ${SIMPLEXE_FILES} ${LU_FILES} ${PNE_FILES} ${SRS_FILES} ) #ADD_EXECUTABLE(PNE_STANDALONE PNE/pne_standalone.c ) #ADD_EXECUTABLE(NEWSPX_STANDALONE SPX_STANDALONE/spx_standalone.c ) #ADD_EXECUTABLE(TEST_API TEST_API/main.c ) @@ -58,6 +59,7 @@ SET_TARGET_PROPERTIES(sirius_solver PROPERTIES PUBLIC_HEADER "${HEADERS}") SET_TARGET_PROPERTIES(sirius_solver_static PROPERTIES C_STANDARD 11) SET_TARGET_PROPERTIES(sirius_solver PROPERTIES C_STANDARD 11) target_include_directories(sirius_solver PUBLIC + $ $ $ $) diff --git a/src/PNE/mps_define.h b/src/PNE/mps_define.h index 6dea33f..28580cd 100644 --- a/src/PNE/mps_define.h +++ b/src/PNE/mps_define.h @@ -68,4 +68,7 @@ int * FirstNomVar; int * NomVarSuivant; double objective_offset; +void *callback; +void *something_from_the_caller; + } PROBLEME_MPS; diff --git a/src/PNE/pne_callback.c b/src/PNE/pne_callback.c new file mode 100644 index 0000000..db68864 --- /dev/null +++ b/src/PNE/pne_callback.c @@ -0,0 +1,26 @@ +#include "pne_fonctions.h" +#include "mps_define.h" + +int PNEsetcbmessage(PROBLEME_PNE *problem_pne, callback_function the_callback_function, void *something_from_the_caller, SIRIUS_LOGLEVEL log_level) +{ + problem_pne->callback = the_callback_function; + problem_pne->something_from_the_caller = something_from_the_caller; + // TODO + return 0; +} + +/*int PROBLEME_MPSsetcbmessage(PROBLEME_MPS *problem_mps, callback_function the_callback_function, void *something_from_the_caller, SIRIUS_LOGLEVEL log_level) +{ + problem_mps->callback = the_callback_function; + problem_mps->something_from_the_caller = something_from_the_caller; + // TODO + return 0; +}*/ + +int PROBLEME_A_RESOUDREsetcbmessage(PROBLEME_A_RESOUDRE *probleme_a_resoudre, callback_function the_callback_function, void *something_from_the_caller, SIRIUS_LOGLEVEL log_level) +{ + probleme_a_resoudre->callback = the_callback_function; + probleme_a_resoudre->something_from_the_caller = something_from_the_caller; + // TODO + return 0; +} diff --git a/src/PNE/pne_define.h b/src/PNE/pne_define.h index f7e5436..9bebd31 100644 --- a/src/PNE/pne_define.h +++ b/src/PNE/pne_define.h @@ -592,6 +592,10 @@ jmp_buf Env; double Critere; + + void *callback; + void *something_from_the_caller; + } PROBLEME_PNE; /*******************************************************************************************/ diff --git a/src/PNE/pne_definition_arguments.h b/src/PNE/pne_definition_arguments.h index 94a215c..90c2f70 100644 --- a/src/PNE/pne_definition_arguments.h +++ b/src/PNE/pne_definition_arguments.h @@ -78,7 +78,7 @@ typedef struct { La matrice des contrainte est decrite par les 4 vecteurs qui suivent. Elle doit etre decrite par ligne. -> Les coefficients de la matrice des contraintes doivent etre donnes dans un vecteur double precision. -> En parallele du vecteur des coefficient, il faut donner l'indice colonne du coefficient. - -> Pour chaque ligne (ou premier membre de la contrainte) il faut donner sont indice début dans le vecteur + -> Pour chaque ligne (ou premier membre de la contrainte) il faut donner sont indice d�but dans le vecteur double precision qui contient les coefficients de la contraintes, et le nombre de coefficients non nuls. */ int * IndicesDebutDeLigne ; /* Pour chaque ligne, indice debut de la ligne dans le @@ -104,7 +104,7 @@ La matrice des contrainte est decrite par les 4 vecteurs qui suivent. Elle doit */ /* Options */ char AlgorithmeDeResolution; /* Doit valoir SIMPLEXE ou POINT_INTERIEUR */ - /* Attention, le choix POINT_INTERIEUR ne peut être utilise que dans le cas + /* Attention, le choix POINT_INTERIEUR ne peut �tre utilise que dans le cas d'un probleme ne comportant pas de varaibles entieres */ char AffichageDesTraces; /* Peut valoir OUI_PNE ou NON_PNE */ char SortirLesDonneesDuProbleme; /* Peut valoir OUI_PNE ou NON_PNE. @@ -115,25 +115,28 @@ La matrice des contrainte est decrite par les 4 vecteurs qui suivent. Elle doit solution optimale n'a pas ete trouvee. Attention, cette grandeur n'est prise en compte que si le probleme contient des variables entieres */ /* Mettre 0 si le temps est illimite */ - int NombreMaxDeSolutionsEntieres; /* Lorsque le nombre de solutions entieres est egal à la valeur de ce + int NombreMaxDeSolutionsEntieres; /* Lorsque le nombre de solutions entieres est egal � la valeur de ce parametre, le solveur s'arrete et donne la meilleure solution rencontree. Remarque: mettre une valeur strictement negative pour que ce parametre n'ai pas - de rôle. + de r�le. */ - double ToleranceDOptimalite; /* Si l'écart relatif entre le cout de la solution entiere trouvee et le plus petit minorant - est inférieur à ToleranceDOptimalite, le solveur s'arrete et considère que la solution + double ToleranceDOptimalite; /* Si l'�cart relatif entre le cout de la solution entiere trouvee et le plus petit minorant + est inf�rieur � ToleranceDOptimalite, le solveur s'arrete et consid�re que la solution entiere trouvee est la solution optimale. - Convention: ToleranceDOptimalite doit etre exprimé en %. + Convention: ToleranceDOptimalite doit etre exprim� en %. Conseil : mettre 0 %. */ char CoupesLiftAndProject; /* Utile que s'il y a des variables entieres dans le probleme. Peut valoir OUI_PNE ou NON_PNE. Lorsque cette option vaut OUI_PNE - le calcul des coupes de type lift and project est activé. - - Choix conseillé: NON_PNE car le calcul de ce type de coupe peut être + le calcul des coupes de type lift and project est activ�. + - Choix conseill�: NON_PNE car le calcul de ce type de coupe peut �tre couteux. - Mettre OUI_PNE si le probleme est difficile a resoudre. */ double objective_offset; + void *callback; + void *something_from_the_caller; + } PROBLEME_A_RESOUDRE; diff --git a/src/PNE/pne_fonctions.h b/src/PNE/pne_fonctions.h index 1e7e9ab..301bc01 100644 --- a/src/PNE/pne_fonctions.h +++ b/src/PNE/pne_fonctions.h @@ -26,7 +26,9 @@ de l'inclure pne_constantes_externes.h dans l'appelant. cependant on le recommande comme ca l'utilisateur sera tente d'aller voir ce qu'il y a comme constantes externes ce qui n'est pas plus mal */ - + +#include "sirius_callback.h" +//#include "mps_define.h" /*--------------------------------------------------------------------------------------------------*/ void PNE_SolveurProblemeReduit( PROBLEME_A_RESOUDRE * , CONTROLS * ); @@ -454,6 +456,11 @@ void PNE_MiseAJourDesSeuilDeSelectionDesCoupes( PROBLEME_PNE * ); /* En test: pour detecter les contraintes d'egalite sur des entiere infaisables */ void PNE_DetectionContraintesEntieresInfaisable( PROBLEME_PNE * ); +int PNEsetcbmessage(PROBLEME_PNE *problem_pne, callback_function the_callback_function, void *something_from_the_caller, SIRIUS_LOGLEVEL log_level); +//int PROBLEME_MPSsetcbmessage(PROBLEME_MPS *problem_pne, callback_function the_callback_function, void *something_from_the_caller, SIRIUS_LOGLEVEL log_level); +int PROBLEME_A_RESOUDREsetcbmessage(PROBLEME_A_RESOUDRE *problem_pne, callback_function the_callback_function, void *something_from_the_caller, SIRIUS_LOGLEVEL log_level); + + /*******************************************************************************************/ # define FONCTIONS_PNE_DEJA_DEFINIES # endif diff --git a/src/SIMPLEXE/spx_ajouter_coupes.c b/src/SIMPLEXE/spx_ajouter_coupes.c index 30a1cd4..58ac62d 100644 --- a/src/SIMPLEXE/spx_ajouter_coupes.c +++ b/src/SIMPLEXE/spx_ajouter_coupes.c @@ -109,7 +109,9 @@ CntVarEcartOuArtif = Spx->CntVarEcartOuArtif; NombreDeContraintes = Spx->NombreDeContraintes; NombreDeVariables = Spx->NombreDeVariables; -/* Seules nous interessent les variables natives car pour les autres on sait que ça vaut 1 */ +callback_function call_back = SPXgetcbmessage(Spx); +void *something_from_the_caller = Spx->something_from_the_caller; +/* Seules nous interessent les variables natives car pour les autres on sait que �a vaut 1 */ CNbTermesDeCoupes = Spx->CNbTermesDeCoupes; memset ( (char *) CNbTermesDeCoupes, 0 , Spx->NombreDeVariables * sizeof( int ) ); @@ -212,8 +214,10 @@ for ( Cnt_E = 0 ; Cnt_E < NbContr_E ; Cnt_E++ ) { else if ( PositionDeLaVariableDEcart[Cnt_E] == HORS_BASE_SUR_BORNE_INF ) { PositionDeLaVariable[NombreDeVariables] = HORS_BASE_SUR_BORNE_INF; } - else { - printf("Bug dans le sous programme SPX_AjouterLesCoupes. Arret d'urgence\n"); + else + { + const char *msg = "Bug dans le sous programme SPX_AjouterLesCoupes. Arret d'urgence\n"; + call_back(something_from_the_caller, msg, 0, SIRIUS_FATAL); exit(0); } /* On la met dans l'equation de la contrainte */ diff --git a/src/SIMPLEXE/spx_allouer_probleme.c b/src/SIMPLEXE/spx_allouer_probleme.c index 59f8e15..a6fa7da 100644 --- a/src/SIMPLEXE/spx_allouer_probleme.c +++ b/src/SIMPLEXE/spx_allouer_probleme.c @@ -172,6 +172,8 @@ Spx->AReduit = (double *) malloc( NbContr_E * sizeof( double ) ); Spx->IndexAReduit = (int *) malloc( NbContr_E * sizeof( int ) ); Spx->Marqueur = (int *) malloc( NbContr_E * sizeof( int ) ); +callback_function call_back = SPXgetcbmessage(Spx); +void *something_from_the_caller = Spx->something_from_the_caller; /*------------------------------------------------------------------------*/ if ( @@ -280,8 +282,8 @@ if ( ) { - printf("Simplexe, sous-programme SPX_AllouerProbleme: \n"); - printf(" -> memoire insuffisante pour l allocation de l espace de travail \n"); + const char *msg = "Simplexe, sous-programme SPX_AllouerProbleme: \n -> memoire insuffisante pour l allocation de l espace de travail \n"; + call_back(something_from_the_caller, msg, 0, SIRIUS_ERROR); Spx->AnomalieDetectee = OUI_SPX; longjmp( Spx->EnvSpx , Spx->AnomalieDetectee ); /* rq: le 2eme argument ne sera pas utilise */ } @@ -318,8 +320,8 @@ if ( ) { - printf("Simplexe, sous-programme SPX_AllouerProbleme: \n"); - printf(" -> memoire insuffisante pour l allocation de l espace de travail \n"); + const char *msg = "Simplexe, sous-programme SPX_AllouerProbleme: \n -> memoire insuffisante pour l allocation de l espace de travail \n"; + call_back(something_from_the_caller, msg, 0, SIRIUS_ERROR); Spx->AnomalieDetectee = OUI_SPX; longjmp( Spx->EnvSpx , Spx->AnomalieDetectee ); } @@ -339,8 +341,8 @@ if ( Spx->ValeurDesTermesDesColonnesDuProblemeReduit == NULL || Spx->IndicesDeLigneDesTermesDuProblemeReduit == NULL ) { - printf("Simplexe, sous-programme SPX_AllouerProbleme: \n"); - printf(" -> memoire insuffisante pour l allocation de l espace de travail \n"); + const char* msg = "Simplexe, sous-programme SPX_AllouerProbleme: \n -> memoire insuffisante pour l allocation de l espace de travail \n"; + call_back(something_from_the_caller, msg, 0, SIRIUS_ERROR); Spx->AnomalieDetectee = OUI_SPX; longjmp( Spx->EnvSpx , Spx->AnomalieDetectee ); } @@ -428,6 +430,8 @@ Spx->PositionHorsBaseReduiteAutorisee = (char *) realloc( Spx->PositionHorsBaseR Spx->CdebProblemeReduit = (int *) realloc( Spx->CdebProblemeReduit, NbVarMx * sizeof( int ) ); /*------------------------------------------------------------------------*/ Spx->CNbTermProblemeReduit = (int *) realloc( Spx->CNbTermProblemeReduit, NbVarMx * sizeof( int ) ); +callback_function call_back = SPXgetcbmessage(Spx); +void *something_from_the_caller = Spx->something_from_the_caller; if ( Spx->C == NULL || @@ -486,8 +490,8 @@ if ( ) { - printf("Simplexe, sous-programme SPX_AugmenterLeNombreDeVariables: \n"); - printf(" -> memoire insuffisante pour l allocation de l espace de travail \n"); + const char* msg= "Simplexe, sous-programme SPX_AugmenterLeNombreDeVariables: \n -> memoire insuffisante pour l allocation de l espace de travail \n"; + call_back(something_from_the_caller, msg, 0, SIRIUS_ERROR); Spx->AnomalieDetectee = OUI_SPX; longjmp( Spx->EnvSpx , Spx->AnomalieDetectee ); /* rq: le 2eme argument ne sera pas utilise */ } @@ -509,8 +513,8 @@ if ( Spx->ContrainteDeLaVariableEnBaseSV == NULL ) { - printf("Simplexe, sous-programme SPX_AugmenterLeNombreDeVariables: \n"); - printf(" -> memoire insuffisante pour l allocation de l espace de travail \n"); + const char* msg= "Simplexe, sous-programme SPX_AugmenterLeNombreDeVariables: \n -> memoire insuffisante pour l allocation de l espace de travail \n"; + call_back(something_from_the_caller, msg, 0, SIRIUS_ERROR); Spx->AnomalieDetectee = OUI_SPX; longjmp( Spx->EnvSpx , Spx->AnomalieDetectee ); } @@ -586,6 +590,7 @@ Spx->LigneDeLaBaseFactorisee = (int *) realloc( Spx->LigneDeLaBaseFactorisee, Nb Spx->AReduit = (double *) realloc( Spx->AReduit, NbContr_E * sizeof( double ) ); Spx->IndexAReduit = (int *) realloc( Spx->IndexAReduit, NbContr_E * sizeof( int ) ); Spx->Marqueur = (int *) realloc( Spx->Marqueur, NbContr_E * sizeof( int ) ); +callback_function call_back = SPXgetcbmessage(Spx); if ( Spx->B == NULL || @@ -638,8 +643,10 @@ if ( ) { - printf("Simplexe, sous-programme SPX_AugmenterLeNombreDeContraintes: \n"); - printf(" -> memoire insuffisante pour l allocation de l espace de travail \n"); + + const char* msg ="Simplexe, sous-programme SPX_AugmenterLeNombreDeContraintes: \n -> memoire insuffisante pour l allocation de l espace de travail \n"; + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_ERROR); + //TODO fflush(stdout); Spx->AnomalieDetectee = OUI_SPX; longjmp( Spx->EnvSpx , Spx->AnomalieDetectee ); /* rq: le 2eme argument ne sera pas utilise */ @@ -665,8 +672,9 @@ if ( Spx->NbTermesDesColonnesDeLaBaseSV == NULL ) { - printf("Simplexe, sous-programme SPX_AugmenterLeNombreDeContraintes: \n"); - printf(" -> memoire insuffisante pour l allocation de l espace de travail \n"); + const char*msg = "Simplexe, sous-programme SPX_AugmenterLeNombreDeContraintes: \n -> memoire insuffisante pour l allocation de l espace de travail \n"; + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_ERROR); + //TODO fflush(stdout); Spx->AnomalieDetectee = OUI_SPX; longjmp( Spx->EnvSpx , Spx->AnomalieDetectee ); @@ -696,6 +704,7 @@ Spx->ACol = (double *) realloc( Spx->ACol, NbTrm * sizeof( double Spx->NumeroDeContrainte = (int *) realloc( Spx->NumeroDeContrainte, NbTrm * sizeof( int ) ); /*------------------------------------------------------------------------*/ +callback_function call_back = SPXgetcbmessage(Spx); if ( Spx->A == NULL || Spx->Indcol == NULL || @@ -705,8 +714,8 @@ if ( Spx->NumeroDeContrainte == NULL ) { - printf("Simplexe, sous-programme SPX_AugmenterLaTailleDeLaMatriceDesContraintes: \n"); - printf(" -> memoire insuffisante pour l allocation de l espace de travail \n"); + const char* msg = "Simplexe, sous-programme SPX_AugmenterLaTailleDeLaMatriceDesContraintes: \n -> memoire insuffisante pour l allocation de l espace de travail \n"; + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_ERROR); Spx->AnomalieDetectee = OUI_SPX; longjmp( Spx->EnvSpx , Spx->AnomalieDetectee ); /* rq: le 2eme argument ne sera pas utilise */ } diff --git a/src/SIMPLEXE/spx_appliquer_eta_vecteurs.c b/src/SIMPLEXE/spx_appliquer_eta_vecteurs.c index ed4a84b..09cdd1c 100644 --- a/src/SIMPLEXE/spx_appliquer_eta_vecteurs.c +++ b/src/SIMPLEXE/spx_appliquer_eta_vecteurs.c @@ -52,12 +52,15 @@ EtaIndiceLigne = Spx->EtaIndiceLigne; EtaMoins1Valeur = Spx->EtaMoins1Valeur; EtaNbTerm = Spx->EtaNbTerm; EtaColonne = Spx->EtaColonne; - + +callback_function call_back = SPXgetcbmessage(Spx); + if ( CalculEnHyperCreux == OUI_SPX ) { if ( TypeDeStockage == COMPACT_LU ) goto HyperCreux; else if ( TypeDeStockage == ADRESSAGE_INDIRECT_LU ) goto HyperCreux; else if ( TypeDeStockage != VECTEUR_LU ){ - printf("AppliquerLesEtaVecteurs: type de stockage non gere\n"); + const char* msg = "AppliquerLesEtaVecteurs: type de stockage non gere\n"; + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_FATAL); exit(0); } } @@ -86,11 +89,15 @@ return; # if CONTROLE_RAZ_DES_VECTEURS == OUI_SPX for ( j = 0 ; j < Spx->NombreDeContraintes ; j++ ) { if ( Spx->AReduit[j] != 0 ) { - printf("Spx->AReduit[%d] = %e\n",j,Spx->AReduit[j]); + char msg[SIRIUS_CALLBACK_BUFFER_SIZE]; + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE,"Spx->AReduit[%d] = %e\n",j,Spx->AReduit[j]); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_FATAL); exit(0); } if ( Spx->Marqueur[j] != -1 ) { - printf("Spx->Marqueur[%d] = %d\n",j,Spx->Marqueur[j]); + char msg[SIRIUS_CALLBACK_BUFFER_SIZE]; + snprintf(msg , SIRIUS_CALLBACK_BUFFER_SIZE"Spx->Marqueur[%d] = %d\n",j,Spx->Marqueur[j]); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_FATAL); exit(0); } } diff --git a/src/SIMPLEXE/spx_appliquer_eta_vecteurs_transposee.c b/src/SIMPLEXE/spx_appliquer_eta_vecteurs_transposee.c index 366bc96..0abc659 100644 --- a/src/SIMPLEXE/spx_appliquer_eta_vecteurs_transposee.c +++ b/src/SIMPLEXE/spx_appliquer_eta_vecteurs_transposee.c @@ -55,15 +55,18 @@ EtaNbTerm = Spx->EtaNbTerm; EtaIndiceLigne = Spx->EtaIndiceLigne; EtaColonne = Spx->EtaColonne; EtaMoins1Valeur = Spx->EtaMoins1Valeur; +callback_function call_back = SPXgetcbmessage(Spx); if ( CalculEnHyperCreux == OUI_SPX ) { if ( TypeDeStockage == COMPACT_LU ) goto HyperCreux; if ( TypeDeStockage == ADRESSAGE_INDIRECT_LU ) { - printf("Attention TypeDeStockage = ADRESSAGE_INDIRECT_LU pas teste dans SPX_AppliquerLesEtaVecteursTransposee\n"); - goto HyperCreux; + const char* msg ="Attention TypeDeStockage = ADRESSAGE_INDIRECT_LU pas teste dans SPX_AppliquerLesEtaVecteursTransposee\n"; + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_WARN); + goto HyperCreux; } else if ( TypeDeStockage != VECTEUR_LU ) { - printf("AppliquerLesEtaVecteursTransposee: type de stockage non gere\n"); + const char* msg = "AppliquerLesEtaVecteursTransposee: type de stockage non gere\n"; + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_FATAL); exit(0); } } @@ -88,11 +91,16 @@ return; # if CONTROLE_RAZ_DES_VECTEURS == OUI_SPX for ( j = 0 ; j < Spx->NombreDeContraintes ; j++ ) { if ( Spx->AReduit[j] != 0 ) { - printf("AppliquerLesEtaVecteursTransposee: Spx->AReduit[%d] = %e\n",j,Spx->AReduit[j]); + char msg [SIRIUS_CALLBACK_BUFFER_SIZE]; + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "AppliquerLesEtaVecteursTransposee: Spx->AReduit[%d] = %e\n",j,Spx->AReduit[j]); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_FATAL); exit(0); } if ( Spx->Marqueur[j] != -1 ) { - printf("AppliquerLesEtaVecteursTransposee: Spx->Marqueur[%d] = %d\n",j,Spx->Marqueur[j]); + + char msg [SIRIUS_CALLBACK_BUFFER_SIZE]; + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "AppliquerLesEtaVecteursTransposee: Spx->Marqueur[%d] = %d\n",j,Spx->Marqueur[j]); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_FATAL); exit(0); } } diff --git a/src/SIMPLEXE/spx_calcul_du_cout.c b/src/SIMPLEXE/spx_calcul_du_cout.c index 34f9129..b587ea4 100644 --- a/src/SIMPLEXE/spx_calcul_du_cout.c +++ b/src/SIMPLEXE/spx_calcul_du_cout.c @@ -18,9 +18,9 @@ FONCTION: Utilisable surtout dans un contexte de Branch and Bound. On calcule le cout de la solution primale et on le compare - au seuil fourni en entrée (qui dans un contexte de + au seuil fourni en entr�e (qui dans un contexte de Branch and Bound est le cout de la meilleure solution - entiere deja trouvee). Si le cout calculé est superieur + entiere deja trouvee). Si le cout calcul� est superieur au seuil fourni en entree, on arrete les calculs et on sort avec le verdict: pas de solution. En effet le cout courant est un minorant du cout optimal. @@ -48,6 +48,8 @@ int i; double Cout; double * C; double * X; PROBLEME_PNE * Pne; # endif SPX_FixerXEnFonctionDeSaPosition( Spx ); +char msg[SIRIUS_CALLBACK_BUFFER_SIZE]; + C = Spx->C; # if TRACES == 1 @@ -71,11 +73,14 @@ for ( i = 0 ; i < Spx->NombreDeVariables ; i++ ) { Cout /= Spx->ScaleLigneDesCouts; Cout += Spx->PartieFixeDuCout; +callback_function call_back = SPXgetcbmessage(Spx); + # if TRACES == 1 VraiCout /= Spx->ScaleLigneDesCouts; VraiCout += Spx->PartieFixeDuCout; Erreur = fabs( VraiCout - Cout ); - printf("Erreur due au bruitage des couts %e Cout sans bruitage %e\n",Erreur,VraiCout); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "Erreur due au bruitage des couts %e Cout sans bruitage %e\n",Erreur,VraiCout); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_ERROR); # endif Spx->Cout = Cout; @@ -88,12 +93,14 @@ if ( Pne != NULL ) { #if VERBOSE_SPX if ( Spx->StrongBranchingEnCours != OUI_SPX ) { if ( Spx->UtiliserCoutMax == OUI_SPX ) { - printf("Iteration %5d Cout %20.6lf Infaisabilites primales %20.6lf PartieFixeDuCout %20.6lf CoutMax %20.6lf\n", + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "Iteration %5d Cout %20.6lf Infaisabilites primales %20.6lf PartieFixeDuCout %20.6lf CoutMax %20.6lf\n", Spx->Iteration,Spx->Cout,Spx->SommeDesInfaisabilitesPrimales,Spx->PartieFixeDuCout,Spx->CoutMax); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); } else { - printf("Iteration %5d Cout %20.6lf Infaisabilites primales %20.6lf PartieFixeDuCout %20.6lf\n", + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "Iteration %5d Cout %20.6lf Infaisabilites primales %20.6lf PartieFixeDuCout %20.6lf\n", Spx->Iteration,Spx->Cout,Spx->SommeDesInfaisabilitesPrimales,Spx->PartieFixeDuCout); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); } } #else @@ -102,21 +109,12 @@ if ( Pne != NULL ) { if ( Spx->EcrireLegendePhase2 == OUI_SPX ) { Spx->EcrireLegendePhase1 = OUI_SPX; Spx->EcrireLegendePhase2 = NON_SPX; - printf(" "); - printf(" | Phase |"); - printf(" Iteration |"); - printf(" Objective |"); - printf(" Primal infeas. |"); - printf(" Primal infeas. count |"); - printf("\n"); + const char* info_msg = " | Phase | Iteration | Objective | Primal infeas. | Primal infeas. count |\n"; + call_back(Spx->something_from_the_caller, info_msg, 0, SIRIUS_INFO); + } - printf(" "); - printf(" | II |"); - printf(" %6d |",Spx->Iteration); - printf(" %16.9e |",Spx->Cout); - printf(" %15.8e |",Spx->SommeDesInfaisabilitesPrimales); - printf(" %10d |",Spx->NombreDeContraintesASurveiller); - printf("\n"); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, " | II | %6d | %16.9e | %15.8e | %10d |\n", + Spx->Iteration, Spx->Cout, Spx->SommeDesInfaisabilitesPrimales, Spx->NombreDeContraintesASurveiller); } #endif diff --git a/src/SIMPLEXE/spx_calculer_a_barre_s.c b/src/SIMPLEXE/spx_calculer_a_barre_s.c index 99d49be..d15a205 100644 --- a/src/SIMPLEXE/spx_calculer_a_barre_s.c +++ b/src/SIMPLEXE/spx_calculer_a_barre_s.c @@ -57,9 +57,14 @@ else { for ( i = 0 ; i < iMx ; i++ ) if ( ABarreS[i] != 0.0 ) Count++; if ( Count < 0.1 * iMx ) Spx->NbEchecsABarreS--; + +callback_function call_back = SPXgetcbmessage(Spx); +char msg [SIRIUS_CALLBACK_BUFFER_SIZE]; + if ( Spx->NbEchecsABarreS <= 0 ) { # if VERBOSE_SPX - printf("Remise en service de l'hyper creux pour le calcul de ABarreS, iteration %d\n",Spx->Iteration); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "Remise en service de l'hyper creux pour le calcul de ABarreS, iteration %d\n",Spx->Iteration); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); # endif Spx->AvertissementsEchecsABarreS = 0; Spx->CountEchecsABarreS = 0; @@ -70,7 +75,8 @@ else if ( Spx->CountEchecsABarreS <= 0 ) { if ( Spx->CalculABarreSEnHyperCreux == NON_SPX ) Spx->AvertissementsEchecsABarreS ++; if ( Spx->AvertissementsEchecsABarreS >= SEUIL_ABANDON_HYPER_CREUX ) { # if VERBOSE_SPX - printf("Arret prolonge de l'hyper creux pour le calcul de ABarreS, iteration %d\n",Spx->Iteration); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "Arret prolonge de l'hyper creux pour le calcul de ABarreS, iteration %d\n",Spx->Iteration); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); # endif Spx->CalculABarreSEnHyperCreuxPossible = NON_SPX; } @@ -104,7 +110,7 @@ if ( CalculEnHyperCreux == OUI_SPX ) { /*printf("Echec hyper creux ABarreS iteration %d\n",Spx->Iteration);*/ if ( Spx->NbEchecsABarreS >= SEUIL_ECHEC_CREUX ) { # if VERBOSE_SPX - printf("Arret de l'hyper creux pour le calcul de ABarreS, iteration %d\n",Spx->Iteration); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE , "Arret de l'hyper creux pour le calcul de ABarreS, iteration %d\n",Spx->Iteration); # endif Spx->CalculABarreSEnHyperCreux = NON_SPX; Spx->CountEchecsABarreS = 0; diff --git a/src/SIMPLEXE/spx_calculer_a_barre_s_avec_base_reduite.c b/src/SIMPLEXE/spx_calculer_a_barre_s_avec_base_reduite.c index 1cbaf50..88a847b 100644 --- a/src/SIMPLEXE/spx_calculer_a_barre_s_avec_base_reduite.c +++ b/src/SIMPLEXE/spx_calculer_a_barre_s_avec_base_reduite.c @@ -105,22 +105,34 @@ if ( *TypeDEntree == ADRESSAGE_INDIRECT_LU ) printf("apres resolution TypeDEntre if ( *TypeDeSortie == VECTEUR_LU ) printf("apres resolution TypeDeSortie = VECTEUR_LU\n"); if ( *TypeDeSortie == COMPACT_LU ) printf("apres resolution TypeDeSortie = COMPACT_LU\n"); */ - + +callback_function call_back = SPXgetcbmessage(Spx); +char msg [SIRIUS_CALLBACK_BUFFER_SIZE]; /* Eventuellement forme produit de l'inverse */ if ( Spx->UtiliserLaLuUpdate == NON_SPX ) { - printf("CalculerBBarre AppliquerLesEtaVecteurs pas operationnel \n"); - exit(0); + call_back(Spx->something_from_the_caller, "CalculerBBarre AppliquerLesEtaVecteurs pas operationnel \n", 0, SIRIUS_FATAL); + exit(0); SPX_AppliquerLesEtaVecteurs( Spx, ABarreS, CntDeABarreSNonNuls, &NbTermesNonNuls, *CalculEnHyperCreux, *TypeDeSortie ); } Spx->NbABarreSNonNuls = NbTermesNonNuls; # if VERIFICATION_ABARRES == OUI_SPX -printf("---------------- CalculerABarreS Spx->NombreDeChangementsDeBase %d -------------\n",Spx->NombreDeChangementsDeBase); -if ( *TypeDEntree == VECTEUR_LU ) printf("apres resolution TypeDEntree = VECTEUR_LU\n"); -if ( *TypeDEntree == COMPACT_LU ) printf("apres resolution TypeDEntree = COMPACT_LU\n"); -if ( *TypeDeSortie == VECTEUR_LU ) printf("apres resolution TypeDeSortie = VECTEUR_LU\n"); -if ( *TypeDeSortie == COMPACT_LU ) printf("apres resolution TypeDeSortie = COMPACT_LU\n"); + +snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "---------------- CalculerABarreS Spx->NombreDeChangementsDeBase %d -------------\n",Spx->NombreDeChangementsDeBase); +call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); +if ( *TypeDEntree == VECTEUR_LU ) { + call_back(Spx->something_from_the_caller, "apres resolution TypeDEntree = VECTEUR_LU\n", 0, SIRIUS_INFO); +} +if ( *TypeDEntree == COMPACT_LU ){ + call_back(Spx->something_from_the_caller, "apres resolution TypeDEntree = COMPACT_LU\n", 0, SIRIUS_INFO); + } +if ( *TypeDeSortie == VECTEUR_LU ) { + call_back(Spx->something_from_the_caller, "apres resolution TypeDeSortie = VECTEUR_LU\n", 0, SIRIUS_INFO); +} +if ( *TypeDeSortie == COMPACT_LU ){ + call_back(Spx->something_from_the_caller, "apres resolution TypeDeSortie = COMPACT_LU\n", 0, SIRIUS_INFO); +} { double * Buff; int i; int Var; int ic; int icMx; double * Sortie; char Arret; int * VariableEnBaseDeLaContrainte; int rr; @@ -166,18 +178,24 @@ for ( r = 0 ; r < RangDeLaMatriceFactorisee ; r++ ) { Arret = NON_SPX; for ( r = 0 ; r < RangDeLaMatriceFactorisee ; r++ ) { if ( fabs( Buff[r] ) > 1.e-7 ) { - printf("r = %d ecart %e\n",r,Buff[r]); - Var = Spx->VariableEnBaseDeLaContrainte[Spx->ColonneDeLaBaseFactorisee[r]]; - if ( Spx->OrigineDeLaVariable[Var] != NATIVE ) printf(" variable non native\n"); - else printf(" variable native\n"); + snprintf(msg , SIRIUS_CALLBACK_BUFFER_SIZE, "r = %d ecart %e\n",r,Buff[r]); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); + + Var = Spx->VariableEnBaseDeLaContrainte[Spx->ColonneDeLaBaseFactorisee[r]]; + if ( Spx->OrigineDeLaVariable[Var] != NATIVE ){ + call_back(Spx->something_from_the_caller, " variable non native\n", 0, SIRIUS_INFO); + } + else { + call_back(Spx->something_from_the_caller, " variable native\n", 0, SIRIUS_INFO); + } Arret = OUI_SPX; } } if ( Arret == OUI_SPX ) { - printf("Verif ABarreS not OK\n"); + call_back(Spx->something_from_the_caller, "Verif ABarreS not OK\n", 0, SIRIUS_FATAL); exit(0); } -printf("Fin verif ABarreS OK\n"); +call_back(Spx->something_from_the_caller, "Fin verif ABarreS OK\n", 0, SIRIUS_INFO); free( Buff ); free( Sortie ); diff --git a/src/SIMPLEXE/spx_calculer_b_barre_avec_base_reduite.c b/src/SIMPLEXE/spx_calculer_b_barre_avec_base_reduite.c index 3d43a29..b342577 100644 --- a/src/SIMPLEXE/spx_calculer_b_barre_avec_base_reduite.c +++ b/src/SIMPLEXE/spx_calculer_b_barre_avec_base_reduite.c @@ -126,15 +126,19 @@ SecondMembreCreux = NON_LU; SPX_ResolutionDeSysteme( Spx, TypeDEntree, BBarre, NULL, NULL, &TypeDeSortie, CalculEnHyperCreux, Save, SecondMembreCreux ); +callback_function call_back = SPXgetcbmessage(Spx); +char msg [SIRIUS_CALLBACK_BUFFER_SIZE]; + /* Eventuellement forme produit de l'inverse */ if ( Spx->UtiliserLaLuUpdate == NON_SPX ) { - printf("CalculerBBarre AppliquerLesEtaVecteurs pas operationnel \n"); - exit(0); + call_back(Spx->something_from_the_caller, "CalculerBBarre AppliquerLesEtaVecteurs pas operationnel \n", 0, SIRIUS_FATAL); + exit(0); SPX_AppliquerLesEtaVecteurs( Spx, BBarre, NULL, NULL, CalculEnHyperCreux, TypeDeSortie ); } # if VERIFICATION_BBARRE == OUI_SPX -printf("----------- CalculerBBarre Iteration %d ---------------- \n",Spx->Iteration); +snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "----------- CalculerBBarre Iteration %d ---------------- \n",Spx->Iteration); +call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); { double * Buff; int i; int Var; int ic; int icMx; double * Sortie; char Arret; Buff = (double *) malloc( Spx->NombreDeContraintes * sizeof( double ) ); @@ -200,18 +204,23 @@ for ( i = 0 ; i < Spx->NombreDeContraintes ; i++ ) { Arret = NON_SPX; for ( i = 0 ; i < Spx->NombreDeContraintes ; i++ ) { if ( fabs( Buff[i] ) > 1.e-7 ) { - printf("i = %d ecart %e VariableEnBaseDeLaContrainte %d\n",i,Buff[i],Spx->VariableEnBaseDeLaContrainte[i]); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "i = %d ecart %e VariableEnBaseDeLaContrainte %d\n",i,Buff[i],Spx->VariableEnBaseDeLaContrainte[i]); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); Var = Spx->VariableEnBaseDeLaContrainte[i]; - if ( Spx->OrigineDeLaVariable[Var] != NATIVE ) printf(" variable non native\n"); - else printf(" variable native\n"); + if ( Spx->OrigineDeLaVariable[Var] != NATIVE ) { + call_back(Spx->something_from_the_caller, " variable non native\n", 0, SIRIUS_INFO); + } + else { + call_back(Spx->something_from_the_caller, " variable native\n", 0, SIRIUS_INFO); + } Arret = OUI_SPX; } } if ( Arret == OUI_SPX ) { - printf("Verif Bbarre not OK\n"); + call_back(Spx->something_from_the_caller, "Verif Bbarre not OK\n", 0, SIRIUS_FATAL); exit(0); } -printf("Fin verif Bbarre OK\n"); +call_back(Spx->something_from_the_caller, "Fin verif Bbarre OK\n", 0, SIRIUS_INFO); free( Buff ); free( Sortie ); diff --git a/src/SIMPLEXE/spx_calculer_erbmoins1_avec_base_complete.c b/src/SIMPLEXE/spx_calculer_erbmoins1_avec_base_complete.c index 9a94e87..ba01656 100644 --- a/src/SIMPLEXE/spx_calculer_erbmoins1_avec_base_complete.c +++ b/src/SIMPLEXE/spx_calculer_erbmoins1_avec_base_complete.c @@ -36,6 +36,9 @@ void SPX_CalculerErBMoins1AvecBaseComplete( PROBLEME_SPX * Spx, char CalculEnHyp { char TypeDEntree; char TypeDeSortie; int i; double * ErBMoinsUn; +callback_function call_back = SPXgetcbmessage(Spx); +char msg [SIRIUS_CALLBACK_BUFFER_SIZE]; + if ( CalculEnHyperCreux != OUI_SPX ) { TypeDEntree = VECTEUR_LU; TypeDeSortie = VECTEUR_LU; @@ -66,7 +69,8 @@ if ( CalculEnHyperCreux == OUI_SPX ) { */ if ( Spx->NbEchecsErBMoins >= SEUIL_ECHEC_CREUX ) { # if VERBOSE_SPX - printf("Arret de l'hyper creux pour le calcul de la ligne pivot, iteration %d\n",Spx->Iteration); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "Arret de l'hyper creux pour le calcul de la ligne pivot, iteration %d\n",Spx->Iteration); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); # endif Spx->CalculErBMoinsUnEnHyperCreux = NON_SPX; Spx->CountEchecsErBMoins = 0; diff --git a/src/SIMPLEXE/spx_calculer_erbmoins1_avec_base_reduite.c b/src/SIMPLEXE/spx_calculer_erbmoins1_avec_base_reduite.c index 06f4001..7240750 100644 --- a/src/SIMPLEXE/spx_calculer_erbmoins1_avec_base_reduite.c +++ b/src/SIMPLEXE/spx_calculer_erbmoins1_avec_base_reduite.c @@ -64,6 +64,9 @@ LigneDeLaBaseFactorisee = Spx->LigneDeLaBaseFactorisee; CntVarSor = ContrainteDeLaVariableEnBase[Spx->VariableSortante]; ResoudreLeSystemeReduit = NON_SPX; +callback_function call_back = SPXgetcbmessage(Spx); +char msg [SIRIUS_CALLBACK_BUFFER_SIZE]; + /* Remarque: a ce stade toutes les AReduit composantes de sont nulles */ if ( CalculEnHyperCreux != OUI_SPX ) { @@ -78,7 +81,7 @@ if ( CalculEnHyperCreux != OUI_SPX ) { } else { /* Ca ne peut pas arriver */ - printf("CalculerErBMoins1AvecBaseReduite bug: variable sortante hors base reduite impossible\n"); + call_back(Spx->something_from_the_caller, "CalculerErBMoins1AvecBaseReduite bug: variable sortante hors base reduite impossible\n", 0, SIRIUS_FATAL); exit(0); } } @@ -97,7 +100,7 @@ else { } else { /* Ca ne peut pas arriver */ - printf("CalculerErBMoins1AvecBaseReduite bug: variable sortante hors base reduite impossible\n"); + call_back(Spx->something_from_the_caller, "CalculerErBMoins1AvecBaseReduite bug: variable sortante hors base reduite impossible\n", 0, SIRIUS_FATAL); exit(0); } } @@ -144,7 +147,8 @@ if ( CalculEnHyperCreux == OUI_SPX ) { */ if ( Spx->NbEchecsErBMoins >= SEUIL_ECHEC_CREUX ) { # if VERBOSE_SPX - printf("Arret de l'hyper creux pour le calcul de la ligne pivot, iteration %d\n",Spx->Iteration); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "Arret de l'hyper creux pour le calcul de la ligne pivot, iteration %d\n",Spx->Iteration); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); # endif Spx->CalculErBMoinsUnEnHyperCreux = NON_SPX; Spx->CountEchecsErBMoins = 0; @@ -154,11 +158,12 @@ if ( CalculEnHyperCreux == OUI_SPX ) { } # if VERIFICATION_ERBMOINS1 == OUI_SPX -printf("------------- CalculerErBMoins1 Spx->NombreDeChangementsDeBase %d Iteration %d ---\n",Spx->NombreDeChangementsDeBase,Spx->Iteration); -if ( TypeDEntree == VECTEUR_LU ) printf("TypeDEntree = VECTEUR_LU\n"); -if ( TypeDEntree == COMPACT_LU ) printf("TypeDEntree = COMPACT_LU\n"); -if ( TypeDeSortie == VECTEUR_LU ) printf("TypeDeSortie = VECTEUR_LU\n"); -if ( TypeDeSortie == COMPACT_LU ) printf("TypeDeSortie = COMPACT_LU\n"); +snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "------------- CalculerErBMoins1 Spx->NombreDeChangementsDeBase %d Iteration %d ---\n",Spx->NombreDeChangementsDeBase,Spx->Iteration); +call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); +if ( TypeDEntree == VECTEUR_LU ) call_back(Spx->something_from_the_caller, "TypeDEntree = VECTEUR_LU\n", 0, SIRIUS_INFO); +if ( TypeDEntree == COMPACT_LU ) call_back(Spx->something_from_the_caller,"TypeDEntree = COMPACT_LU\n", 0, SIRIUS_INFO); +if ( TypeDeSortie == VECTEUR_LU ) call_back(Spx->something_from_the_caller,"TypeDeSortie = VECTEUR_LU\n", 0, SIRIUS_INFO); +if ( TypeDeSortie == COMPACT_LU ) call_back(Spx->something_from_the_caller,"TypeDeSortie = COMPACT_LU\n", 0, SIRIUS_INFO); { double * Buff; int i; int Var; int ic; int icMx; double S; double * Sortie; char Arret; Buff = (double *) malloc( Spx->NombreDeContraintes * sizeof( double ) ); @@ -183,22 +188,26 @@ for ( i = 0 ; i < Spx->NombreDeContraintes ; i++ ) { ic++; } if ( fabs( S - Buff[i] ) > 1.e-7 ) { - printf("i = %d S %e Buff %e ecart %e\n",i,S,Buff[i],fabs( S - Buff[i] )); - printf("Var = %d\n",Var); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE,"i = %d S %e Buff %e ecart %e\n",i,S,Buff[i],fabs( S - Buff[i] )); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE,"Var = %d\n",Var); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); ic = Spx->Cdeb[Var]; icMx = ic + Spx->CNbTerm[Var]; while ( ic < icMx ) { - printf("NumeroDeContrainte[%d] = %d Sortie = %e ACol = %e\n",ic,Spx->NumeroDeContrainte[ic],Sortie[Spx->NumeroDeContrainte[ic]],Spx->ACol[ic]); - ic++; + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "NumeroDeContrainte[%d] = %d Sortie = %e ACol = %e\n",ic,Spx->NumeroDeContrainte[ic],Sortie[Spx->NumeroDeContrainte[ic]],Spx->ACol[ic]); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); + ic++; } Arret = OUI_SPX; } } if ( Arret == OUI_SPX ) { - printf("RangDeLaMatriceFactorisee %d NombreDeContraintes %d\n",Spx->RangDeLaMatriceFactorisee,Spx->NombreDeContraintes); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "RangDeLaMatriceFactorisee %d NombreDeContraintes %d\n",Spx->RangDeLaMatriceFactorisee,Spx->NombreDeContraintes); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_FATAL); exit(0); } -printf("Fin verif erbmoins1 OK\n"); +call_back(Spx->something_from_the_caller,"Fin verif erbmoins1 OK\n", 0, SIRIUS_INFO); free( Buff ); free( Sortie ); diff --git a/src/SIMPLEXE/spx_calculer_pi_avec_base_reduite.c b/src/SIMPLEXE/spx_calculer_pi_avec_base_reduite.c index 2405e00..5cb41d3 100644 --- a/src/SIMPLEXE/spx_calculer_pi_avec_base_reduite.c +++ b/src/SIMPLEXE/spx_calculer_pi_avec_base_reduite.c @@ -66,8 +66,12 @@ TypeDeSortie = VECTEUR_LU; CalculEnHyperCreux = NON_SPX; SecondMembreCreux = NON_SPX; +callback_function call_back = SPXgetcbmessage(Spx); +char msg [SIRIUS_CALLBACK_BUFFER_SIZE]; + + /* Eventuellement les Eta vecteurs */ -/* Attention il faut âs faire comme ca mais resoudre tout le systeme avec les eta */ +/* Attention il faut �s faire comme ca mais resoudre tout le systeme avec les eta */ /* if ( Spx->UtiliserLaLuUpdate == NON_SPX ) { SPX_AppliquerLesEtaVecteursTransposee( Spx, Pi, IndexDesTermesNonNuls, NombreDeTermesNonNuls, @@ -84,7 +88,8 @@ for ( r = 0 ; r < RangDeLaMatriceFactorisee ; r++ ) { } # if VERIFICATION_PI == OUI_SPX -printf("------------- CalculerPi Spx->NombreDeChangementsDeBase %d -------------\n",Spx->NombreDeChangementsDeBase); +snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "------------- CalculerPi Spx->NombreDeChangementsDeBase %d -------------\n",Spx->NombreDeChangementsDeBase); +call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); { double * Buff; int i; int Var; int ic; int icMx; double S; double * Sortie; Buff = (double *) malloc( Spx->NombreDeContraintes * sizeof( double ) ); @@ -101,11 +106,12 @@ for ( i = 0 ; i < Spx->NombreDeContraintes ; i++ ) { ic++; } if ( fabs( S - Buff[i] ) > 1.e-7 ) { - printf("i = %d S %e Buff %e ecart %e\n",i,S,Buff[i],fabs( S - Buff[i] )); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "i = %d S %e Buff %e ecart %e\n",i,S,Buff[i],fabs( S - Buff[i] )); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_FATAL); exit(0); } } -printf("Fin verif CalculerPi OK\n"); +call_back(Spx->something_from_the_caller, "Fin verif CalculerPi OK\n", 0, SIRIUS_INFO); free( Buff ); free( Sortie ); diff --git a/src/SIMPLEXE/spx_calculer_une_gomory.c b/src/SIMPLEXE/spx_calculer_une_gomory.c index 11b54db..5b337ef 100644 --- a/src/SIMPLEXE/spx_calculer_une_gomory.c +++ b/src/SIMPLEXE/spx_calculer_une_gomory.c @@ -215,7 +215,7 @@ AlphaI0 = Spx->BBarre[Spx->ContrainteDeLaVariableEnBase[VariableFractionnaireSpx /* Calcul de la ligne de B^{-1} qui correspond a la variable de base fractionnaire. On utilise pour cela le module de l'algorithme dual */ -/* Il est preferable de ne pas faire le calcul des gomory en hyper creux. De toutes façons une gomory est +/* Il est preferable de ne pas faire le calcul des gomory en hyper creux. De toutes fa�ons une gomory est rarement hyper creuse. */ Spx->CalculErBMoinsUnEnHyperCreux = NON_SPX; Spx->CalculErBMoinsEnHyperCreuxPossible = NON_SPX; @@ -238,6 +238,9 @@ Cdeb = Spx->Cdeb; CNbTerm = Spx->CNbTerm; NumeroDeContrainte = Spx->NumeroDeContrainte; +callback_function call_back = SPXgetcbmessage(Spx); +char msg [SIRIUS_CALLBACK_BUFFER_SIZE]; + /* Si le stockage de ErBMoinsUn est COMPACT_SPX on en fait un VECTEUR_SPX */ if ( Spx->TypeDeStockageDeErBMoinsUn == COMPACT_SPX ) { Bs = Spx->Bs; @@ -248,7 +251,7 @@ if ( Spx->TypeDeStockageDeErBMoinsUn == COMPACT_SPX ) { Spx->TypeDeStockageDeErBMoinsUn = VECTEUR_SPX; } else if ( Spx->TypeDeStockageDeErBMoinsUn != VECTEUR_SPX ) { - printf("Calcul des gomory, attention le mode de stockage de ErBMoinsUn est incorrect\n"); + call_back(Spx->something_from_the_caller,"Calcul des gomory, attention le mode de stockage de ErBMoinsUn est incorrect\n", 0, SIRIUS_INFO); } goto AAA; @@ -269,7 +272,8 @@ for ( Cnt = 0 ; Cnt < Spx->NombreDeContraintes ; Cnt++ ) { if ( NormeL1 > SEUIL_DE_VERIFICATION_DE_NBarreR_GOMORY ) { #if VERBOSE_SPX - printf("Erreur de resolution sur ErBMoinsUn: %e, Gomory refusee\n",fabs( NormeL1 )); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "Erreur de resolution sur ErBMoinsUn: %e, Gomory refusee\n",fabs( NormeL1 )); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_ERROR); #endif Spx->FactoriserLaBase = NON_SPX; return; @@ -290,7 +294,8 @@ while ( il < ilMax ) { NormeL1 += fabs( S ); if ( NormeL1 > SEUIL_DE_VERIFICATION_DE_NBarreR_GOMORY ) { #if VERBOSE_SPX - printf("Erreur de resolution sur ErBMoinsUn: %e, Gomory refusee\n",fabs( NormeL1 )); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "Erreur de resolution sur ErBMoinsUn: %e, Gomory refusee\n",fabs( NormeL1 )); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_ERROR); #endif Spx->FactoriserLaBase = NON_SPX; return; @@ -323,7 +328,8 @@ break; NormeL1 += fabs( S ); if ( NormeL1 > SEUIL_DE_VERIFICATION_DE_NBarreR_GOMORY ) { #if VERBOSE_SPX - printf("Erreur de resolution sur ErBMoinsUn: %e, Gomory refusee\n",fabs( NormeL1 )); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "Erreur de resolution sur ErBMoinsUn: %e, Gomory refusee\n",fabs( NormeL1 )); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_ERROR); #endif Spx->FactoriserLaBase = NON_SPX; return; @@ -354,12 +360,12 @@ if ( Spx->TypeDeStockageDeNBarreR == ADRESSAGE_INDIRECT_SPX ) { Spx->TypeDeStockageDeNBarreR = VECTEUR_SPX; } else if ( Spx->TypeDeStockageDeNBarreR != VECTEUR_SPX ) { - printf("Calcul des gomory, le mode de stockage de NBarreR est incorrect\n"); + call_back(Spx->something_from_the_caller,"Calcul des gomory, le mode de stockage de NBarreR est incorrect\n", 0, SIRIUS_INFO); } /* Constitution du vecteur sur lequel on fera la MIR */ /* Remarque: les variables non bornees x = x+ - x- avec x+ >= 0 et x- >= 0 sont hors base a 0 - c'est à dire x+ et x- sont nuls. Comme il y a une difference la variable n'intervient pas. */ + c'est � dire x+ et x- sont nuls. Comme il y a une difference la variable n'intervient pas. */ for ( VarSpx = 0 ; VarSpx < Spx->NombreDeVariables ; VarSpx++ ) { T [VarSpx] = 0; diff --git a/src/SIMPLEXE/spx_choix_variable_a_instancier_exploration_rapide_profondeur.c b/src/SIMPLEXE/spx_choix_variable_a_instancier_exploration_rapide_profondeur.c index daa8db8..1d89942 100644 --- a/src/SIMPLEXE/spx_choix_variable_a_instancier_exploration_rapide_profondeur.c +++ b/src/SIMPLEXE/spx_choix_variable_a_instancier_exploration_rapide_profondeur.c @@ -67,9 +67,12 @@ Bb = (BB *) BbProb; if ( Spx->YaUneSolution == NON_SPX ) return; +callback_function call_back = SPXgetcbmessage(Spx); +char msg [SIRIUS_CALLBACK_BUFFER_SIZE]; + SPX_CalculDuCout( Spx ); if ( Spx->Cout > Spx->CoutMax ) { - printf("Fin par coutmax dans choix var a instancier\n"); + call_back(Spx->something_from_the_caller, "Fin par coutmax dans choix var a instancier\n", 0, SIRIUS_INFO); Spx->YaUneSolution = NON_SPX; return; } diff --git a/src/SIMPLEXE/spx_construction_matrice_reduite.c b/src/SIMPLEXE/spx_construction_matrice_reduite.c index 81926c3..dcb91e5 100644 --- a/src/SIMPLEXE/spx_construction_matrice_reduite.c +++ b/src/SIMPLEXE/spx_construction_matrice_reduite.c @@ -53,6 +53,8 @@ CNbTermProblemeReduit = Spx->CNbTermProblemeReduit; ValeurDesTermesDesColonnesDuProblemeReduit = Spx->ValeurDesTermesDesColonnesDuProblemeReduit; IndicesDeLigneDesTermesDuProblemeReduit = Spx->IndicesDeLigneDesTermesDuProblemeReduit; +callback_function call_back = SPXgetcbmessage(Spx); +char msg [SIRIUS_CALLBACK_BUFFER_SIZE]; /* Construction de la matrice du probleme reduit stockee par colonne */ icNew = 0; NbTermesTotal = 0; @@ -68,8 +70,8 @@ for ( Var = 0 ; Var < Spx->NombreDeVariables ; Var++ ) { Spx->ValeurDesTermesDesColonnesDuProblemeReduit = (double *) realloc( Spx->ValeurDesTermesDesColonnesDuProblemeReduit, Spx->NbElementsAllouesPourLeProblemeReduit * sizeof( double ) ); Spx->IndicesDeLigneDesTermesDuProblemeReduit = (int *) realloc( Spx->IndicesDeLigneDesTermesDuProblemeReduit, Spx->NbElementsAllouesPourLeProblemeReduit * sizeof( int ) ); if ( Spx->ValeurDesTermesDesColonnesDuProblemeReduit == NULL || Spx->IndicesDeLigneDesTermesDuProblemeReduit == NULL ) { - printf("Simplexe, sous-programme SPX_FactoriserLaBase: \n"); - printf(" -> memoire insuffisante pour l allocation de l espace de travail \n"); + call_back(Spx->something_from_the_caller, "Simplexe, sous-programme SPX_FactoriserLaBase: \n", 0, SIRIUS_INFO); + call_back(Spx->something_from_the_caller, " -> memoire insuffisante pour l allocation de l espace de travail \n", 0, SIRIUS_INFO); Spx->AnomalieDetectee = OUI_SPX; longjmp( Spx->EnvSpx , Spx->AnomalieDetectee ); } @@ -102,9 +104,11 @@ for ( Var = 0 ; Var < Spx->NombreDeVariables ; Var++ ) { } # if TRACES == 1 - printf("\n Nombre de variables hors du probleme reduit %d sur %d restent %d / nombre de couts remis a zero: %d\n", + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "\n Nombre de variables hors du probleme reduit %d sur %d restent %d / nombre de couts remis a zero: %d\n", NbH,Spx->NombreDeVariables,Spx->NombreDeVariables-NbH,NbRaz); - printf("\n Nombre de termes de la matrice reduite des contraintes %d\n",NbTermesTotal); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "\n Nombre de termes de la matrice reduite des contraintes %d\n",NbTermesTotal); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); # endif return; @@ -251,10 +255,13 @@ for ( Var = 0 ; Var < Spx->NombreDeVariables ; Var++ ) { free( XminSv ); free( XmaxSv ); -printf("NbRlx %d NbForcing %d\n",NbRlx,NbForcing); +snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "NbRlx %d NbForcing %d\n",NbRlx,NbForcing); +call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); -printf("NbFix %d sur %d restent %d\n",NbFix,Spx->NombreDeContraintes,Spx->NombreDeContraintes-NbFix); -printf("Nombre de contraintes d'inegalite %d\n",NbIneg); +snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "NbFix %d sur %d restent %d\n",NbFix,Spx->NombreDeContraintes,Spx->NombreDeContraintes-NbFix); +call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); +snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "Nombre de contraintes d'inegalite %d\n",NbIneg); +call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); /* Fin test */ # endif diff --git a/src/SIMPLEXE/spx_construire_probleme.c b/src/SIMPLEXE/spx_construire_probleme.c index 96e9e91..11f86b5 100644 --- a/src/SIMPLEXE/spx_construire_probleme.c +++ b/src/SIMPLEXE/spx_construire_probleme.c @@ -160,6 +160,9 @@ for ( i = 0 ; i < NbVar_E ; i++ ) { Xmin [NombreDeVariables] = Xmin_E[i]; CorrectionDuale[NombreDeVariables] = NOMBRE_MAX_DE_PERTURBATIONS_DE_COUT; + callback_function call_back = SPXgetcbmessage(Spx); + char msg [SIRIUS_CALLBACK_BUFFER_SIZE]; + if ( TypeVar_E[i] == VARIABLE_BORNEE_DES_DEUX_COTES || TypeVar_E[i] == VARIABLE_BORNEE_INFERIEUREMENT ) { Spx->PartieFixeDuCout+= C_E[i] * Xmin_E[i]; @@ -184,8 +187,11 @@ for ( i = 0 ; i < NbVar_E ; i++ ) { /* X [NombreDeVariables] = 0.; */ } else { - printf(" Bug dans la fourniture de la base de depart, la variable %d est mal positionnee\n",i); - printf(" son positionnement donne est %d \n",(int) PositionDeLaVariable_E[i]); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, " Bug dans la fourniture de la base de depart, la variable %d est mal positionnee\n",i); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_ERROR); + + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, " son positionnement donne est %d \n",(int) PositionDeLaVariable_E[i]); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_FATAL); exit(0); } } @@ -214,13 +220,19 @@ for ( i = 0 ; i < NbVar_E ; i++ ) { Xmax [NombreDeVariables] = LINFINI_POUR_X; } else { - printf("Erreur entree du solveur: le seul type de variables reconnues est: \n"); - printf(" VARIABLE_FIXE -> valeur de constante: %d\n",(int) VARIABLE_FIXE); - printf(" VARIABLE_BORNEE_DES_DEUX_COTES -> valeur de constante: %d\n",(int) VARIABLE_BORNEE_DES_DEUX_COTES); - printf(" VARIABLE_BORNEE_INFERIEUREMENT -> valeur de constante: %d\n",(int) VARIABLE_BORNEE_INFERIEUREMENT); - printf(" VARIABLE_BORNEE_SUPERIEUREMENT -> valeur de constante: %d\n",(int) VARIABLE_BORNEE_SUPERIEUREMENT); - printf(" VARIABLE_NON_BORNEE -> valeur de constante: %d\n",(int) VARIABLE_NON_BORNEE); - printf("Or la variable %d est du type %d => exit volontaire car pb de mise au point\n",i,(int) TypeVar_E[i]); + call_back(Spx->something_from_the_caller,"Erreur entree du solveur: le seul type de variables reconnues est: \n", 0, SIRIUS_ERROR); + snprintf(msg,SIRIUS_CALLBACK_BUFFER_SIZE," VARIABLE_FIXE -> valeur de constante: %d\n",(int) VARIABLE_FIXE); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_FATAL); + snprintf(msg,SIRIUS_CALLBACK_BUFFER_SIZE," VARIABLE_BORNEE_DES_DEUX_COTES -> valeur de constante: %d\n",(int) VARIABLE_BORNEE_DES_DEUX_COTES); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_FATAL); + snprintf(msg,SIRIUS_CALLBACK_BUFFER_SIZE," VARIABLE_BORNEE_INFERIEUREMENT -> valeur de constante: %d\n",(int) VARIABLE_BORNEE_INFERIEUREMENT); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_FATAL); + snprintf(msg,SIRIUS_CALLBACK_BUFFER_SIZE," VARIABLE_BORNEE_SUPERIEUREMENT -> valeur de constante: %d\n",(int) VARIABLE_BORNEE_SUPERIEUREMENT); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_FATAL); + snprintf(msg,SIRIUS_CALLBACK_BUFFER_SIZE," VARIABLE_NON_BORNEE -> valeur de constante: %d\n",(int) VARIABLE_NON_BORNEE); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_FATAL); + snprintf(msg,SIRIUS_CALLBACK_BUFFER_SIZE,"Or la variable %d est du type %d => exit volontaire car pb de mise au point\n",i,(int) TypeVar_E[i]); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_FATAL); exit(0); } @@ -307,13 +319,13 @@ for ( il = 0 , Cnt_E = 0 ; Cnt_E < NbContr_E ; Cnt_E++ ) { if ( TypeDeContrainte_E[Cnt_E] == '=' ) { /* Dans le cas des contraintes d'egalite il ne peut y avoir au plus qu'une seule - variable additionnelle laquelle sera affectée a la base initiale */ + variable additionnelle laquelle sera affect�e a la base initiale */ il++; /* On laisse de la place pour l'eventuelle variable de base */ } else { /* Dans le cas des contraintes d'inegalite il ne peut y avoir au plus que 2 variables additionnelles une variable d'ecart et si necessaire une variable - affectée a la base initiale */ + affect�e a la base initiale */ il++; /* On laisse de la place pour la variable d'ecart */ il++; /* On laisse de la place pour l'eventuelle variable de base */ } @@ -402,6 +414,9 @@ SPX_CalculerLeScaling( Spx ); /* Application du scaling */ SPX_Scaling( Spx ); +callback_function call_back = SPXgetcbmessage(Spx); +char msg [SIRIUS_CALLBACK_BUFFER_SIZE]; + for ( Cnt = 0 ; Cnt < Spx->NombreDeContraintes ; Cnt++ ) { BAvantTranslationEtApresScaling[Cnt] *= ScaleB[Cnt]; } @@ -410,7 +425,7 @@ for ( Cnt = 0 ; Cnt < Spx->NombreDeContraintes ; Cnt++ ) { for ( Cnt = 0 ; Cnt < Spx->NombreDeContraintes ; Cnt++ ) { Cnt_E = CorrespondanceCntSimplexeCntEntree[Cnt]; if ( Cnt_E < 0 ) { - printf(" Bug dans SPX_ConstruireLeProbleme \n"); + call_back(Spx->something_from_the_caller, " Bug dans SPX_ConstruireLeProbleme \n", 0, SIRIUS_ERROR); Spx->AnomalieDetectee = OUI_SPX; longjmp( Spx->EnvSpx , Spx->AnomalieDetectee ); /* rq: le 2eme argument ne sera pas utilise */ } @@ -449,7 +464,8 @@ for ( i = NombreDeVariablesNatives ; i < Spx->NombreDeVariables ; i++ ) { } #if VERBOSE_SPX - printf("Nombre de variables dans le simplexe %d\n", Spx->NombreDeVariables); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "Nombre de variables dans le simplexe %d\n", Spx->NombreDeVariables); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); fflush( stdout ); #endif @@ -509,6 +525,9 @@ CorrespondanceVarSimplexeVarEntree = Spx->CorrespondanceVarSimplexeVarEntree; StatutBorneSupCourante = Spx->StatutBorneSupCourante; StatutBorneSupAuxiliaire = Spx->StatutBorneSupAuxiliaire; +callback_function call_back = SPXgetcbmessage(Spx); +char msg [SIRIUS_CALLBACK_BUFFER_SIZE]; + il = Mdeb[Cnt]; ilMax = il + NbTerm[Cnt]; Smin = 0.; @@ -527,7 +546,8 @@ while ( il < ilMax) { if ( Smin > ( B[Cnt] + SEUIL_DADMISSIBILITE ) ) { #if VERBOSE_SPX - printf("Simplexe: impossible de satisfaire la contrainte d'inegalite %d car Smin = %lf B = %lf \n",Cnt,Smin,Spx->B[Cnt]); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "Simplexe: impossible de satisfaire la contrainte d'inegalite %d car Smin = %lf B = %lf \n",Cnt,Smin,Spx->B[Cnt]); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_INFO); #endif Spx->YaUneSolution = NON_SPX; return; diff --git a/src/SIMPLEXE/spx_creation_noeuds_en_exploration_rapide.c b/src/SIMPLEXE/spx_creation_noeuds_en_exploration_rapide.c index 4752771..13471d2 100644 --- a/src/SIMPLEXE/spx_creation_noeuds_en_exploration_rapide.c +++ b/src/SIMPLEXE/spx_creation_noeuds_en_exploration_rapide.c @@ -36,7 +36,7 @@ /*----------------------------------------------------------------------------*/ -/* On connait le noeud courant, c'est celui qui vient d'être examiné */ +/* On connait le noeud courant, c'est celui qui vient d'�tre examin� */ void Spx_CreationNoeudsFils( PROBLEME_SPX * Spx, void * PneProb, void * BbProb, int VariablesPneAInstancier ) { @@ -100,6 +100,8 @@ for ( VarPne = 0 ; VarPne < NombreDeVariablesPNE ; VarPne++ ) { } } +callback_function call_back = SPXgetcbmessage(Spx); +char msg [SIRIUS_CALLBACK_BUFFER_SIZE]; NbVarDeBaseComplementaires = 0; for ( Var = 0 ; Var < Spx->NombreDeVariablesDuProblemeSansCoupes ; Var++ ) { @@ -119,7 +121,8 @@ for ( Var = 0 ; Var < Spx->NombreDeVariablesDuProblemeSansCoupes ; Var++ ) { il++; } if ( NbT != 1 ) { - printf("Bug dans SPX_RecupererLaSolution nombre de termes dans la colonne de la variable %d incorrect, %d\n",Var,NbT); + snprintf(msg, SIRIUS_CALLBACK_BUFFER_SIZE, "Bug dans SPX_RecupererLaSolution nombre de termes dans la colonne de la variable %d incorrect, %d\n",Var,NbT); + call_back(Spx->something_from_the_caller, msg, 0, SIRIUS_ERROR); Spx->AnomalieDetectee = OUI_SPX; longjmp( Spx->EnvSpx , Spx->AnomalieDetectee ); /* rq: le 2eme argument ne sera pas utilise */ } @@ -135,7 +138,7 @@ NoeudEnExamen->NbVarDeBaseComplementaires = NbVarDeBaseComplementaires; NumCoupe = 0; if ( Spx->NombreDeContraintes - Spx->NombreDeContraintesDuProblemeSansCoupes != Bb->NombreDeCoupesAjoutees ) { - printf("pb Bb->NombreDeCoupesAjoutees dans SPX\n"); + call_back(Spx->something_from_the_caller, "pb Bb->NombreDeCoupesAjoutees dans SPX\n", 0, SIRIUS_INFO); } for ( Cnt = Spx->NombreDeContraintesDuProblemeSansCoupes ; Cnt < Spx->NombreDeContraintes ; Cnt++ ) { /* On cherche la variable Cnt_E correspondante */ diff --git a/src/SIMPLEXE/spx_define.h b/src/SIMPLEXE/spx_define.h index 4d17c67..be5a77a 100644 --- a/src/SIMPLEXE/spx_define.h +++ b/src/SIMPLEXE/spx_define.h @@ -299,7 +299,7 @@ double Cout; /* Valeur du cout de la solution */ double CoutMax; /* Valeur du cout au dessus de laquelle on arrete les calculs (utilite: branch and bound) */ int UtiliserCoutMax; /* Vaut OUI_SPX si on desire faire le test par rapport a CoutMax, et NON_SPX si on ne veut pas utiliser cette possibilite */ -double PartieFixeDuCout; /* Partie du cout qui est due aux variables dont la valeur est fixe. C'est calculé en +double PartieFixeDuCout; /* Partie du cout qui est due aux variables dont la valeur est fixe. C'est calcul� en entree du solveur */ char LeSteepestEdgeEstInitilise; @@ -436,6 +436,8 @@ char ExplorationRapideEnCours; /* OUI_SPX ou NON_SPX */ double A1; /*------------------------------------------*/ +void *callback; +void *something_from_the_caller; } PROBLEME_SPX; diff --git a/src/SIMPLEXE/spx_definition_arguments.h b/src/SIMPLEXE/spx_definition_arguments.h index 1838bbb..07c6f10 100644 --- a/src/SIMPLEXE/spx_definition_arguments.h +++ b/src/SIMPLEXE/spx_definition_arguments.h @@ -29,23 +29,23 @@ il contient la definition de la structure C exploitee par la fonction. Apres avoir renseigne les champs, le module utilisateur appelle la fonction SPX_Simplexe avec, pour argument d'appel: - - un pointeur à un objet de type PROBLEME_SIMPLEXE: il permet de renseigner les donnees - du probleme à résoudre - - un pointeur à un objet de type PROBLEME_SPX. Lorsque la valeur de ce pointeur vaut NULL, + - un pointeur � un objet de type PROBLEME_SIMPLEXE: il permet de renseigner les donnees + du probleme � r�soudre + - un pointeur � un objet de type PROBLEME_SPX. Lorsque la valeur de ce pointeur vaut NULL, SPX_Simplexe alloue un nouvel objet de type PROBLEME_SPX sur lequel il travaillera. - Dans le cas contraire SPX_Simplexe travaillera sur l'objet de type PROBLEME_SPX passé + Dans le cas contraire SPX_Simplexe travaillera sur l'objet de type PROBLEME_SPX pass� par l'appelant. - SPX_Simplexe renvoie un pointeur à un objet de type PROBLEME_SPX, ce pointeur - correspond à l'objet sur lequel SPX_Simplexe vient de faire ses calculs. + SPX_Simplexe renvoie un pointeur � un objet de type PROBLEME_SPX, ce pointeur + correspond � l'objet sur lequel SPX_Simplexe vient de faire ses calculs. - L'appelant peut de cette façon travailler sur plusieurs instances de problemes qu'il + L'appelant peut de cette fa�on travailler sur plusieurs instances de problemes qu'il souhaite faire resoudre par le simplexe. Exemple d'utilisation : PROBLEME_SIMPLEXE Mon_Probleme; <- definition d'une structure "Mon_Probleme" de type PROBLEME_SIMPLEXE - void * ProblemeSpx; <- Utiliser void * comme type de pointeur permet à l'appelant d'ignorer la + void * ProblemeSpx; <- Utiliser void * comme type de pointeur permet � l'appelant d'ignorer la composition de la structure PROBLEME_SPX, qu'il n'a d'ailleurs pas besoin de connaitre. ....... @@ -62,12 +62,12 @@ typedef struct { int Contexte; /* Contexte dans lequel le simplexe est utilise. Cet argument peut prendre 3 valeurs: - BRANCH_AND_BOUND_OU_CUT: le simplexe est appelé dans un contexte de Branch And Bound + BRANCH_AND_BOUND_OU_CUT: le simplexe est appel� dans un contexte de Branch And Bound ou de Branch And Cut - BRANCH_AND_BOUND_OU_CUT_NOEUD: le simplexe est appelé dans un contexte de Branch And Bound + BRANCH_AND_BOUND_OU_CUT_NOEUD: le simplexe est appel� dans un contexte de Branch And Bound ou de Branch And Cut mais on ne reinitialise pas le probleme - SIMPLEXE_SEUL: le simplexe est appelé hors d'un contexte de Branch and Bound ou de - Branch And Cut (dans ce cas, certaines sauvegardes particulières ne sont + SIMPLEXE_SEUL: le simplexe est appel� hors d'un contexte de Branch and Bound ou de + Branch And Cut (dans ce cas, certaines sauvegardes particuli�res ne sont pas faites) */ int NombreMaxDIterations; /* Si < 0 , le simplexe prendre sa valeur par defaut */ double DureeMaxDuCalcul; /* Exprime en secondes (attention c'est du double). @@ -102,23 +102,23 @@ typedef struct { SPX_PRIMAL s'il veut utiliser l'algorithme primal SPX_DUAL s'il veut utiliser l'algorithme dual */ /* Guidage de l'algorithme */ - int TypeDePricing; /* Le pricing est l'étape du calcul dans laquelle on choisit la variable sortante + int TypeDePricing; /* Le pricing est l'�tape du calcul dans laquelle on choisit la variable sortante dans l'algorithme dual (ou la variale entrante dans l'algorithme primal). Deux choix sont possibles: - * PRICING_DANTZIG: c'est la méthode basique, elle est rapide mais dans certains - cas conduit à faire beaucoup d'itérations pour trouver l'optimum. - * PRICING_STEEPEST_EDGE: méthode élaborée (Forrest-Goldfarb), elle demande plus de - calculs mais permet de réduite significativement le nombre d'itérations. Il est - recommander de l'utiliser pour les problèmes difficiles. */ + * PRICING_DANTZIG: c'est la m�thode basique, elle est rapide mais dans certains + cas conduit � faire beaucoup d'it�rations pour trouver l'optimum. + * PRICING_STEEPEST_EDGE: m�thode �labor�e (Forrest-Goldfarb), elle demande plus de + calculs mais permet de r�duite significativement le nombre d'it�rations. Il est + recommander de l'utiliser pour les probl�mes difficiles. */ int FaireDuScaling; /* Vaut OUI_SPX ou NON_SPX. Si l'utilisateur positionne la valeur a OUI_SPX, - le simplexe fait un scaling du probleme dès le début de la résolution. - Le scaling a pour but d'améliorer le conditionnement du problème. Il est - recommandé de l'utiliser lorsque les coefficients de la matrice des contraintes - sont très différents les un des autres (rapport > 100) */ + le simplexe fait un scaling du probleme d�s le d�but de la r�solution. + Le scaling a pour but d'am�liorer le conditionnement du probl�me. Il est + recommand� de l'utiliser lorsque les coefficients de la matrice des contraintes + sont tr�s diff�rents les un des autres (rapport > 100) */ int StrategieAntiDegenerescence; /* Vaut AGRESSIF ou PEU_AGRESSIF. - * AGRESSIF: le controle est fait à chaque iterations. + * AGRESSIF: le controle est fait � chaque iterations. * PEU_AGRESSIF: le controle est fait moins souvent. - -> Choix recommandé: AGRESSIF + -> Choix recommand�: AGRESSIF */ /* En Entree ou en Sortie */ int BaseDeDepartFournie; /* Vaut OUI_SPX ou NON_SPX */ @@ -144,15 +144,15 @@ typedef struct { a "SPX_LibererProbleme" */ double CoutMax; /* En entree: cette information n'est utilisee que si l'algorithme choisi est l'algorithme dual. On sait qu'a chaque iteration de l'algorithme dual, le cout courant est un minorant du cout optimal. - Il est donc possible de comparer ce cout à un Cout Max, seuil au dessus duquel on convient d'arreter les + Il est donc possible de comparer ce cout � un Cout Max, seuil au dessus duquel on convient d'arreter les calculs (l'algorithme sort alors avec le verdict "pas de solution"). Quelle en est l'utilite (mais il peut y en avoir d'autres) ? Dans un contexte de branch and bound, des que l'on dispose d'une solution entiere, toutes les resolutions de - probleme relaxé menant a un cout superieur a ce cout sont a rejeter. Donc, si l'on se rend compte au cours de + probleme relax� menant a un cout superieur a ce cout sont a rejeter. Donc, si l'on se rend compte au cours de l'algorithme dual, que la resolution du probleme relaxe va mener a un cout trop grand il est inutile de poursuivre les calculs. Ceci permet de gagner du temps de calcul. - ATTENTION: comme l'algorithme dual peut etre utilisé en tant que solveur (c'est à dire + ATTENTION: comme l'algorithme dual peut etre utilis� en tant que solveur (c'est � dire --------- en dehors d'un contexte de branch and bound) ou bien pour resoudre un probleme dont on de souhaite pas donner de Cout Max parce qu'on ne le connait pas, l'information "CoutMax" n'est utilisee par l'algorithme dual que si l'indicateur "UtiliserCoutMax" (argument suivant) @@ -172,8 +172,10 @@ typedef struct { double * CoutsReduits; /* Couts reduits des variables hors-base, longueur nombre de variables passees en entree du probleme. Contient la valeur 0 si la variable est basique */ /* Traces */ - char AffichageDesTraces; /* Vaut OUI_SPX ou NON_SPX */ - + char AffichageDesTraces; /* Vaut OUI_SPX ou NON_SPX */ + void *callback; + void *something_from_the_caller; + } PROBLEME_SIMPLEXE; /*******************************************************************************************/ diff --git a/src/SIMPLEXE/spx_fonctions.h b/src/SIMPLEXE/spx_fonctions.h index 280876f..ae30af7 100644 --- a/src/SIMPLEXE/spx_fonctions.h +++ b/src/SIMPLEXE/spx_fonctions.h @@ -23,6 +23,7 @@ # include "spx_definition_arguments.h" # include "spx_define.h" +#include "sirius_callback.h" /* En cours pour tests heuristique spx_dual_sortir_les_variables_binaires.c @@ -373,6 +374,10 @@ void SPX_MettreAJourLaMatriceHorsBase( PROBLEME_SPX * ); /*-----------------------------------------------------------------------------------------*/ +int SPXsetcbmessage(PROBLEME_SPX *problem_spx, callback_function the_callback_function, void *something_from_the_caller, SIRIUS_LOGLEVEL log_level); +int SPLXsetcbmessage(PROBLEME_SIMPLEXE *problem_simplex, callback_function the_callback_function, void *something_from_the_caller, SIRIUS_LOGLEVEL log_level); +callback_function SPXgetcbmessage(PROBLEME_SPX *problem_spx); + # define FONCTIONS_SPX_DEJA_DEFINIES # endif # ifdef __cplusplus diff --git a/src/SIMPLEXE/spx_getcbmessage.c b/src/SIMPLEXE/spx_getcbmessage.c new file mode 100644 index 0000000..8240c4c --- /dev/null +++ b/src/SIMPLEXE/spx_getcbmessage.c @@ -0,0 +1,13 @@ + +#include "spx_fonctions.h" + +callback_function SPXgetcbmessage(PROBLEME_SPX *problem_spx){ + callback_function call_back = NULL; + call_back = (callback_function)problem_spx->callback; +// TODO else default +if (!call_back) +{ + call_back = SiriusDefaultCallback; +} +return call_back; +} diff --git a/src/SIMPLEXE/spx_simplexe.c b/src/SIMPLEXE/spx_simplexe.c index 9ac68b2..cef63d8 100644 --- a/src/SIMPLEXE/spx_simplexe.c +++ b/src/SIMPLEXE/spx_simplexe.c @@ -28,6 +28,7 @@ # include "spx_fonctions.h" # include "spx_define.h" +#include "sirius_callback.h" # ifdef SPX_UTILISER_LES_OUTILS_DE_GESTION_MEMOIRE_PROPRIETAIRE # include "spx_memoire.h" @@ -47,10 +48,23 @@ return; PROBLEME_SPX * SPX_Simplexe( PROBLEME_SIMPLEXE * Probleme , PROBLEME_SPX * Spx ) { -void * Tas; -if ( Spx == NULL ) { - # ifdef SPX_UTILISER_LES_OUTILS_DE_GESTION_MEMOIRE_PROPRIETAIRE + callback_function call_back = (callback_function)Probleme->callback; + const char *welcome = "Sirius Welcome you!\n"; + // TODO else default + if (call_back) + { + call_back(Probleme->something_from_the_caller, welcome, 4, SIRIUS_INFO); + } + else + { + call_back = SiriusDefaultCallback; + } + void *Tas; + + if (Spx == NULL) + { +#ifdef SPX_UTILISER_LES_OUTILS_DE_GESTION_MEMOIRE_PROPRIETAIRE Tas = MEM_Init(); Spx = (PROBLEME_SPX *) MEM_Malloc( Tas, sizeof( PROBLEME_SPX ) ); if ( Spx == NULL ) { @@ -60,8 +74,8 @@ if ( Spx == NULL ) { } memset( (char *) Spx, 0, sizeof( PROBLEME_SPX ) ); Spx->Tas = Tas; - # else - Tas = NULL; +#else + Tas = NULL; Spx = (PROBLEME_SPX *) malloc( sizeof( PROBLEME_SPX ) ); if ( Spx == NULL ) { printf("Saturation memoire, impossible d'allouer un objet PROBLEME_SPX\n"); @@ -70,49 +84,57 @@ if ( Spx == NULL ) { } memset( (char *) Spx, 0, sizeof( PROBLEME_SPX ) ); Spx->Tas = Tas; - # endif -} - -Spx->AnomalieDetectee = NON_SPX; - -setjmp( Spx->EnvSpx ); - -/* Pour ne pas avoir de warning a la compilation */ -/* Attention, il ne faut pas faire appel à a une autre routine pour faire le setjmp - car lorsque le longjmp arrive, au return de la routine en question on se retrouve - n'importe ou et ça plante */ -/*SPX_InitSetJmp( Spx->EnvSpx );*/ - -if ( Spx->AnomalieDetectee != NON_SPX ) { - /* Liberation du probleme */ - /* Meme si une anomalie a ete detectee il est preferable de ne pas liberer le probleme - ici. Le probleme est de toute facon libere en fin de PNE . */ - /* SPX_LibererProbleme( Spx ); */ - Probleme->ExistenceDUneSolution = SPX_ERREUR_INTERNE; - if ( Spx->AnomalieDetectee == SPX_MATRICE_DE_BASE_SINGULIERE ) { - Probleme->ExistenceDUneSolution = SPX_MATRICE_DE_BASE_SINGULIERE; - /*printf("Trace simplexe: Matrice de base singuliere\n");*/ +#endif } - return( Spx ); -} -else { - /* Optimisation */ - SPX_SimplexeCalculs( Probleme , Spx ); - /* On ne renvoie pas de pointeur a la structure si sa desallocation - a ete demandee par l'appelant */ - if ( Probleme->LibererMemoireALaFin == OUI_SPX ) Spx = NULL; -} - -return( Spx ); -} - - - - - - - - + Spx->AnomalieDetectee = NON_SPX; + + setjmp(Spx->EnvSpx); + + /* Pour ne pas avoir de warning a la compilation */ + /* Attention, il ne faut pas faire appel � a une autre routine pour faire le setjmp + car lorsque le longjmp arrive, au return de la routine en question on se retrouve + n'importe ou et �a plante */ + /*SPX_InitSetJmp( Spx->EnvSpx );*/ + + if (Spx->AnomalieDetectee != NON_SPX) + { + /* Liberation du probleme */ + /* Meme si une anomalie a ete detectee il est preferable de ne pas liberer le probleme + ici. Le probleme est de toute facon libere en fin de PNE . */ + /* SPX_LibererProbleme( Spx ); */ + Probleme->ExistenceDUneSolution = SPX_ERREUR_INTERNE; + if (Spx->AnomalieDetectee == SPX_MATRICE_DE_BASE_SINGULIERE) + { + Probleme->ExistenceDUneSolution = SPX_MATRICE_DE_BASE_SINGULIERE; + /*printf("Trace simplexe: Matrice de base singuliere\n");*/ + } + return (Spx); + } + else + { + /* Optimisation */ + SPX_SimplexeCalculs(Probleme, Spx); + /* On ne renvoie pas de pointeur a la structure si sa desallocation + a ete demandee par l'appelant */ + if (Probleme->LibererMemoireALaFin == OUI_SPX) + Spx = NULL; + } + return (Spx); +} +int SPXsetcbmessage(PROBLEME_SPX *problem_spx, callback_function the_callback_function, void *something_from_the_caller, SIRIUS_LOGLEVEL log_level) +{ + problem_spx->callback = the_callback_function; + problem_spx->something_from_the_caller = something_from_the_caller; + // TODO + return 0; +} +int SPLXsetcbmessage(PROBLEME_SIMPLEXE *problem_simplex, callback_function the_callback_function, void *something_from_the_caller, SIRIUS_LOGLEVEL log_level) +{ + problem_simplex->callback = the_callback_function; + problem_simplex->something_from_the_caller = something_from_the_caller; + // TODO + return 0; +} diff --git a/src/SRS/srs_api.h b/src/SRS/srs_api.h index 81383ac..b46c7f5 100644 --- a/src/SRS/srs_api.h +++ b/src/SRS/srs_api.h @@ -6,7 +6,7 @@ // This file is part of SIRIUS, a linear problem solver, used in the ANTARES Simulator : https://antares-simulator.org/. #pragma once - +#include "sirius_callback.h" #include "srs_problem.h" #include "srs_problem_functions.h" #include diff --git a/src/SRS/srs_problem.c b/src/SRS/srs_problem.c index f97387a..385ef1a 100644 --- a/src/SRS/srs_problem.c +++ b/src/SRS/srs_problem.c @@ -8,6 +8,7 @@ #include #include #include +#include "sirius_callback.h" #include "srs_api.h" #include "pne_constantes_externes.h" #include "pne_fonctions.h" @@ -153,6 +154,7 @@ int initProblemMpsPointer(SRS_PROBLEM * problem_srs) { return 0; } + SRS_PROBLEM * SRScreateprob() { SRS_PROBLEM * problem_srs = (SRS_PROBLEM *)malloc(sizeof(SRS_PROBLEM)); @@ -172,7 +174,8 @@ SRS_PROBLEM * SRScreateprob() { //MPS initProblemMpsPointer(problem_srs); - + problem_srs->callback = SiriusDefaultCallback; + return problem_srs; } @@ -807,6 +810,15 @@ int SRSgetbestbound(SRS_PROBLEM * problem_srs, double * bestBoundVal) { return -1; } +int SRSsetdefaultcbmessage(SRS_PROBLEM *problem_srs, callback_function the_callback_function, SIRIUS_LOGLEVEL log_level) +{ + problem_srs->callback = SiriusDefaultCallback; +} +int SRSsetcbmessage(SRS_PROBLEM *problem_srs, callback_function the_callback_function, void *something_from_the_caller, SIRIUS_LOGLEVEL log_level) +{ + problem_srs->callback = the_callback_function; + problem_srs->something_from_the_caller = something_from_the_caller; +} # ifdef __cplusplus } diff --git a/src/SRS/srs_problem.h b/src/SRS/srs_problem.h index 8e4c6d2..09bdf54 100644 --- a/src/SRS/srs_problem.h +++ b/src/SRS/srs_problem.h @@ -34,6 +34,8 @@ typedef struct SRS_PROBLEM { int presolve; int scaling; double maxTime; + void *callback; + void *something_from_the_caller; } SRS_PROBLEM; # ifdef __cplusplus diff --git a/src/SRS/srs_problem_functions.h b/src/SRS/srs_problem_functions.h index b3f9d43..4486774 100644 --- a/src/SRS/srs_problem_functions.h +++ b/src/SRS/srs_problem_functions.h @@ -75,7 +75,8 @@ int SRSwritempsprob(PROBLEME_MPS * problem_mps, const char * fileName); int SRSfreempsprob(PROBLEME_MPS * problem_mps); int SPXcopy_problem(PROBLEME_MPS * problem_mps, PROBLEME_SIMPLEXE * problem_simplexe); int SRScopy_from_problem_simplexe(SRS_PROBLEM * problem_srs, PROBLEME_SIMPLEXE * problem_simplexe); - +int SRSsetdefaultcbmessage(SRS_PROBLEM *problem_srs, callback_function the_callback_function, SIRIUS_LOGLEVEL log_level); +int SRSsetcbmessage(SRS_PROBLEM *problem_srs, callback_function the_callback_function, void *something_from_the_caller, SIRIUS_LOGLEVEL log_level); # ifdef __cplusplus } # endif