알고리즘 최적화. - 페이지 2

 

그래서:

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

?

 

절반으로 가속화됩니다.

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

0(귀하의 경우 "계수")은 어리석게 선택됩니다(거의 "불도저에서").

// 잠재 사용자로서 이 순간을 신중하게 고려하는 것이 좋습니다.

// 나는 그 주제에 대해 합리적인 생각을 가지고 있습니다. 당신은 당신의 여가 시간에 토론할 수 있습니다.

0을 계산할 때 1 대신 1.1을 넣으면 결과(속도가 아닌 숫자)가 결과와 완전히 일치합니다.

 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)       ----------------
파일:
 

https://www.mql5.com/en/forum/6343/page5#comment_177533 이 질문이 이 주제에 적합합니까?

 
MetaDriver :

1. 1.5배 가속.

2. 나는 그 주제에 대해 합리적인 생각을 가지고 있습니다. 당신은 당신의 여가 시간에 토론할 수 있습니다.

1. 좋은 결정, 감사합니다. 본질은 내 것과 동일하지만 두 개가 아닌 하나의 마킹 어레이로 관리하여 속도가 향상되었습니다. 인 것 같습니다. 당신은 아무것도하지 않는 것이 좋습니다.

음, 주기에 대한 마크업을 제거하는 것을 제외하고:

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

:)

2. 물론이다.

 
Yedelkin :

https://www.mql5.com/en/forum/6343/page5#comment_177533 이 질문이 이 주제에 적합합니까?

예, 이것은 알고리즘화의 문제입니다. 사실, 그것은 이미 그 스레드에서 답변되었습니다.
 

하지만 이렇게...

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

입력은 섹터 크기 의 배열입니다(배열 정렬 은 필요하지 않음).

배열에 음수가 있는 이유는 무엇입니까? 이해가 되지 않습니다. 아마도 섹터 표시?

 
joo :

좋은 결정입니다. 감사합니다. 본질은 내 것과 동일하지만 두 개가 아닌 하나의 마킹 어레이로 관리하여 속도가 향상되었습니다. 인 것 같습니다. 당신은 아무것도하지 않는 것이 좋습니다.

이득은 많은 작은 개선에 의해 달성됩니다. "작은 일"에 속도를 높일 수도 있습니다.

예를 들어, 룰렛 휠을 호출할 때 두 번째 매개변수를 미리 1로 줄이는 경우:

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

우리는 상당히 측정 가능한 차이를 얻습니다

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

하지만 그게 다가 아닙니다. 진정한 큰 승리가 눈앞에 있습니다. 기다려, 내가 고칠게 - 내가 그것을 게시할게.

// 여기에 작은 버그가 있습니다 - 이미 수정되었습니다.

 
Integer :

하지만 이렇게...

1. 입력은 섹터 크기 의 배열입니다(배열 정렬 은 필요하지 않음).

2. 배열에 음수가 있는 이유 - 이해하지 못했습니다. 아마도 섹터 표시?

1. 문제는 입력이 원시 데이터라는 것입니다. 그들의 플레이 경로는 아직 섹터 크기로 바뀌지 않았습니다. 이것은 작업의 kagbe 부분입니다. :)

2. 신경 쓰지마. 토먼트주, 충분히 밀어주면 고백해줄게. 그리고 디버깅하러 갔습니다. ;)

 
그러나 이것은 진정한 속사급 퀵 룰렛입니다.
 // Рулетка.
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)      ----------------
결과가 인상적이었습니까?

이것은 순진합니다. ;) 입력 배열을 10000배로 늘리십시오. 그러면 확실히 감명을 받을 것입니다.

--

비교 테스트를 기대합니다. // 큰 배열에서.

;)

파일:
 
MetaDriver :

비교 테스트를 기대합니다. // 큰 배열에서.

기다릴 수 없을 것 같습니다. :)

스스로 다시 해야 합니다.

 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


동시에 마침내 빗질을 하고 모든 것을 교실로 밀어 넣었다. 룰렛 섹터의 "설정"이 CRoulette.Reset()으로 이동되었습니다.