vers Labo Algo
Labo Algo

Sources de tspgen 0.32 : résolution du problème du voyageur de commerce


/*==========================================================================
Project : tspgen 0.32
File    : tsplog.cpp
Purpose : logs (screen, log file, html, time, gnuplot...)
==========================================================================*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "tsplog.h"
#include "Individual.h"


/*========================================================================
============================== TspLog =====================================
==========================================================================*/

/*========================================================================
Function : TspLog constructor
In :  iLogLevel0 : the level of log for the log file (DEBUG, INFO...)
      iScreenLogLevel0 : the level of log for screen (DEBUG, INFO...)
      sLogDir : the directory of the log file
      sBaseLogName : the name of the log file
==========================================================================*/
TspLog::TspLog(int iLogLevel0, int iScreenLogLevel0, char *sLogDir, char *sBaseLogName)
{
  char sTemp[255];
  bool bOk;
  iStartLogTime = time(NULL);

  iLogLevel = iLogLevel0;
  iScreenLogLevel = iScreenLogLevel0;
  iNiveau=0;
  strcpy(sNiveau, "");

  sprintf(sTemp, "%s/%s.log", sLogDir, sBaseLogName);
/*  printf("Ouverture de %s\n", sTemp);
  fflush(stdout);*/
  fGlobalLog = fopen(sTemp, "w");

  bOk = (fGlobalLog!=NULL);

  if (bOk)
  {
    sprintf(sTemp, "%s/%s.html", sLogDir, sBaseLogName);
/*    printf("Ouverture de %s\n", sTemp);
    fflush(stdout);*/
    fHtmlLog = fopen(sTemp, "w");

    bOk = (fHtmlLog != NULL);
  }

  if (bOk)
  {
    fprintf(fHtmlLog, "<html>\n");
    fprintf(fHtmlLog, "<head>\n");
    fprintf(fHtmlLog, "   <title>%s</title>\n", sBaseLogName);
    fprintf(fHtmlLog, "</head>\n");
    fprintf(fHtmlLog, "<body bgcolor=\"#ffffff\">\n");

    sprintf(sTemp, "%s/%s.time", sLogDir, sBaseLogName);
/*    printf("Ouverture de %s\n", sTemp);
    fflush(stdout);*/
    fTimeLog = fopen(sTemp, "w");

    bOk = (fTimeLog != NULL);
  }

  if (bOk)
  {
    CreateGnuPlotFile(sLogDir, sBaseLogName);
  }
}

/*========================================================================
Function : create a gnuplot script for the time log
In :  sLogDir : the directory of the log file
      sBaseLogName : the name of the log file
==========================================================================*/
void TspLog::CreateGnuPlotFile(char *sLogDir, char *sBaseLogName)
{
  FILE* fGnuPlot;
  char sGnuPlotFileName[255];
  char sPngFileName[255];
  char sTimeLogName[255];

  sprintf(sGnuPlotFileName, "%s/%s.plot", sLogDir, sBaseLogName);
  sprintf(sPngFileName, "%s.png", sBaseLogName);
  sprintf(sTimeLogName, "%s.time", sBaseLogName);

  fGnuPlot = fopen(sGnuPlotFileName, "w");

  fprintf(fGnuPlot, "set terminal png small color\n");
  fprintf(fGnuPlot, "set xlabel \"Temps\"\n");
  fprintf(fGnuPlot, "set ylabel \"-Distance totale du parcours\"\n");
  fprintf(fGnuPlot, "set autoscale\n");
  fprintf(fGnuPlot, "set out \"%s\"\n", sPngFileName);
  fprintf(fGnuPlot, "plot '%s' title \"%s\" with lines\n", sTimeLogName,sTimeLogName);

  fclose(fGnuPlot);
}

/*========================================================================
Function : TspLog destructor
==========================================================================*/
TspLog::~TspLog()
{
  fclose(fGlobalLog);
  fclose(fTimeLog);
  fclose(fHtmlLog);
}

/*========================================================================
Function : Log a message on screen and on a log file
==========================================================================*/
void TspLog::GlobalLog()
{
  if (iCurrentLevel <= iLogLevel)
  {
    fprintf(fGlobalLog, "%s%s\n", sNiveau, sCurrentMessage);
    fflush(fGlobalLog);
  }
  if (iCurrentLevel <= iScreenLogLevel)
  {
    // tronquer le message ? ***
    fprintf(stdout, "%s%s\n", sNiveau, sCurrentMessage);
    fflush(stdout);
  }
}

/*========================================================================
Function : print a debug message
In :  sMessage : the message to display
==========================================================================*/
void TspLog::DebugMsg(char *sMessage)
{
  iCurrentLevel = LEVEL_DEBUG;
  sprintf(sCurrentMessage, "<%s> : %s", sFunctionName, sMessage);
  GlobalLog();
}

/*========================================================================
Function : print a message on screen only
In :  sMessage : the message to display
==========================================================================*/
void TspLog::ScreenMsg(char *sMessage)
{
  iCurrentLevel = LEVEL_DEBUG;
  if (iCurrentLevel <= iScreenLogLevel)
  {
    //printf(sMessage);
    //fprintf(stdout, "%s\n", sMessage);
    fprintf(stdout, "%s%s\n", sNiveau, sMessage);
    fflush(stdout);
  }
}

/*========================================================================
Function : print an info message
In :  sMessage : the message to display
==========================================================================*/
void TspLog::InfoMsg(char *sMessage)
{
  iCurrentLevel = LEVEL_INFO;
  sprintf(sCurrentMessage, "<%s> : %s", sFunctionName, sMessage);
  GlobalLog();
}

/*========================================================================
Function : print an error message
In :  sMessage : the message to display
==========================================================================*/
void TspLog::ErrorMsg(char *sMessage)
{
  iCurrentLevel = LEVEL_CRITICAL;
  sprintf(sCurrentMessage, "*** ERREUR : <%s> : %s", sFunctionName, sMessage);
  GlobalLog();
}

/*========================================================================
Function : print informations on the project
In : _project_info : info (name)
     _project_version : version, date
     _project_author : author(s)
==========================================================================*/
void TspLog::ProjectInfoMsg(char *_project_info, char *_project_version, char *_project_author)
{
  iCurrentLevel = LEVEL_INFO;
  sprintf(sCurrentMessage, "Project info : %s\nProject version : %s\nProject author : %s",
                         _project_info, _project_version, _project_author);
  GlobalLog();
}

/*========================================================================
Function :
In :
==========================================================================*/
void TspLog::CalculeChaineNiveau()
{
  int i;
  strcpy(sNiveau, "");
  for (i=0; i<iNiveau; i++)
  {
    strcat(sNiveau, "     ");
  }
}

/*========================================================================
Function : Log the beginning of a function
In : sFunctionName0
     iInstance0
     iCurrentLevel0
     iNbIteration0
==========================================================================*/
void TspLog::StartFunction(char *sFunctionName0, int iInstance0, int iCurrentLevel0, int iNbIteration0)
{
  sprintf(sFunctionName, "%s[%d]", sFunctionName0, iInstance0);
  iNbIteration = iNbIteration0;
  iCurrentLevel=iCurrentLevel0;

  CalculeChaineNiveau();
  iNiveau++;

  sprintf(sCurrentMessage, "===> Début <%s>", sFunctionName);
  GlobalLog();

  if (iNbIteration > 0)
  {
    iStartTime = time(NULL);
    sprintf(sCurrentMessage, "<%s> : Nb itérations prévues : %d", sFunctionName, iNbIteration);
    GlobalLog();
  }
}

/*========================================================================
Function : Log the end of a function
In : sFunctionName0
     iInstance0
==========================================================================*/
void TspLog::EndFunction(char *sFunctionName0, int iInstance0)
{
  double lfNbIterParSeconde;
  iNiveau--;
  CalculeChaineNiveau();

  sprintf(sFunctionName, "%s[%d]", sFunctionName0, iInstance0);

  iCurrentLevel = LEVEL_DEBUG;

  if (iNbIteration > 0)
  {
    iEndTime = time(NULL);
    if ((iEndTime-iStartTime) != 0)
    {
      lfNbIterParSeconde = (float)(iNbIteration)/(float)(iEndTime-iStartTime);
    }
    else
    {
      lfNbIterParSeconde = (float)(iNbIteration);
    }
    sprintf(sCurrentMessage, "<%s> : Temps de calcul = %d secondes (%f itérations/secondes)", sFunctionName, iEndTime-iStartTime, lfNbIterParSeconde);
    GlobalLog();
  }
  sprintf(sCurrentMessage, "<=== Fin   <%s>", sFunctionName);
  GlobalLog();
}


/*========================================================================
Function : Logs the best individual
In :  iCurrentIteration
      sPath
      lfFitness
      iNbCities
      bDefaultProblem
      bTSPLIB,
      sCitiesPosX
      sCitiesPosY
TODO : réécrire avec Individual en entrée
==========================================================================*/
void TspLog::LogRecord(int iCurrentIteration,
                       char *sPath,
                       double lfFitness,
                       int iNbCities,
                       bool bDefaultProblem,
                       bool bTSPLIB,
                       char *sCitiesPosX,
                       char *sCitiesPosY)
{
  int iTempsCalcul;

  iTempsCalcul = TimeLog(lfFitness);

  iCurrentLevel = LEVEL_INFO;
  sprintf(sCurrentMessage, "<%s> (itération %d/%d) (%d s) :\tNouveau record : <<< %f >>>", sFunctionName, iCurrentIteration, iNbIteration, iTempsCalcul, -lfFitness);
  GlobalLog();

  if (fHtmlLog != NULL)
  {
    fprintf(fHtmlLog, "<applet code=\"DisplayTsp.class\" width=200 height=200>\n");
    if (bDefaultProblem)
    {
      fprintf(fHtmlLog, "<param name=Problem value=\"default\">\n");
    }
    else
    {
      if (bTSPLIB)
      {
        fprintf(fHtmlLog, "<param name=ProblemType value=\"tsplib\">\n");
      }
      fprintf(fHtmlLog, "<param name=Problem value=\"custom\">\n");
      fprintf(fHtmlLog, "<param name=NbCities value=\"%d\">\n", iNbCities);
      fprintf(fHtmlLog, "<param name=CitiesPosX value=\"%s\">\n", sCitiesPosX);
      fprintf(fHtmlLog, "<param name=CitiesPosY value=\"%s\">\n", sCitiesPosY);
    }
    fprintf(fHtmlLog, "<param name=Parcours value=\"%s\">\n", sPath);
    fprintf(fHtmlLog, "<hr>\n</applet><br>\n");
    fprintf(fHtmlLog, "<i>%s (%d s)</i><br><br>\n", sFunctionName, iTempsCalcul);
    fflush(fHtmlLog);
  }
}

/*========================================================================
Function : Time log (gnuplot compatible)
In : lfFitness
==========================================================================*/
int TspLog::TimeLog(double lfFitness)
{
  int iTempsCalcul;
  iTempsCalcul=(int)(time(NULL)-iStartLogTime);

  fprintf(fTimeLog, "%d\t%f\t#%s\n", iTempsCalcul, lfFitness, sFunctionName);
  fflush(fTimeLog);

  return iTempsCalcul;
}


vers Labo Algo
Labo Algo

Alexandre Aupetit, Mai 2004