Ottimizzazione degli algoritmi. - pagina 2

 

E così:

//————————————————————————————————————————————————————————————————
int Selection()
{
  int    u=0;
  double p=RNDfromCI(Population[0][0]-Population[0][SizeOfPop-1]);

   for(u=0;u<SizeOfPop;u++)   if(Population[0][u+1]<=p)  break;
  
  return(u);
}
//————————————————————————————————————————————————————————————————

?

 

L'ho accelerato di un fattore e mezzo.

// Рулетка.
int Roulette(double &array[], int SizeOfPop)
{
  double p, sum=0, zero = array[SizeOfPop-1] - 1.;
  for(int i=0; i<SizeOfPop; i++)
  {
    select[i] = sum += array[i] - zero;
  }
  // бросим "шарик"
  p=RNDfromCI(0,sum);
  // посмотрим, на какой сектор упал "шарик"
  for(int u=0;u<SizeOfPop;u++)   if(select[u]>=p)  return(u);
  return -1;    
}

Lo zero (nel tuo caso "coefficiente") è scelto altrettanto stupidamente (quasi "di punto in bianco").

// Come utente potenziale, ti suggerisco di riflettere ancora attentamente su questo punto.

// Ho dei pensieri ragionevoli sull'argomento, possiamo discuterne a nostro piacimento.

Se metti 1,1 invece di 1 quando calcoli lo zero, i risultati (numerici, non di velocità) saranno esattamente gli stessi del tuo caso.

2012.04.05 02:30:17     mdRoulette (GBOTUSDMUR16Apr2012,M1)     ----------------
2012.04.05 02:30:17     mdRoulette (GBOTUSDMUR16Apr2012,M1)     h0 = 38621212;  38.621212
2012.04.05 02:30:17     mdRoulette (GBOTUSDMUR16Apr2012,M1)     h1 = 31685827;  31.685827
2012.04.05 02:30:17     mdRoulette (GBOTUSDMUR16Apr2012,M1)     h2 = 17770070;  17.77007
2012.04.05 02:30:17     mdRoulette (GBOTUSDMUR16Apr2012,M1)     h3 = 7335400;  7.3354
2012.04.05 02:30:17     mdRoulette (GBOTUSDMUR16Apr2012,M1)     h4 = 4203603;  4.203603
2012.04.05 02:30:17     mdRoulette (GBOTUSDMUR16Apr2012,M1)     h5 = 383888;  0.383888
2012.04.05 02:30:17     mdRoulette (GBOTUSDMUR16Apr2012,M1)     10374 мс - Время исполнения
2012.04.05 02:30:00     Roulette (GBOTUSDMUR16Apr2012,M1)       ----------------
2012.04.05 02:30:00     Roulette (GBOTUSDMUR16Apr2012,M1)       h0 38635063 38.635063
2012.04.05 02:30:00     Roulette (GBOTUSDMUR16Apr2012,M1)       h1 31678144 31.678144
2012.04.05 02:30:00     Roulette (GBOTUSDMUR16Apr2012,M1)       h2 17759576 17.759576
2012.04.05 02:30:00     Roulette (GBOTUSDMUR16Apr2012,M1)       h3 7333799 7.333799
2012.04.05 02:30:00     Roulette (GBOTUSDMUR16Apr2012,M1)       h4 4208364 4.208364
2012.04.05 02:30:00     Roulette (GBOTUSDMUR16Apr2012,M1)       h5 385054 0.385054
2012.04.05 02:30:00     Roulette (GBOTUSDMUR16Apr2012,M1)       16036 мс - Время исполнения
2012.04.05 02:29:24     Roulette (GBOTUSDMUR16Apr2012,M1)       ----------------
File:
 

Una tale domanda https://www.mql5.com/ru/forum/6343/page5#comment_177533 è appropriata in questo thread?

 
MetaDriver:

1. Accelerato di un fattore uno e mezzo.

2. hanno pensieri ragionevoli sull'argomento, possono essere discussi con calma.

1. buona soluzione, grazie. Il succo è lo stesso del mio, ma tu hai fatto con un solo array di marcatura invece di due - da qui il guadagno di velocità. Sembra che non si possa fare di meglio.

A meno che non si tolga il markup dal ciclo:

for(int i=0; i<SizeOfPop; i++)
  {
    select[i] = sum += array[i] - zero;
  }

:)

2. Certo.

 
Yedelkin:

Una tale domanda https://www.mql5.com/ru/forum/6343/page5#comment_177533 è appropriata in questo thread?

Sì, queste sono domande algoritmiche. Comunque, quel thread ha già risposto.
 

E così...

void Test(){
   double SectorSize[]={22,3,2,1,7,12};
   
   double tc[];
   ArrayResize(tc,ArraySize(SectorSize));
   for(int i=0;i<100000;i++){
      tc[Roulete(SectorSize)]++;
   }
   int m=tc[ArrayMinimum(tc)];
   string str="";
      for(i=0;i<ArraySize(SectorSize);i++){
         tc[i]/=m;
         str=str+DoubleToStr(tc[i],2)+" ";
      }      
   Alert(str);
}

int Roulete(double & SectorSize[]){ // На входе размеры секторов
   double Sum=0;
   int i;
   for(i=ArraySize(SectorSize);i>=0;i--){
      Sum+=SectorSize[i];
   }
   for(i=ArraySize(SectorSize);i>0;i--){
      if(MathRand()<SectorSize[i]/Sum*32767){
         return(i);
      }
      Sum-=SectorSize[i];
   }
   return(i);   
   
}

L'input è un array con le dimensioni dei settori( non è richiesto alcunordinamento dell'array ).

Non capisco perché hai un numero negativo nell'array. Probabilmente il partizionamento dei settori?

 
joo:

Buona soluzione, grazie. L'idea è la stessa della mia, ma ti sei accontentato di una sola matrice di marcatura invece di due - da qui il guadagno di velocità. Sembra che non si possa fare di meglio.

Il guadagno è stato ottenuto con molti piccoli miglioramenti. Si può anche accelerare un po' di più le "piccole cose".

Per esempio, se si riduce il secondo parametro di uno prima quando si chiama la roulette:

int Roulette(double &array[], int MaxIndex)
{
  double p, sum=0, zero = array[MaxIndex] - 1.1;
  for(int i=0; i!=MaxIndex; i++)
  {
    select[i] = sum += array[i] - zero;
  }
  // бросим "шарик"
  p=RNDfromCI(0,sum);
  // посмотрим, на какой сектор упал "шарик"
  for(int u=0;u!=MaxIndex;u++) 
  {  if(select[u]>=p)  return(u);}
  return -1;    
}

si ottiene comunque una differenza abbastanza misurabile.

2012.04.05 18:35:31     mdQuikRoulette (USDCHF,M1)      ----------------
2012.04.05 18:35:31     mdQuikRoulette (USDCHF,M1)      h0 = 38784632;  38.784632
2012.04.05 18:35:31     mdQuikRoulette (USDCHF,M1)      h1 = 31791177;  31.791177
2012.04.05 18:35:31     mdQuikRoulette (USDCHF,M1)      h2 = 17835360;  17.83536
2012.04.05 18:35:31     mdQuikRoulette (USDCHF,M1)      h3 = 7365937;  7.365937
2012.04.05 18:35:31     mdQuikRoulette (USDCHF,M1)      h4 = 4222894;  4.222894
2012.04.05 18:35:31     mdQuikRoulette (USDCHF,M1)      h5 = 0;  0.0
2012.04.05 18:35:31     mdQuikRoulette (USDCHF,M1)      9828 мс - Время исполнения
2012.04.05 18:33:30     mdRoulette (USDCHF,M1)  ----------------
2012.04.05 18:33:30     mdRoulette (USDCHF,M1)  h0 = 38627427;  38.627427
2012.04.05 18:33:30     mdRoulette (USDCHF,M1)  h1 = 31682853;  31.682853
2012.04.05 18:33:30     mdRoulette (USDCHF,M1)  h2 = 17763763;  17.763763
2012.04.05 18:33:30     mdRoulette (USDCHF,M1)  h3 = 7334465;  7.334465
2012.04.05 18:33:30     mdRoulette (USDCHF,M1)  h4 = 4206490;  4.20649
2012.04.05 18:33:30     mdRoulette (USDCHF,M1)  h5 = 385002;  0.385002
2012.04.05 18:33:30     mdRoulette (USDCHF,M1)  10359 мс - Время исполнения

Ma non è tutto. La vera "grande vittoria" è davanti a noi. Aspetta, la metto a punto e la pubblico.

// c'è un piccolo bug - già risolto.

 
Integer:

E così...

1. viene inserito un array con le dimensioni dei settori( non è richiesto alcunordinamento dell'array ).

2. Perché hai un numero negativo nell'array - non lo capisco. Probabilmente il partizionamento dei settori?

1. il problema è che l'input è costituito da dati grezzi. Hanno solo bisogno di essere convertiti in dimensioni di settore man mano che il gioco va avanti. Questo è parte del problema. :)

2. Assolutamente no. Basta torturare joo, lo ammetterà se lo spingi abbastanza forte. Ora sto facendo il debugging. ;)

 
E questa è una vera Quik-roulette ad alta velocità.
// Рулетка.
int Roulette(double &array[], int r)
{
  double p, sum=0, zero = array[r++] - 1.1;
  for(int i=0; i!=r; i++)
  {
    select[i] = sum += array[i] - zero;
  }
  p=RNDfromCI(0,sum);
  int l=0, m=(l+(--r))>>1;
  while(l<r) 
    {
     if(select[m]>=p) r=m;
     else l=m+1; 
     m=(l+r)>>1;
    }
  return m;    
}
2012.04.05 19:58:24     mdQuikRoulette (USDCHF,M1)      ----------------
2012.04.05 19:58:24     mdQuikRoulette (USDCHF,M1)      h0 = 38632491;  38.632491
2012.04.05 19:58:24     mdQuikRoulette (USDCHF,M1)      h1 = 31675215;  31.675215
2012.04.05 19:58:24     mdQuikRoulette (USDCHF,M1)      h2 = 17769223;  17.769223
2012.04.05 19:58:24     mdQuikRoulette (USDCHF,M1)      h3 = 7337466;  7.337466
2012.04.05 19:58:24     mdQuikRoulette (USDCHF,M1)      h4 = 4202088;  4.202088
2012.04.05 19:58:24     mdQuikRoulette (USDCHF,M1)      h5 = 383517;  0.383517
2012.04.05 19:58:24     mdQuikRoulette (USDCHF,M1)      11529 мс - Время исполнения
2012.04.05 19:57:06     mdQuikRoulette (USDCHF,M1)      ----------------
Non siete rimasti impressionati dal risultato?

Questo è ingenuo. ;) Aumentare l'array di input di 10.000 volte - allora sarete sicuramente impressionati.

--

Sto aspettando test comparativi // su array di grandi dimensioni.

;)

File:
 
MetaDriver:

Sto aspettando dei test comparativi // su un grande array.

Non riesco ad aspettare... :)

Dovrò farlo di nuovo io stesso:

2012.04.05 22:04:25     mdQuikRoulette_CompareTest (USDCHF,M1)  h0 = 2105;  0.02105
2012.04.05 22:04:25     mdQuikRoulette_CompareTest (USDCHF,M1)  h1 = 1782;  0.01782
2012.04.05 22:04:25     mdQuikRoulette_CompareTest (USDCHF,M1)  h2 = 2189;  0.02189
2012.04.05 22:04:25     mdQuikRoulette_CompareTest (USDCHF,M1)  h3 = 1793;  0.01793
2012.04.05 22:04:25     mdQuikRoulette_CompareTest (USDCHF,M1)  h4 = 1803;  0.01803
2012.04.05 22:04:25     mdQuikRoulette_CompareTest (USDCHF,M1)  h5 = 2075;  0.02075
2012.04.05 22:04:25     mdQuikRoulette_CompareTest (USDCHF,M1)  1825 мс - Время исполнения QuickRoulette
2012.04.05 22:04:23     mdQuikRoulette_CompareTest (USDCHF,M1)  h0 = 2104;  0.02104
2012.04.05 22:04:23     mdQuikRoulette_CompareTest (USDCHF,M1)  h1 = 1812;  0.01812
2012.04.05 22:04:23     mdQuikRoulette_CompareTest (USDCHF,M1)  h2 = 2088;  0.02088
2012.04.05 22:04:23     mdQuikRoulette_CompareTest (USDCHF,M1)  h3 = 1839;  0.01839
2012.04.05 22:04:23     mdQuikRoulette_CompareTest (USDCHF,M1)  h4 = 1769;  0.01769
2012.04.05 22:04:23     mdQuikRoulette_CompareTest (USDCHF,M1)  h5 = 2089;  0.02089
2012.04.05 22:04:23     mdQuikRoulette_CompareTest (USDCHF,M1)  183207 мс - Время исполнения Roulette


Allo stesso tempo ho pettinato tutto nella classe e messo in CRoulette.Reset();