20 #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) 
   21 #include <QRandomGenerator> 
   32   return QObject::tr( 
"Natural Breaks (Jenks)" );
 
   37   return QStringLiteral( 
"Jenks" );
 
   53 QList<double> QgsClassificationJenks::calculateBreaks( 
double &minimum, 
double &maximum,
 
   54     const QList<double> &values, 
int nclasses )
 
   66   if ( values.isEmpty() )
 
   67     return QList<double>();
 
   71     return QList<double>() <<  maximum;
 
   74   if ( nclasses >= values.size() )
 
   79   QVector<double> sample;
 
   80   QVector<double> sorted;
 
   83   if ( values.size() > mMaximumSize )
 
   89     sample.resize( std::max( mMaximumSize, 
static_cast<int>( values.size() ) / 10 ) );
 
   91     QgsDebugMsgLevel( QStringLiteral( 
"natural breaks (jenks) sample size: %1" ).arg( sample.size() ), 2 );
 
   94     sample[ 0 ] = minimum;
 
   95     sample[ 1 ] = maximum;
 
   97     sorted = values.toVector();
 
   98     std::sort( sorted.begin(), sorted.end() );
 
  106     for ( 
int i = 1; i < sorted.size() - 2; i++ )
 
  108       if ( ( i * ( mMaximumSize - 2 ) / ( sorted.size() - 2 ) ) > j )
 
  111         sample[ j + 2 ] = sorted[ i ];
 
  117     sample = values.toVector();
 
  120   const int n = sample.size();
 
  123   std::sort( sample.begin(), sample.end() );
 
  125   QVector< QVector<int> > matrixOne( n + 1 );
 
  126   QVector< QVector<double> > matrixTwo( n + 1 );
 
  128   for ( 
int i = 0; i <= n; i++ )
 
  130     matrixOne[i].resize( nclasses + 1 );
 
  131     matrixTwo[i].resize( nclasses + 1 );
 
  134   for ( 
int i = 1; i <= nclasses; i++ )
 
  138     matrixTwo[0][i] = 0.0;
 
  139     for ( 
int j = 2; j <= n; j++ )
 
  141       matrixTwo[j][i] = std::numeric_limits<double>::max();
 
  145   for ( 
int l = 2; l <= n; l++ )
 
  153     for ( 
int m = 1; m <= l; m++ )
 
  155       const int i3 = l - m + 1;
 
  157       const double val = sample[ i3 - 1 ];
 
  163       v = s2 - ( s1 * s1 ) / 
static_cast< double >( w );
 
  164       const int i4 = i3 - 1;
 
  167         for ( 
int j = 2; j <= nclasses; j++ )
 
  169           if ( matrixTwo[l][j] >= v + matrixTwo[i4][j - 1] )
 
  171             matrixOne[l][j] = i4;
 
  172             matrixTwo[l][j] = v + matrixTwo[i4][j - 1];
 
  181   QVector<double> breaks( nclasses );
 
  182   breaks[nclasses - 1] = sample[n - 1];
 
  184   for ( 
int j = nclasses, k = n; j >= 2; j-- )
 
  186     const int id = matrixOne[k][j] - 1;
 
  187     breaks[j - 2] = sample[
id];
 
  188     k = matrixOne[k][j] - 1;
 
  191   return breaks.toList();