c++ - 多线程模拟退火

标签 c++ multithreading simulated-annealing

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

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

请帮忙。

谢谢 阿维内什

最佳答案

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

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

arg1->Solution1 = SearchSpace;

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

尝试用 malloc 代替

arg1 = new t;

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

这也带来了另一个小问题,即您新建的这段内存也需要在某处删除。在这种情况下,由于 arg1 被传递给另一个线程,它应该像

delete args;

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

关于c++ - 多线程模拟退火,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16755173/

相关文章:

C++ - 获取整数位的大小

c++ - 将大型单 block 单线程应用程序转换为多线程体系结构的建议?

java - Android:处理同步网络通话

java - 生成具有给定概率的随机 boolean 值

c++ - 常规转换的内存损坏?调用了错误的函数

C++17,<memory> 标准库中弃用的函数?

c - 对称多处理系统的输出

genetic-algorithm - 遗传算法与时间表的模拟退火

algorithm - 模拟退火中的概率计算和比较

c++ - 带有一个选项卡的 QTabBar 太宽