1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// IASolverToolInt.cpp

#include "meshkit/IASolverToolInt.hpp"
#include "meshkit/IAData.hpp"
#include "meshkit/IASolution.hpp"
#include "meshkit/IPData.hpp"
#include "meshkit/IAWeights.hpp"

#include <vector>
#include <math.h>
#include <cstdio>
#include <assert.h>

namespace MeshKit {
 
IASolverToolInt::IASolverToolInt() 
  : IASolverTool(), 
  debuggingToolInt(false) 
  {ipData = new IPData;}
  
IASolverToolInt::IASolverToolInt( const IAData *ia_data, IASolution *ia_solution, bool debugging_set) 
  : IASolverTool(ia_data, ia_solution, debugging_set), 
  debuggingToolInt( debugging_set ) 
  {ipData = new IPData;}
  
IASolverToolInt::IASolverToolInt(const bool debugging_set) 
  : IASolverTool(debugging_set), 
  debuggingToolInt(debugging_set) 
  {ipData = new IPData;}

  
IASolverToolInt::~IASolverToolInt()
{
  ipData = NULL;
}
  
  
void IASolverToolInt::round_solution()
{
  assert( iaSolution );
  for (unsigned int i = 0; i < iaSolution->x_solution.size(); ++i )
  {
    assert(iaSolution->x_solution[i] >= 0.);
    iaSolution->x_solution[i] = floor( iaSolution->x_solution[i] + 0.5 );
  }
}
  
  
bool IASolverToolInt::solution_is_integer(const bool print_non_integer)
{
  assert( iaSolution );
  
  int num_non_int = 0;
  class NonInt
  {
  public:
    double x;
    int i;
    double dist () const
    {
      double xm = fabs( x - floor(x));
      double xp = fabs( floor(x) + 1. - x);
      // printf("dist: x %f floor %f xm %f xp %f\n", x, floor(x), xm, xp); // debug
      if (xm > xp)
        return xp;
      else
        return xm;
    }
    NonInt() : x(0.), i(-1) {}
    NonInt(const double x_val, const unsigned int i_val) : x(x_val), i( (int) i_val ) {}
  };
  
  NonInt worst_non_int;
  
  bool all_int = true;  
  for (unsigned int i = 0; i<iaSolution->x_solution.size(); ++i)
  {
    const double x = iaSolution->x_solution[i];
    if (!is_integer(x))
    {
      all_int = false;
      if (print_non_integer)
      {
        NonInt xnon(x,i);
        if (xnon.dist() > worst_non_int.dist())
          worst_non_int = xnon;
        if (num_non_int++ == 0)
        {
          printf("\nChecking solution integrality\n");
        }
        const double goal = iaData->I[i];
        printf(" x %d (g %f) is %f NON-INTEGER\n", i, goal, x);<--- %d in format string (no. 1) requires 'int' but the argument type is 'unsigned int'.
      }
      // shortcut return if we're not printing anything
      else
        return false; 
    }
  }
  if (print_non_integer)
  {
    if (num_non_int == 0)
    {
      printf("all integer\n");
    }
    else
    {
      printf("%d of %lu NON-INTEGERS\n", num_non_int, iaSolution->x_solution.size());
      printf("worst was x_%d = %g\n", worst_non_int.i, worst_non_int.x );
    }
  }
  return all_int;
}


void IASolverToolInt::get_frac( double x, int &integer, double &frac) const
{
  assert(x>=0.);
  integer = floor(x); 
  frac = x - integer;
  assert( frac < 1. );
  assert( frac >= 0. );
}

double IASolverToolInt::get_xl( int i ) const
{
  return floor( ipData->relaxedSolution[i] );
}

double IASolverToolInt::get_xh( int i ) const
{
  return floor( ipData->relaxedSolution[i] )+1;
}

double IASolverToolInt::get_km( int i, double x ) const
{
  const double y =  get_xl(i) - x;
  return y>0. ? y : 0.;
}

void IASolverToolInt::get_km( int i, double x, int &km_integer, double &km_frac ) const
{
  get_frac( get_km(i,x), km_integer, km_frac);
}

double IASolverToolInt::get_kp( int i, double x ) const
{
  const double y = x - get_xh(i);
  return y > 0 ? y : 0.;
}

void IASolverToolInt::get_kp( int i, double x, int &kp_integer, double &kp_frac ) const
{
  get_frac( get_kp(i,x), kp_integer, kp_frac);
}
  
  
  
bool IASolverToolInt::randomize_weights_of_non_int(IAWeights* weights, const double rand_factor)
{
    
  for (size_t i=0; i<iaSolution->x_solution.size(); ++i) 
  {
    const double x = iaSolution->x_solution[i];
    if (!is_integer(x))
    {
      const double d = IAWeights::rand_excluded_middle();
      (*weights)[i] *= 1. + rand_factor * d;
    }
  }
  return true;
}

} // namespace MeshKit