Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Оптимизация ЛКГ (Си)

64K
22 октября 2010 года
Hokan
1 / / 22.10.2010
Необходимо отоптимизировать линейный конгруэнтный генератор, в котором осуществлены 3 проверки его качества:
  • критерий Хи-квадрат
  • критерий перестановок
  • проверка мощности
В итоге получилась средненькая оптимизация всего кода, но без оптимизации критериев проверки, вопрос - можно ли как-нибудь этот код упросить и убыстрить?
А если проще, то отоптимизировать критерий перестановок:
Код:
C[dr]=x;
dr++;
if (dr>=3) // критерий того что у нас есть 3 значения
{
if(C[1]>=C[0] && C[1]<=C[2])B[0]+=1.0;
else if(C[2]>=C[0] && C[2]<=C[1])B[1]+=1.0;
else if(C[0]>=C[1] && C[0]<=C[2])B[2]+=1.0;
else if(C[2]>=C[1] && C[2]<=C[0])B[3]+=1.0;
else if(C[0]>=C[2] && C[0]<=C[1])B[4]+=1.0;
else if(C[1]>=C[2] && C[1]<=C[0])B[5]+=1.0;
dr=0;
}


Код:
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <time.h>
#define c 1
int a=22695477;
long long int m=4294967296,i,x=13,y=13,j;
int main(void)
{
int k=16,dr=0,NumK,Num,C[3];
double hi2=0,hi,A[16],B[6];
// А - распределение чисел в 1/16 m
// B - число определённых перестановок
// С - массив для набора 3 чисел и определения типа перестановки
memset(A,0,sizeof(A));
memset(B,0,sizeof(B));
Num=1000000;
NumK=Num>>4;
// генерируем 1млн. чисел на которых тестируем Хи-квадрат и перестановки
for(i=0;i<Num;i++)
{
j=x>>28;    // помещение х в определённый диапазон 1/16 m
A[j]++;
C[dr]=x;
dr++;
if (dr>=3) // критерий того что у нас есть 3 значения
{
if(C[1]>=C[0] && C[1]<=C[2])B[0]+=1.0;
else if(C[2]>=C[0] && C[2]<=C[1])B[1]+=1.0;
else if(C[0]>=C[1] && C[0]<=C[2])B[2]+=1.0;
else if(C[2]>=C[1] && C[2]<=C[0])B[3]+=1.0;
else if(C[0]>=C[2] && C[0]<=C[1])B[4]+=1.0;
else if(C[1]>=C[2] && C[1]<=C[0])B[5]+=1.0;
dr=0;
}
x=(x*a+c)%m;
}
for(j=0;j<k;) hi2+=hi=((A[j]-NumK)*(A[j++]-NumK))/NumK;
printf("HI2:\t%.4f\n",hi2);
hi2=0;
NumK=Num/18;
for(j=0;j<6;) hi2+=hi=((B[j]-NumK)*(B[j++]-NumK))/NumK;
printf("CHANGES:\t%.4f\n",hi2);
dr=0;
a--;
while (a%2==0)
{
    dr++;
    a>>=1;
}
j=32/dr+1;
printf("POWER:\t%d\n",j);
for(i;i<m-Num;i++) x=(x*a+c)%m;
/*y=x; // алтернативное вычисление Х, y = long long int
x<<=25;
x-=10858955*y;
x++;
x%=m; действует не так быстро как метод "влоб"*/
printf("Time is: %d sec\n",clock()/1000);
getc(stdin);
return 0;
}


Вопрос исчерпан, можно сносить тему
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог