0

我写了一个多线程模拟退火程序,但它没有运行。我不确定代码是否正确。代码能够编译,但是当我运行代码时它崩溃了。它只是一个运行时错误。

#include <stdio.h> 
#include <time.h>
#include <iostream>
#include <stdlib.h>
#include <math.h>
#include <string>
#include <vector>
#include <algorithm>
#include <fstream>
#include <ctime>
#include <windows.h>
#include <process.h> 

using namespace std;



typedef vector<double> Layer; //defines a vector type

typedef struct {
   Layer Solution1;
   double temp1;
   double coolingrate1;
   int MCL1;
   int prob1;
}t; 
//void SA(Layer Solution, double temp, double coolingrate, int MCL, int prob){


double  Rand_NormalDistri(double mean, double stddev) {
 //Random Number from Normal Distribution

    static double n2 = 0.0;
    static int n2_cached = 0;
    if (!n2_cached) {
       // choose a point x,y in the unit circle uniformly at random
     double x, y, r;
     do {
  //  scale two random integers to doubles between -1 and 1
   x = 2.0*rand()/RAND_MAX - 1;
   y = 2.0*rand()/RAND_MAX - 1;

    r = x*x + y*y;
   } while (r == 0.0 || r > 1.0);

        {
       // Apply Box-Muller transform on x, y
        double d = sqrt(-2.0*log(r)/r);
      double n1 = x*d;
      n2 = y*d;

       // scale and translate to get desired mean and standard deviation

      double result = n1*stddev + mean;

        n2_cached = 1;
        return result;
        }
    } else {
        n2_cached = 0;
        return n2*stddev + mean;
    }
}



double   FitnessFunc(Layer x, int ProbNum)
{


    int i,j,k;
    double z; 
  double fit = 0;  
  double   sumSCH; 

 if(ProbNum==1){
  // Ellipsoidal function
  for(j=0;j< x.size();j++)
    fit+=((j+1)*(x[j]*x[j]));
}

 else if(ProbNum==2){
  // Schwefel's function
  for(j=0; j< x.size(); j++)
    {
      sumSCH=0;

      for(i=0; i<j; i++)
    sumSCH += x[i];
      fit += sumSCH * sumSCH;
    }
}

 else if(ProbNum==3){
  // Rosenbrock's function

  for(j=0; j< x.size()-1; j++)
    fit += 100.0*(x[j]*x[j] - x[j+1])*(x[j]*x[j] - x[j+1]) + (x[j]-1.0)*(x[j]-1.0);
}
  return fit;
}

double probl(double energychange, double temp){
    double a;
    a= (-energychange)/temp;
    return double(min(1.0,exp(a)));
}

int random (int min, int max){
    int n = max - min + 1;
    int remainder = RAND_MAX % n;
    int x;
    do{
        x = rand();
    }while (x >= RAND_MAX - remainder);
    return min + x % n;
}

//void SA(Layer Solution, double temp, double coolingrate, int MCL, int prob){
void SA(void *param){

    t *args = (t*) param;

    Layer Solution = args->Solution1;
    double temp = args->temp1;
    double coolingrate = args->coolingrate1;
    int MCL = args->MCL1;
    int prob = args->prob1;

    double Energy;
    double EnergyNew;
    double EnergyChange;
    Layer SolutionNew(50);

    Energy = FitnessFunc(Solution, prob);

    while (temp > 0.01){

        for ( int i = 0; i < MCL; i++){
            for (int j = 0 ; j < SolutionNew.size(); j++){

                SolutionNew[j] = Rand_NormalDistri(5, 1);
            }
            EnergyNew = FitnessFunc(SolutionNew, prob);
            EnergyChange = EnergyNew - Energy;

            if(EnergyChange <= 0){
                Solution = SolutionNew;
                 Energy = EnergyNew;    
            }
            if(probl(EnergyChange ,temp ) >  random(0,1)){
                //cout<<SolutionNew[i]<<endl;
                Solution = SolutionNew;
                 Energy = EnergyNew;
                cout << temp << "=" << Energy << endl;
            }
        }
        temp = temp * coolingrate;
    }

}




int main ()
{ 

 srand ( time(NULL) ); //seed for getting different numbers each time the prog is run


Layer SearchSpace(50); //declare a vector of 20 dimensions

//for(int a = 0;a < 10; a++){

for (int i = 0 ; i < SearchSpace.size(); i++){

    SearchSpace[i] = Rand_NormalDistri(5, 1);
}

t *arg1;
arg1 = (t *)malloc(sizeof(t));
arg1->Solution1 = SearchSpace;
arg1->temp1 = 1000;
arg1->coolingrate1 = 0.01;
arg1->MCL1 = 100;
arg1->prob1 = 3;

//cout << "Test " << ""<<endl;
_beginthread( SA, 0, (void*) arg1);
Sleep( 100 );

//SA(SearchSpace, 1000, 0.01, 100, 3);
//}

  return 0;
}

请帮忙。

谢谢阿维内什

4

2 回答 2

2

正如leftaroundabout 所指出的,您在C++ 代码中使用了malloc。这是你崩溃的根源。

Malloc 将分配一块内存,但由于它实际上是为 C 设计的,因此它不调用任何 C++ 构造函数。在这种情况下,vector<double> 永远不会正确构造。什么时候

arg1->Solution1 = SearchSpace;

调用时,成员变量“Solution1”处于未定义状态,赋值运算符崩溃。

而不是 malloc 尝试

arg1 = new t;

这将完成大致相同的事情,但“new”关键字还调用任何必要的构造函数以确保正确初始化 vector<double>。

这也带来了另一个小问题,你更新的这个内存也需要在某个地方删除。在这种情况下,由于 arg1 被传递给另一个线程,它可能应该像清理

delete args;

完成 args 变量后,由您的“SA”函数执行。

于 2013-05-26T01:15:04.077 回答
2

虽然我不知道您崩溃的实际原因,但您最终遇到麻烦并不感到惊讶。例如,那些“缓存”的静态变量Rand_NormalDistri显然容易受到数据竞争的影响。你为什么不使用std::normal_distribution?当标准库例程可用时使用它们几乎总是一个好主意,当您需要考虑多线程技巧时更是如此。

更糟糕的是,您正在大量混合 C 和 C++。malloc是你几乎不应该在 C++ 代码中使用的东西——它不知道 RAII,这是你可以在 C++ 中坚持的少数本质安全的东西之一。

于 2013-05-26T00:50:36.190 回答