模拟退火:为什么给我运行最大值?

时间:2013-11-14 18:32:20

标签: c++ simulated-annealing

我创建一个矩阵,我生成0和1的随机数。这个矩阵表示以位为单位生成的数字。在此之后,我将这些位转换为实数,并将其加载到向量中。我使用模拟退火算法对Griewangk函数进行确定函数的最小值。但是当我将较小的解决方案保存到矢量函数中时,一些解决方案更大。我不明白为什么。代码有什么问题?

#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <time.h>

using namespace std;

int counter = 1, mat[10000][10000], world = 1, iBit = 0, jBit = 0;
float vect[10000];
int q = 2;

int getRandom()
{
    return rand() % 2;
}

void nr_random( float a, float b, int n )//generate the matrix of number of bits
{
    int i, j, x, decimal = 0;
    int k = 2;
    float nrBiti, auxiliar;

nrBiti = ( b - a ) * pow ( 10, q );
auxiliar = log(nrBiti);
auxiliar += 1;
counter = (int)auxiliar;
//cout << endl << "Numar biti:" << (int)auxiliar << endl;

for ( i = 0; i < n; i++ )
    for ( j = 0; j < counter; j ++ )
    {
        mat[i][j] = getRandom();
    }

/*for ( i = 0 ; i < n; i ++ )
{
    for ( j = 0; j < counter; j++ )
    {
        cout << mat[i][j] << " ";
    }
    cout << endl;
}*/
}

void vector(int a, int b, int n)//make a vector with float numbers who are extract         from the matrix with bits
{
    int i, j, decimal = 0, vectCount = 0, k = pow(2,counter);
    //cout << "Numerele in decimal:";
    for ( i = 0 ; i < n; i ++ )
{
    for ( j = 0; j < counter; j++ )
    {
        decimal += k/2 * mat[i][j];
        k = k/2;
    }
    k = pow(2, counter);
    //cout << decimal << " " ;
    vect[vectCount] = a + decimal * ( b-a ) / ( pow(2,counter) - 1 );
    vectCount++;
    decimal = 0;
}

/*cout << endl;
cout << "Numerele reale: ";
for ( i = 0; i < vectCount; i++ )
{
    cout << vect[i] << " ";
}
cout << endl;*/
}

void changeBit(int n)//change a bit of random in the matrix of bits
{
    int i = 0, j;
    if ( n > 1 )
        i = rand() % (n);


j = rand() % counter;
iBit = i; jBit = j;
//cout << world << ")Pozitia de pe care se schimba bitul:" << i << " " << j << endl;
world++;

if ( mat[i][j] == 0 )
{
    mat[i][j] = 1;
}
else
{
    mat[i][j] = 0;
}

i = 0, j = 0;

/*cout << endl;
for ( i = 0; i < n; i++ )
{
    for ( j = 0; j < counter; j++ )
    {
        cout << mat[i][j] << " ";
    }
    cout << endl;
}*/

}

float grie( int n )//griewangk's function
{
int i;
    float s = 0, p = 1;

for ( i = 0; i < n; i++ )
{
    s += vect[i] * vect[i] / 4000;
}

//cout << "Suma:" << s <<endl;

for ( i = 0; i < n; i++ )
{
    p = p * cos(vect[i]/sqrt(i+1));
}

//cout << "Produs:" << p << endl;

s = s - p + 1;
//cout << "Return:" << s << endl;
return s;
}

float coolRate(float a)
{
return a - 0.9;
}


int _tmain(int argc, _TCHAR* argv[])
{
int n,fCount = 0,i;
float best, take, T = 100, aux, count = 0, functie[10000];
srand(time(NULL));
long t = 0;
cout << "Dati dimensiunea = ";
cin >> n;
cout << endl;

nr_random(-600,600, n);
vector(-600, 600, n );
best = grie(n);

//Simulated Annealing algorithm
do{
    do{
        changeBit(n);
        vector(-600, 600, n );
        take = grie(n);

        if ( take < best )
        {
            best = take;
            functie[fCount] = best;
            fCount++;
        }
        else
        {
            aux = best - take;
            if ( aux > 0 )
                aux = -aux;

            if ( (( rand() % 1000 ) / 1000) <  pow(2.71,aux/T) )
            {
                best = take;
                //functie[fCount] = best;
                //fCount++;
            }
            else// refact punctul initial
            {
                if ( mat[iBit][jBit] == 0 )
                    mat[iBit][jBit] = 1;
                else
                    mat[iBit][jBit] = 0;
            }
        }
        count++;
    }while ( count < 5);
    count=0;
    T = coolRate(T);
    t++;
//}while( t < 50 );
}while( t < 5);
//cout << T << endl;

for ( i = 0; i < fCount; i++ )
{
    cout << "F[" << i << "]=" << functie[i] << endl;
    /*if( best > functie[i])
        best = functie[i];*/

}

cout << endl << "Best = " << best << endl;

return 0;
}

0 个答案:

没有答案