Optimierung von Algorithmen. - Seite 2

 

Und so:

//————————————————————————————————————————————————————————————————
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);
}
//————————————————————————————————————————————————————————————————

?

 

Ich habe sie um das Anderthalbfache beschleunigt.

// Рулетка.
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;    
}

Die Null (in Ihrem Fall "Koeffizient") ist ebenso dumm gewählt (fast "aus heiterem Himmel").

// Als potenzieller Nutzer sollten Sie sich diesen Punkt trotzdem gut überlegen.

// Ich habe vernünftige Gedanken zu diesem Thema, wir können sie in Ruhe diskutieren.

Wenn Sie bei der Berechnung von Null 1,1 statt 1 einsetzen, sind die Ergebnisse (numerisch, nicht in Bezug auf die Geschwindigkeit) genau dieselben wie in Ihrem Fall.

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)       ----------------
Dateien:
 

Ist eine solche Frage https://www.mql5.com/ru/forum/6343/page5#comment_177533 in diesem Thema angebracht?

 
MetaDriver:

1. Um das Eineinhalbfache beschleunigt.

2. vernünftige Gedanken zu dem Thema haben, die in Ruhe diskutiert werden können.

1. gute Lösung, danke. Die Grundidee ist dieselbe wie bei mir, aber Sie haben mit einem Markierungsfeld anstelle von zwei gearbeitet - daher der Geschwindigkeitsgewinn. Sieht aus, als könnten Sie es nicht besser machen.

Es sei denn, Sie nehmen den Aufschlag aus der Schleife heraus:

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

:)

2. Ja, sicher.

 
Yedelkin:

Ist eine solche Frage https://www.mql5.com/ru/forum/6343/page5#comment_177533 in diesem Thema angebracht?

Ja, dies sind algorithmische Fragen. In diesem Thread wurde diese Frage jedoch bereits beantwortet.
 

Und so...

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);   
   
}

Die Eingabe ist ein Array mit Sektorgrößen(eine Sortierung des Arrays ist nicht erforderlich).

Ich verstehe nicht, warum Sie dort eine negative Zahl in der Matrix haben. Wahrscheinlich Sektorpartitionierung?

 
joo:

Gute Lösung, danke. Die Idee ist die gleiche wie meine, aber Sie haben sich mit einem Markierungsfeld statt zwei begnügt - daher der Geschwindigkeitsgewinn. Sieht aus, als könnten Sie es nicht besser machen.

Der Gewinn wurde durch viele kleine Verbesserungen erzielt, und man kann auch etwas mehr "Kleinigkeiten" beschleunigen.

Zum Beispiel, wenn Sie den zweiten Parameter beim Aufruf des Roulettes vorher um eins reduzieren:

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;    
}

erhalten Sie dennoch einen deutlich messbaren Unterschied.

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 мс - Время исполнения

Aber das ist noch nicht alles. Der eigentliche "große Gewinn" steht noch bevor. Warten Sie, ich werde es debuggen und veröffentlichen.

// hier ist ein kleiner Fehler - bereits behoben.

 
Integer:

Und so...

1. Ein Array mit Sektorgrößen wird eingegeben(eine Sortierung des Arrays ist nicht erforderlich).

2. warum Sie eine negative Zahl in dem Feld haben - ich verstehe es nicht. Wahrscheinlich Sektorpartitionierung?

1. Das Problem ist, dass es sich bei der Eingabe um Rohdaten handelt. Sie müssen nur im Laufe des Spiels in Sektorgrößen umgerechnet werden. Das ist ein Teil des Problems. :)

2. auf keinen Fall. Foltern Sie Joo einfach, er wird es zugeben, wenn Sie ihn stark genug drängen. Ich debugge jetzt. ;)

 
Und dies ist ein echtes Hochgeschwindigkeits-Quik-Roulette.
// Рулетка.
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)      ----------------
Sie waren von dem Ergebnis nicht beeindruckt?

Das ist naiv. ;) Vergrößern Sie das Eingabefeld um das 10.000-fache - dann werden Sie sicher beeindruckt sein.

--

Ich warte auf vergleichende Tests // mit einem großen Array.

;)

Dateien:
 
MetaDriver:

Ich warte auf vergleichende Tests // mit einem großen Array.

Ich kann es kaum erwarten... :)

Ich muss es wieder selbst tun:

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


Zur gleichen Zeit habe ich es alle in der Klasse gekämmt und in CRoulette.Reset() setzen;