MeshKit  1.0
IASolverToolInt.cpp
Go to the documentation of this file.
00001 // IASolverToolInt.cpp
00002 
00003 #include "meshkit/IASolverToolInt.hpp"
00004 #include "meshkit/IAData.hpp"
00005 #include "meshkit/IASolution.hpp"
00006 #include "meshkit/IPData.hpp"
00007 #include "meshkit/IAWeights.hpp"
00008 
00009 #include <vector>
00010 #include <math.h>
00011 #include <cstdio>
00012 #include <assert.h>
00013 
00014 namespace MeshKit {
00015  
00016 IASolverToolInt::IASolverToolInt() 
00017   : IASolverTool(), 
00018   debuggingToolInt(false) 
00019   {ipData = new IPData;}
00020   
00021 IASolverToolInt::IASolverToolInt( const IAData *ia_data, IASolution *ia_solution, bool debugging_set) 
00022   : IASolverTool(ia_data, ia_solution, debugging_set), 
00023   debuggingToolInt( debugging_set ) 
00024   {ipData = new IPData;}
00025   
00026 IASolverToolInt::IASolverToolInt(const bool debugging_set) 
00027   : IASolverTool(debugging_set), 
00028   debuggingToolInt(debugging_set) 
00029   {ipData = new IPData;}
00030 
00031   
00032 IASolverToolInt::~IASolverToolInt()
00033 {
00034   ipData = NULL;
00035 }
00036   
00037   
00038 void IASolverToolInt::round_solution()
00039 {
00040   assert( iaSolution );
00041   for (unsigned int i = 0; i < iaSolution->x_solution.size(); ++i )
00042   {
00043     assert(iaSolution->x_solution[i] >= 0.);
00044     iaSolution->x_solution[i] = floor( iaSolution->x_solution[i] + 0.5 );
00045   }
00046 }
00047   
00048   
00049 bool IASolverToolInt::solution_is_integer(const bool print_non_integer)
00050 {
00051   assert( iaSolution );
00052   
00053   int num_non_int = 0;
00054   class NonInt
00055   {
00056   public:
00057     double x;
00058     int i;
00059     double dist () const
00060     {
00061       double xm = fabs( x - floor(x));
00062       double xp = fabs( floor(x) + 1. - x);
00063       // printf("dist: x %f floor %f xm %f xp %f\n", x, floor(x), xm, xp); // debug
00064       if (xm > xp)
00065         return xp;
00066       else
00067         return xm;
00068     }
00069     NonInt() : x(0.), i(-1) {}
00070     NonInt(const double x_val, const unsigned int i_val) : x(x_val), i( (int) i_val ) {}
00071   };
00072   
00073   NonInt worst_non_int;
00074   
00075   bool all_int = true;  
00076   for (unsigned int i = 0; i<iaSolution->x_solution.size(); ++i)
00077   {
00078     const double x = iaSolution->x_solution[i];
00079     if (!is_integer(x))
00080     {
00081       all_int = false;
00082       if (print_non_integer)
00083       {
00084         NonInt xnon(x,i);
00085         if (xnon.dist() > worst_non_int.dist())
00086           worst_non_int = xnon;
00087         if (num_non_int++ == 0)
00088         {
00089           printf("\nChecking solution integrality\n");
00090         }
00091         const double goal = iaData->I[i];
00092         printf(" x %d (g %f) is %f NON-INTEGER\n", i, goal, x);
00093       }
00094       // shortcut return if we're not printing anything
00095       else
00096         return false; 
00097     }
00098   }
00099   if (print_non_integer)
00100   {
00101     if (num_non_int == 0)
00102     {
00103       printf("all integer\n");
00104     }
00105     else
00106     {
00107       printf("%d of %lu NON-INTEGERS\n", num_non_int, iaSolution->x_solution.size());
00108       printf("worst was x_%d = %g\n", worst_non_int.i, worst_non_int.x );
00109     }
00110   }
00111   return all_int;
00112 }
00113 
00114 
00115 void IASolverToolInt::get_frac( double x, int &integer, double &frac) const
00116 {
00117   assert(x>=0.);
00118   integer = floor(x); 
00119   frac = x - integer;
00120   assert( frac < 1. );
00121   assert( frac >= 0. );
00122 }
00123 
00124 double IASolverToolInt::get_xl( int i ) const
00125 {
00126   return floor( ipData->relaxedSolution[i] );
00127 }
00128 
00129 double IASolverToolInt::get_xh( int i ) const
00130 {
00131   return floor( ipData->relaxedSolution[i] )+1;
00132 }
00133 
00134 double IASolverToolInt::get_km( int i, double x ) const
00135 {
00136   const double y =  get_xl(i) - x;
00137   return y>0. ? y : 0.;
00138 }
00139 
00140 void IASolverToolInt::get_km( int i, double x, int &km_integer, double &km_frac ) const
00141 {
00142   get_frac( get_km(i,x), km_integer, km_frac);
00143 }
00144 
00145 double IASolverToolInt::get_kp( int i, double x ) const
00146 {
00147   const double y = x - get_xh(i);
00148   return y > 0 ? y : 0.;
00149 }
00150 
00151 void IASolverToolInt::get_kp( int i, double x, int &kp_integer, double &kp_frac ) const
00152 {
00153   get_frac( get_kp(i,x), kp_integer, kp_frac);
00154 }
00155   
00156   
00157   
00158 bool IASolverToolInt::randomize_weights_of_non_int(IAWeights* weights, const double rand_factor)
00159 {
00160     
00161   for (size_t i=0; i<iaSolution->x_solution.size(); ++i) 
00162   {
00163     const double x = iaSolution->x_solution[i];
00164     if (!is_integer(x))
00165     {
00166       const double d = IAWeights::rand_excluded_middle();
00167       (*weights)[i] *= 1. + rand_factor * d;
00168     }
00169   }
00170   return true;
00171 }
00172 
00173 } // namespace MeshKit
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines