代码之家  ›  专栏  ›  技术社区  ›  Student. Engineering

如何解决C语言中的应用程序响应问题#

  •  -2
  • Student. Engineering  · 技术社区  · 7 年前

    我正在尝试用c语言实现一个遗传算法。遗传有交叉法和变异法。群体大小为5条染色体,其中每条染色体是一个二维整数数组(矩阵10x10)。遗传应循环50次,并按如下方式调用交叉和突变每个循环:

      DateTime startTiming = DateTime.Now;
    
            TimeSpan startGenetic;
    
    
            // Make a population for each layer - as we have 4 layers, thus 4 population arrays after the intial eavaluation for the intial population and have differernt values in the aterations > 1 
            static List<int[,]> populationLayer1 = new List<int[,]>();
            static List<int[,]> populationLayer2 = new List<int[,]>();
            static List<int[,]> populationLayer3 = new List<int[,]>();
            static List<int[,]> populationLayer4 = new List<int[,]>();
    
            // 4 layers - we need 4 arrays 
            double[,] FitnessValLayer1 = new double[5, 2]; // for all "5" chromosome we store "2" Values : (Fitness Value - Fitness Ratio) in each layer (as we have 4 layers)
            double[,] FitnessValLayer2 = new double[5, 2]; // for all "5" chromosome we store "2" Values : (Fitness Value - Fitness Ratio) in each layer (as we have 4 layers)
            double[,] FitnessValLayer3 = new double[5, 2]; // for all "5" chromosome we store "2" Values : (Fitness Value - Fitness Ratio) in each layer (as we have 4 layers)
            double[,] FitnessValLayer4 = new double[5, 2]; // for all "5" chromosome we store "2" Values : (Fitness Value - Fitness Ratio) in each layer (as we have 4 layers)
    
            // 4 RouletteWeel values because of the 4 layers
            int[] RouletteWheelLayer1 = new int[10];
            int[] RouletteWheelLayer2 = new int[10];
            int[] RouletteWheelLayer3 = new int[10];
            int[] RouletteWheelLayer4 = new int[10];
    
            public async Task Genetic_Algorithm(List<int[,]> population)
    
            {
    
                cancelSource = new CancellationTokenSource();
    
                //In this step just duplicate the initial population 
                populationLayer1 = population.ToList();
                populationLayer2 = population.ToList();
                populationLayer3 = population.ToList();
                populationLayer4 = population.ToList();
    
                int round = 0;
    
    
    
                for (geneticIteration = 0; geneticIteration < minIteration; geneticIteration++)
                {
    
    
                    round = geneticIteration;
    
                    //----------------------//
                    //Calculate Fitness 
                    try
                    {
                        // Calculate the fitness Function and the Fitness Ratio
                        await FitnessFunctionAsync(populationLayer1, populationLayer2, populationLayer3, populationLayer4, cancelSource.Token); // Fitness Function
                    }
    
                    catch (Exception ex)
                    {
    
                        // Write output to the file.
                        Trace.Write("when calling (FitnessFunctionAsync)..." + ex.Message);
                        Trace.Flush();
    
                    }
    
                    //----------------------//
                    // To Do : 
                    //get 4 arrays for the fitness for each layer 
    
    
                    //----------------------//
                    // Note : Each layer has different values for fitness so the changes on the population will not be the same in the 4 layers 
                    //---------------------//
    
                        //RouletteWeel 
                        RouletteWheelLayer1 = RouletteWheel_Selection(FitnessValLayer1);
                        RouletteWheelLayer2 = RouletteWheel_Selection(FitnessValLayer2);
                        RouletteWheelLayer3 = RouletteWheel_Selection(FitnessValLayer3);
                        RouletteWheelLayer4 = RouletteWheel_Selection(FitnessValLayer4);
    
    
                        //Crossover 
                       // populationLayer1 = CrosssOver(RouletteWheelLayer1, populationLayer1);
                        //populationLayer2 = CrosssOver(RouletteWheelLayer2, populationLayer2);
                       // populationLayer3 = CrosssOver(RouletteWheelLayer3, populationLayer3);
                        //populationLayer4 = CrosssOver(RouletteWheelLayer4, populationLayer4);
    
                        //Mutation 
                        //populationLayer1 = Mutation(RouletteWheelLayer1, populationLayer1);
                       // populationLayer2 = Mutation(RouletteWheelLayer2, populationLayer2);
                       // populationLayer3 = Mutation(RouletteWheelLayer3, populationLayer3);
                        //populationLayer4 = Mutation(RouletteWheelLayer4, populationLayer4);
    
    
                        // 4 layers - re-intialize  
                         FitnessValLayer1 = new double[5, 2]; 
                         FitnessValLayer2 = new double[5, 2]; 
                         FitnessValLayer3 = new double[5, 2]; 
                         FitnessValLayer4 = new double[5, 2]; 
    
                        // 4 RouletteWeel - re-intialize 
                         RouletteWheelLayer1 = new int[10];
                         RouletteWheelLayer2 = new int[10];
                         RouletteWheelLayer3 = new int[10];
                         RouletteWheelLayer4 = new int[10];
    
    
                }
    
    
                InvokeUpdateControls();
    
    
            }
    

    不幸的是,当实现交叉或变异时,即当概率满足时,我的应用程序没有响应。以下是两种方法:

    public List<int[,]> CrosssOver(int[] RouletteWheel, List<int[,]> population)
            {
    
    
                double rndNumber1 = 0.0;
    
                int rndNumber2 = 0;
    
                Random rnd = new Random();
    
                int chrom1 = 0;
    
                int chrom2 = 0;
    
    
    
                for (int i = 0; i < population.Count; i++) // For all Chromosomes
                {
                    rndNumber1 = rnd.Next(0, 11) / 10.00; // generate a random number to check the probability for crossover
    
                    chrom1 = RouletteWheel[rnd.Next(0, 10)];
    
                    chrom2 = RouletteWheel[rnd.Next(0, 10)];
    
                    if (rndNumber1 <= Pc) /* check if we will do Crossover */
                    {
    
                        rndNumber2 = rnd.Next(0, rows - 1); // determine the crossover point randomly by generating number between 0 and rows-1
    
    
                        for (int j = 0; j < rows; j++)
                        {
    
    
                            for (int v = 0; v < columns; v++)
                            {
    
    
    
                                if (j == rndNumber2) /* copy from same chromosome */
                                {
    
                                    try
                                    {
                                        population[chrom1][j, v] = population[chrom2][j, v];
                                    }
    
                                    catch (Exception ex)
                                    {
                                        // Write output to the file.
                                        Trace.Write("crossover..." + ex.Message);
                                        Trace.Flush();
                                        return population;
    
                                    }
    
                                }
    
    
                            }
    
                        }
    
                    }
    
                }
    
    
    
                return population;
    
            } // end-cross-over
    

    突变方法:

     public List<int[,]> Mutation(int[] RouletteWheel, List<int[,]> population)
            {
    
                double rndNumber1 = 0.0;
    
                int chrom1 = 0;
    
                int rndNumber2 = 0;
    
                Random rnd = new Random();
    
    
                for (int i = 0; i < population.Count; i++) // For all Chromosomes
                {
                    rndNumber1 = rnd.Next(0, 11) / 100.00; // generate a random number between 0 and 10 and divide result by 100
    
                    chrom1 = RouletteWheel[rnd.Next(0, 10)];
    
                    if (rndNumber1 <= Pm) /* check if we will do Crossover */
                    {
    
                        rndNumber2 = rnd.Next(0, rows); // determine the crossover point randomly by generating number between 0 and rows -1 
    
    
                        for (int j = 0; j < rows; j++)
                        {
    
    
                            for (int v = 0; v < columns; v++)
                            {
    
    
    
                                if (j == rndNumber2) /* Mutate the cell that is equal to 1 */
                                {
                                    try
                                    {
                                        if (population[chrom1][j, v] == 0)
                                        {
                                            population[chrom1][j, v] = 1;
                                        }
    
                                    }
    
                                    catch (Exception ex)
                                    {
                                        // Write output to the file.
                                        Trace.Write("mutation..." + ex.Message);
                                        Trace.Flush();
                                        return population;
    
                                    }
    
                                }
    
    
                            }
    
                        }
    
                    }
    
                }
    
    
                return population;
    
    
            }
    

    由于这些方法,我的应用程序被卡住。。。 如果变异和交叉成功完成,我需要转到下一个迭代。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Loren Pechtel    7 年前

    不幸的是,在这样的情况下,唯一真正的答案是将有问题的代码移动到一个单独的线程中,以便主线程仍然可以用于抽取消息队列。

    确保它不会被触发两次,确保其他任何东西都不能在它运行时写入数据 非常 甚至在任何其他线程中读取任何数据(例如,显示中间结果)都要小心。