// ---------------------------------------------------------------------------
// $Id: BestFit.cc 227 2008-08-13 20:51:32Z daaugusto $
//
//   BestFit.cc (created on Sat Nov 19 18:00:35 BRT 2005)
// 
//   Genetic Algorithm File Fitter (gaffitter)
//
//   Copyright (C) 2005-2008 Douglas A. Augusto
// 
// This file is part of gaffitter.
// 
// gaffitter is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at
// your option) any later version.
// 
// gaffitter is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with gaffitter; if not, see <http://www.gnu.org/licenses/>.
//
// ---------------------------------------------------------------------------

#include "BestFit.h"

#include <vector>

using namespace std;

// ---------------------------------------------------------------------------
void
BestFit::Evolve()
{
   if( m_params.m_verbose ) cout << *this;

   m_solution = new BinSet();

   /* Best Fit Decreasing */
   for( unsigned i = 0; i < m_files.size(); ++i )
   {
      // find the best free bin; insert another bin if necessary
      int best_bin = -1;
      Params::Size_t best_fit = numeric_limits<Params::Size_t>::max();

      for( unsigned j = 0; j < m_solution->Count(); ++j )
      {
         if( (*m_solution)[j].Free() >= m_files[i]->Size() ) 
         {
            if( (*m_solution)[j].Free() - m_files[i]->Size() < best_fit )
            {
               best_bin = j;
               best_fit = (*m_solution)[j].Free() - m_files[i]->Size();
            }
         }
      }

      if( best_bin == -1 ) 
         m_solution->AddBin( m_params.m_target ).AddItem( m_files[i] );
      else (*m_solution)[best_bin].AddItem( m_files[i] );
   }
}

// --------------------------------------------------------------------
ostream& 
BestFit::Write( ostream& s ) const 
{ 
   s << endl;
   s << "> -----------------------------------" << endl;
   s << "> Best Fit search (approximate)    " << endl;
   s << "> -----------------------------------" << endl;

   Optimizer::Write( s );

   s << endl << flush;

   return s;
}

// --------------------------------------------------------------------
