Logo Search packages:      
Sourcecode: gaffitter version File versions  Download package

Params.cc

// ---------------------------------------------------------------------
// $Id: Params.cc,v 1.62 2006/08/28 16:34:57 daaugusto Exp $
//
//   Params.cc (created on Tue Aug 23 18:48:35 BRT 2005)
// 
//   Genetic Algorithm File Fitter (gaffitter)
//
//   Copyright (C) 2005-2006 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 2 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, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// ---------------------------------------------------------------------

#include "Params.hh"
#include "util/Exception.hh"
#include "util/CmdLineParser.hh"

#include <sstream>
#include <cmath>

using namespace std;

//---------------------------------------------------------------------
void
00039 Params::ShowVersion() const // --version
{
   cout

   << "gaffitter 0.5.0 (Genetic Algorithm File Fitter) (C) 2005-2006\n"
   << "\n"
   << "This is free software. You may redistribute copies of it under the terms\n"
   << "of the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.\n"
   << "There is NO WARRANTY, to the extent permitted by law.\n"
   << "\n"
   << "Written by Douglas Adriano Augusto (daaugusto).\n";
}

//---------------------------------------------------------------------
void
00054 Params::ShowUsage(const char* app = "gaffitter") const // -h or --help
{
   cout  

   << "Genetic Algorithm File Fitter (GAFFitter)\n"
   << "\n"
   << "Usage: " << app << " -t target [options...] <files>\n"
   << "       ... | " << app << " - -t target [options...] [files]\n"
   << "\n"
   << "General options:\n"
   << "  -t <f>, --target <f>\n"
   << "     target size (mandatory), f>0.0\n"
   << "  -b, --bytes\n"
   << "     target, min and max size in bytes\n"
   << "  -k, --kb\n"
   << "     target, min and max size in kibi bytes (KiB); KB if --si\n"
   << "  -m, --mb\n"
   << "     target, min and max size in mebi bytes (MiB) [default]; MB if --si\n"
   << "  -g, --gb\n"
   << "     target, min and max size in gibi bytes (GiB); GB if --si\n"
   << "  --si\n"
   << "     use powers of 1000 (not 1024) for target, min, max and output sizes\n"
   << "  -i, --iter\n"
   << "     iterate (extract volumes) as much as possible\n"
   << "  -i <n>, --iter <n>\n"
   << "     maximum number of iterations (volumes) [default = 1]\n"
   << "  -v, --verbose\n"
   << "     verbose\n"
   << "  --min <n>, --min-size <n>\n"
   << "     minimum file size [default = none]\n"
   << "  --max <n>, --max-size <n>\n"
   << "     maximum file size [default = none]\n"
   << "  --bs <n>, --block-size <n>\n"
   << "     the smallest amount of bytes a file can occupy [default = 1]\n"
   << "  --ss, --show-size\n"
   << "     print the size of each file\n"
   << "  --sb, --show-bytes\n"
   << "     also print the sizes in bytes\n"
   << "  --su, --show-unselected\n"
   << "     print unselected files\n"
   << "  --hsel, --hide-selected\n"
   << "     don't print selected files\n"
   << "  --hs, --hide-summary\n"
   << "     hide summary line containing sum, difference and number of\n"
   << "     selected files\n"
   << "  -s, --sort-by-size\n"
   << "     sort the output by size, not by name\n"
   << "  -n, --no-case\n"
   << "     use case-insensitive sorting\n"
   << "  -r, --sort-reverse\n"
   << "     sort the output in reverse order\n"
   << "  --ew <char>, --enclose-with <char>\n"
   << "     enclose file names with \"char\" [default = none]\n"
   << "  --dw <char>, --delimit-with <char>\n"
   << "     delimit file names (lines) with \"char\" [default = newline]\n"
   << "  --version\n"
   << "     print gaffitter version and exit\n"
   << "  -h, --help\n"
   << "     print this help and exit\n"
   << "\n"
   << "Direct Input options:\n"
   << "  --di, --direct-input\n"
   << "     switch to direct input mode, i.e., read directly \"size identifier\"\n"
   << "     pairs instead of file names\n"
   << "  --di-b, --di-bytes\n"
   << "     assume input sizes as bytes\n"
   << "  --di-k, --di-kb\n"
   << "     assume input sizes as kibi bytes (KiB); KB if --di-si\n"
   << "  --di-m, --di-mb\n"
   << "     assume input sizes as mebi bytes (MiB); MB if --di-si\n"
   << "  --di-g, --di-gb\n"
   << "     assume input sizes as gibi bytes (GiB); GB if --di-si\n"
   << "  --di-si\n"
   << "     use powers of 1000 (not 1024) for input sizes\n"
   << "\n"
   << "Genetic Algorithm options:\n"
   << "  --ga-s <n>, --ga-seed <n>\n"
   << "     GA initialization seed, n>=0 [default = 1]; 0 = random\n"
   << "  --ga-rs, --ga-random-seed\n"
   << "     use random GA seed (same as --ga-seed 0)\n"
   << "  --ga-ng <n>, --ga-num-generations <n>\n"
   << "     maximum number of generations, n>0 [default = auto]\n"
   << "  --ga-ps <n>, --ga-pop-size <n>\n"
   << "     number of individuals, n>tournament_size [default = auto]\n"
   << "  --ga-cp <f>, --ga-cross-prob <f>\n"
   << "     crossover probability, 0.0<=f<=1.0 [default = 0.95]\n"
   << "  --ga-mp <f>, --ga-mutation-prob <f>\n"
   << "     mutation probability (per gene), 0.0<=f<=1.0 [default = auto]\n"
   << "  --ga-sp <n>, --ga-sel-pressure <n>\n"
   << "     selection pressure (tournament size), 2<=n<pop_size [default = 2]\n"
   << "\n"
   << "Other search methods\n"
   << "  --bf, --brute-force\n"
   << "     tries all possible combinations (use carefully!)\n"
   << "  --ap, --approximate\n"
   << "     approximate the solution using Best First search (non-optimal\n"
   << "     but very fast)\n"
   << "  --sp, --split\n"
   << "     just split the input when target size is reached (preserves\n"
   << "     original order while splitting)\n";
}

//----------------------------------------------------------------------
bool 
00158 Params::Initialize()
{
   CmdLineParser Opts(m_argc,m_argv,m_cmdline_items);

   Opts.Bool.Add("-h","--help");
   Opts.Bool.Add("--version");

   Opts.Bool.Add("-");

   Opts.Bool.Add("--si");

   Opts.Bool.Add("-b","--bytes");
   Opts.Bool.Add("-k","--kb");
   Opts.Bool.Add("-m","--mb");
   Opts.Bool.Add("-g","--gb");

   Opts.Bool.Add("--di","--direct-input");
   Opts.Bool.Add("--di-b","--di-bytes");
   Opts.Bool.Add("--di-k","--di-kb");
   Opts.Bool.Add("--di-m","--di-mb");
   Opts.Bool.Add("--di-g","--di-gb");
   Opts.Bool.Add("--di-si");

   Opts.Float.Add("-t","--target",-1.0,0.0,numeric_limits<Size_t>::max());

   Opts.Int.Add("-i","--iter",1,1,numeric_limits<int>::max());
   Opts.Bool.Add("-i","--iter");

   Opts.Float.Add("--min","--min-size",0.0,0.0,numeric_limits<Size_t>::max());
   Opts.Float.Add("--max","--max-size",numeric_limits<Size_t>::max(),0.0,
                                       numeric_limits<Size_t>::max());

   Opts.Int.Add("--bs","--block-size",1,1,numeric_limits<int>::max());

   Opts.Bool.Add("-v","--verbose");

   Opts.Bool.Add("--hs","--hide-summary");
   Opts.Bool.Add("--ss","--show-size");
   Opts.Bool.Add("--sb","--show-bytes");
   Opts.Bool.Add("--su","--show-unselected");
   Opts.Bool.Add("--hsel","--hide-selected");

   Opts.Bool.Add("-s","--sort-by-size");
   Opts.Bool.Add("-r","--sort-reverse");
   Opts.Bool.Add("-n","--no-case");

   Opts.Int.Add("--ga-ng","--ga-num-generations",0,0,numeric_limits<int>::max());
   Opts.Int.Add("--ga-ps","--ga-pop-size",0,0,numeric_limits<int>::max());
   Opts.Float.Add("--ga-cp","--ga-cross-prob",0.95,0.0,1.0);
   Opts.Float.Add("--ga-mp","--ga-mutation-prob",-1.0,0.0,1.0);
   Opts.Int.Add("--ga-sp","--ga-sel-pressure",0,0,numeric_limits<int>::max());
   Opts.Bool.Add("--ga-rs","--ga-random-seed");
   Opts.Int.Add("--ga-s","--ga-seed",1,0,numeric_limits<long>::max());

   Opts.Bool.Add("--bf","--brute-force");
   Opts.Bool.Add("--ap","--approximate");
   Opts.Bool.Add("--sp","--split");

   Opts.Char.Add("--dw","--delimit-with",'\n');
   Opts.Char.Add("--ew","--enclose-with",'\0');

   // -- Get the options! ----------------
   Opts.Process();
   // ------------------------------------

   if (Opts.Bool.Get("-h")) { ShowUsage(); return false; /* exit */ }
   if (Opts.Bool.Get("--version")) { ShowVersion(); return false; /* exit */ }

   m_pipe = Opts.Bool.Get("-");

   // ---- units
   if (Opts.Bool.Get("--si"))
   {
      m_unit_symbol='\0';
      m_unit_power=1000.0;
   }
   else
   {
      m_unit_symbol='i';
      m_unit_power=1024.0;
   }

   if (Opts.Bool.Get("-b")) m_factor = 1.0;
   else if (Opts.Bool.Get("-k")) m_factor = KB();
   else if (Opts.Bool.Get("-m")) m_factor = MB();
   else if (Opts.Bool.Get("-g")) m_factor = GB();
   else m_factor = MB(); // default to MiB (mebibyte)

   // --- manual input (no files)
   m_direct_input = Opts.Bool.Get("--di");

   if (m_direct_input)
   {
      double di_power = Opts.Bool.Get("--di-si") ? 1000.0 : 1024.0;

      if (Opts.Bool.Get("--di-b")) m_di_factor = 1.0;
      else if (Opts.Bool.Get("--di-k")) m_di_factor = KB(di_power);
      else if (Opts.Bool.Get("--di-m")) m_di_factor = MB(di_power);
      else if (Opts.Bool.Get("--di-g")) m_di_factor = GB(di_power);
      else m_no_metric = true; // default to no metric!
   }

   // ---- Target size (default = none) [mandatory option]
   m_target = Opts.Float.Get<Size_t>("-t");
   if (m_target <= 0.0) throw E_NoTarget(); 

   // adjust power of m_target if necessary (when no_metric is unset)
   if (!m_no_metric) m_target = floor(m_target * m_factor);

   // ---- Iterations (default = 1)
   if (Opts.Int.Found("-i")) m_iterations = Opts.Int.Get("-i");
   else if (Opts.Bool.Get("-i")) 
           m_iterations = numeric_limits<int>::max(); // "infinite"

   // --- min and max file size
   m_min_size = Opts.Float.Get<Size_t>("--min");

   // check range and if m_factor must be applicated
   if (m_min_size > 0.0 && !m_no_metric) m_min_size = ceil(m_min_size * m_factor);

   m_max_size = Opts.Float.Get<Size_t>("--max");

   // check range and if m_factor must be applicated
   if (m_max_size <= 0.0) m_max_size = numeric_limits<Size_t>::max();
   else if (!m_no_metric) m_max_size = floor(m_max_size * m_factor);

   // --- block size
   m_block_size = Opts.Int.Get("--bs");

   // --- verbose
   m_verbose = Opts.Bool.Get("-v");

   // --- hide summary (last line)?
   m_hide_summary = Opts.Bool.Get("--hs");
   
   // --- show sizes?
   m_show_size = Opts.Bool.Get("--ss");
   
   // --- show bytes?
   // showing bytes in direct input mode (with no metric) make no sense.
   m_show_bytes = Opts.Bool.Get("--sb") && !m_no_metric;

   // --- show unselected files?
   m_show_unselected = Opts.Bool.Get("--su");

   // --- hide selected files?
   m_hide_selected = Opts.Bool.Get("--hsel");

   // --- sort by size?
   m_sort_by_size = Opts.Bool.Get("-s");

   // --- reverse order while sorting?
   m_sort_reverse = Opts.Bool.Get("-r");

   // --- case-sensitive or insensitive? (only for "sort by name")
   m_no_case = Opts.Bool.Get("-n");

   // ---- Genetic Algorithm ------------------------------------------
   /* m_ga_pop_size and m_ga_num_gens are (auto)adjusted in
    * Optimizer::Initialize */

   // -- Number of generations
   m_ga_num_gens = Opts.Int.Get("--ga-ng"); // check range: done in 
                                            // Optimizer::Initialize
   // -- Population size
   m_ga_pop_size = Opts.Int.Get("--ga-ps"); // check range: done in 
                                            // Optimizer::Initialize

   // -- Crossover probability
   m_ga_cross_prob = Opts.Float.Get("--ga-cp");

   // -- Mutation probability
   m_ga_mut_prob = Opts.Float.Get("--ga-mp"); // automatic value adjusted 
                                              // by GeneticAlgorithm (~1/L)

   // -- Selection pressure (currently "tournament size")
   m_ga_sel_pressure = Opts.Int.Get("--ga-sp"); // check range: done in 
                                                // Optimizer::Initialize

   // -- Initialization seed
   if (Opts.Bool.Get("--ga-rs")) m_ga_seed = 0;
   else m_ga_seed = Opts.Int.Get("--ga-s");

   // ---- Search ----------------------------------------------
   // --- Brute Force Search. May be very slow ( O(2^|input|) )
   m_brute_force = Opts.Bool.Get("--bf");

   // --- Best First Search (very fast but just approximate)
   m_approximate = Opts.Bool.Get("--ap");

   // --- Split "Search"
   m_split = Opts.Bool.Get("--sp");

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

   // Separate and Enclose options
   m_delimit_chr = Opts.Char.Get("--dw"); // default = "\n" (new line)
   m_enclose_chr = Opts.Char.Get("--ew"); // default = none (no enclose char)
   m_enclose = Opts.Char.Found("--ew"); // C++ hasn't a truly empty char (not '\0')

   // ---------------
   return true;
}

//---------------------------------------------------------------------
std::string
00364 Params::PrettySize(Size_t size) const
{
   std::ostringstream o;

   if (m_no_metric) // = (m_direct_input && m_no_metric)
   {
      // just print the size without units
      o.precision(16); o << size; return o.str();
   }

   // format adjust
   o << std::fixed; 
   
   // module
   Size_t positive_bytes = (size < 0.0) ? -size : size;

   o.precision(2);

   if (positive_bytes >= GB())
      o << size/GB() << 'G'<<m_unit_symbol<<'B';
   else if (positive_bytes >= MB())
      o << size/MB() << 'M'<<m_unit_symbol<<'B';
   else if (positive_bytes >= KB())
      o << size/KB() << 'K'<<m_unit_symbol<<'B';
   else { o.precision(0); o << size << "Bytes"; }
   
   // print bytes together?
   if (m_show_bytes) { o.precision(0); o << " (" << size << ")"; }

   return o.str();
}

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

Generated by  Doxygen 1.6.0   Back to index