MeshKit
1.0
|
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