#include "VertexCoverProblem.h"
#include "SgEngine.h"
#include "Random.h"
#include "Parameters.h"
#include "StoppingConditions.h"

#include <cstdio>
#include <string>

int main( int argc, char *argv[] ) {
  if ( argc == 1/* < 3*/ ) {
    std::fprintf( stderr, "Usage: %s <file(s)>\n", argv[0] );
    return 1;
  }

  for ( int problemNumber = 1; problemNumber < argc; problemNumber++ ) {
    std::printf( "\n\n==== Problem #%d ====\n", problemNumber );
    std::string filename( argv[problemNumber] );
    VertexCoverProblem vcp( filename );
    vcp.print( false );
    if ( vcp.isGood() ) {
      SgEngine engine( &vcp );
      StoppingConditions stopCon( &engine );
      stopCon.add( StoppingConditions::GENERATIONS,
                   1000*1000 ); // 1 million generations
      stopCon.add( StoppingConditions::CPU_TIME,
                   10 ); // 5 seconds of cpu time
      stopCon.add( StoppingConditions::CONVERGED_ALLELES,
                   vcp.getNumberOfGenes() - ( vcp.getNumberOfGenes() >> 3 ) ); // 87.5% of alleles must converge

      do {
        for ( unsigned i = 0;i < Parameters::getInstance()->getPollingInterval(); i++ )
          engine.doOneGeneration( true );
      } while ( !stopCon.pollDisjunctive( true ) );

      std::printf( "==== Done ====\n" );
      std::printf( "SgEngine finished in %u seconds; %u alleles converged after %u generations.\n",
                   stopCon.getCpuTime(),
                   engine.getPopulation()->getNumberOfConvergedAlleles(),
                   engine.getGenerationCount() );
      engine.printBestIndividual( false );
    }
  }

  Parameters::deleteInstance();
  Random::deleteInstance();
  return 0;
}
