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

私はあなたのクラッシュの実際の原因を知りませんが、あなたがトラブルに巻き込まれることに本当に驚かない. たとえば、これらの「キャッシュされた」静的変数Rand_NormalDistriは明らかにデータ競合に対して脆弱です。なぜあなたは使わないのですstd::normal_distributionか?ほとんどの場合、標準ライブラリ ルーチンが利用可能な場合はそれを使用することをお勧めします。

さらに悪いことに、C と C++ を大量に混在させています。malloc実質的に C++ コードで使用してはならないものです。RAII については認識していません。RAII は、C++ で固執できる数少ない本質的に安全なものの 1 つです。

于 2013-05-26T00:50:36.190 に答える
2

leftaroundabout が指摘したように、C++ コードで malloc を使用しています。これがクラッシュの原因です。

Malloc はメモリのブロックを割り当てますが、実際には C 用に設計されているため、C++ コンストラクターを呼び出しません。この場合、 vector<double> は適切に構築されません。いつ

arg1->Solution1 = SearchSpace;

が呼び出されると、メンバー変数「Solution1」が未定義の状態になり、代入演算子がクラッシュします。

malloc try の代わりに

arg1 = new t;

これはほぼ同じことを達成しますが、「new」キーワードは必要なコンストラクターも呼び出して、 vector<double> が適切に初期化されるようにします。

これにより、新しいメモリもどこかで削除する必要があるという別の小さな問題が発生します。この場合、arg1 は別のスレッドに渡されるため、おそらく次のようにクリーンアップする必要があります。

delete args;

args 変数を使用した後、「SA」関数によって。

于 2013-05-26T01:15:04.077 に答える