Halcom 发表于 2017-3-15 23:25:06

基于PSO算法的工序问题求解

一、 问题概述假设有10段工序,一共需要5个技工,每段工序持续的时间不同,技工每小时计费也不同,但技工必须呆到自己负责的工序结束了才能走。(当然,中间不需要技工参加的工序,也是要付出成本的)最终想要得到使成本最低的工序排序。
工序13579246810工人成本
技工 a** * ***20
技工 b******* 5
技工 c * * * 4
技工 d* * * * 10
技工 e * * * 4
工序时间1231111122

* 表示技工参与到的工序右列是每个工人的成本,下方是每道工序持续的时间。
二、求解目标 如上表,再此假设工序排列下,因技工要呆到需要他的工序始末,所以总成本如下推得:Ca=(1+2+3+1+1+1+1+1+2+2)*20Cb=(1+2+3+1+1+1+1)*5Cc=(1+1+1+1+1+2)*4……总成本=Ca+Cb+Cc+Cd+Ce=…                   (优化的最终目标)
例如:解(1):
工序13526749810工人成本
技工 a** * ***20
技工 b**** *** 5
技工 c * * * 4
技工 d* *** 10
技工 e *** 4
工序时间1231111122
Ca=(1+2+3+1+1+1+1+1+2+2)*20= 300Cb =(1+2+3+1+1+1+1+1) *5=55Cc =(1+1+1+1+1+2)*4=28Cd =(1+2+3+1+1)*10 = 80Ce =(1+1+2)*4 = 16总成本=Ca+Cb+Cc+Cd+Ce= 479
解(2):
工序13106985274工人成本
技工 a****** 20
技工 b** * ****5
技工 c * ** 4
技工 d* * ** 10
技工 e ** *4
工序时间1221123111
Ca=(1+2+2+1+1+2)*20= 180Cb =(1+2+2+1+1+2+3+1+1+1) *5=75Cc =(2+3+1+1)*4=28Cd =(1+2+2+1+1+2+3+1)*10 = 130Ce =(1+2+3+1+1+1)*4 = 36
总成本=Ca+Cb+Cc+Cd+Ce= 449
C语言代码如下:视频:链接:https://pan.baidu.com/s/16wFcXCHcJInK-fZyJCkW6g 密码:onaz#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#include"gx_fun.h"// 适应度函数头文件
#include"cross_gx.h"// 交叉函数头文件

/* PSO粒子群算法中的两个参数 */
#define sizepop 5000   /* 表示种群数 */
#define itermax 100   /* 进化次数 */
#define num_g 10       /* 10个工序--粒子个体数目*/
#define num_w 5      /* 5个技工 */

extern double gx ={{1,2,3,4,5,6,7,8,9,10,0},
                                                {1,0,1,0,0,1,0,1,1,1,20},
                                                {1,1,1,1,1,0,1,0,1,0,5},
                                                {0,1,0,0,0,0,1,1,0,0,4},
                                                {1,1,0,0,1,1,0,0,0,0,10},
                                                {0,0,0,1,0,0,0,1,1,0,4},
                                                {1,1,2,1,3,1,1,2,1,2,0}};
void main(void)
{
      typedef long clock_t;
      clock_t start,finish;
      double duration;
      start = clock();//启动计时
      srand((unsigned int)time(NULL));//随机种子
      srand(time(0));// 初始化随机种子
      // 变量声明
      int tabu,path,i,j,k,step,kk;// 禁忌表
      int path1,path2,zbest,gbest;
      double pd,pk,pd_s=0,rk,spk;
      double fitness,bestfitness,fitnessgbest,fitnesszbest;

      // 产生初始粒子和速度
      for(i=0;i<sizepop;i++)
      {
                for(j=0;j<num_g;j++)
                {
                        path = 1;   // 初始化
                        path2 = 1;   // 初始化
                        if(j==int(0))
                              tabu = 0; //初始化      
                        else
                              tabu = 1; //初始化
                }
               
      }

      // 随机得到path序列
      for(k=0;k<sizepop;k++)
      {
                for(step=0;step<num_g-1;step++)
                {
                        pd_s=0;
                        for(kk=0;kk<num_g;kk++)
                        {
                              pd_s = pd_s + double(tabu); // 求和
                              pd = tabu;      // 取值
                        }
                        for(kk=0;kk<num_g;kk++)
                        {
                              pk = double(pd)/double(pd_s);   // 归一化
                        }
                        rk = double(rand())/double(RAND_MAX); //0-1随机数
                        spk=0;j=0; // 初始化
                        while(j<=num_g-1)
                        {
                              if(rk < spk+pk)
                                        break;
                              else
                              {
                                        spk=spk+pk;
                                        j=j+1;
                                        if(j>num_g-1)
                                                j=num_g-1;
                              }
                        }
                        tabu = 0;       // 初始化
                        path=j+1;// 随机产生一个种群
                }
                for(i=0;i<num_g;i++){path1 = path;}

                fitness = gx_fun(path1);// 适应度值 = 计算总成本
                //printf("适应度值:%lf\n",fitness);
      }

      // 找最好的粒子种群--初始化
      bestfitness = fitness;         // 最小成本--初始化
      for(i=0;i<sizepop;i++)
      {
                for(j=0;j<num_g;j++)
                {
                        if(i==0)
                        {
                              zbest = path;   // 全局最佳--初始化
                        }
                        gbest = path;    // 个体最佳--初始化
                }
                fitnessgbest = fitness;   // 个体最佳适应度值--初始化
      }
      fitnesszbest = bestfitness;      // 全局最佳适应度值--初始化

      //while(fitnesszbest>449)//
      for(i=0;i<itermax;i++)
      {
                for(j=0;j<sizepop;j++)
                {
                        //交叉算子
                        for(k=0;k<num_g;k++)
                        {
                              path1 = path;
                              //printf("%d\t",path1 );
                        }
                        cross_gx(path1,zbest);    // 全局最优个体交叉
                        cross_gx(path1,gbest); // 个体最优交叉
                        // 适应度值更新
                        fitness = gx_fun(path1);// 适应度值 = 计算总成本
                        
                        // 个体最优更新
                        if(fitness < fitnessgbest)
                        {
                              for(k=0;k<num_g;k++)
                              {
                                        path = path1;
                                        gbest = path1;
                              }
                              fitnessgbest = fitness;
                        }
                        // 群体最优更新
                        if(fitness < fitnesszbest)
                        {
                              for(k=0;k<num_g;k++)
                              {
                                        zbest = path1;
                                        path = path1;
                              }
                                 fitnesszbest = fitness;
                        }

                }
      printf("寻优结果:\n");
      for(k=0;k<num_g;k++)
                printf("%d\t",zbest );
      printf("适应度值(总成本):%lf\n",fitnesszbest);
      printf("\n\n");// 输出显示
      }
      printf("\n\n");// 输出显示
      printf("最优适应度值(总成本):%lf\n",fitnesszbest);
      printf("\n");// 输出显示
      printf("最优工序\n");
      for(k=0;k<num_g;k++)
                printf("%d\t",zbest );
      finish = clock(); // 结束计时
      duration=(double)(finish-start)/CLOCKS_PER_SEC;
      printf("\n");// 输出显示
      printf("程序执行时间:%lf\n",duration);    // 程序执行时间输出显示
      //system("pause");    // 消除屏幕一闪即消失的情况
}

gx_fun.cpp#include<stdio.h>
#include<math.h>
/* 适应度函数 */
/*全局变量*/
#define num_g 10       /* 10个工序--粒子个体数目*/
#define num_w 5      /* 5个技工 */
extern double gx;

double gx_fun(int path)
{
      int i,j,k,flag;
      long int mapf;
      double gx1,cb=0,s;
      
      for(j=0;j<num_g;j++)
      {
                for(i=0;i<num_w+2;i++)
                {
                        gx1 = gx-1]; // 将gx数组重新排序
                }
      }

      for(i=0;i<num_w;i++) //5个技工
      {
                mapf=0;// 最小值初始化
                mapf=-100;// 最大值初始化
                for(j=0;j<num_g;j++)//10个工序
                {
                        flag=0;    // 初始化
                        s = 0;
                }
      }

      for(i=1;i<=num_w;i++) //5个技工
      {
                k=0;
                for(j=0;j<num_g;j++)//10个工序
                {
                        if(gx1==double(1.0)) // 带*为1
                        {
                              flag=j; //记录下标
                              //printf("%d \t",flag);
                              k=k+1;
                        }
                }
                //printf("\n");
      }

      // 对flag元素求最大值和最小值
      for(i=0;i<num_w;i++)
      {
                for(j=0;j<num_g;j++)
                {
                        mapf=flag;//求最小值
                        if(flag>mapf)
                              mapf=flag;//求最大值
                }
                //printf("%d,%d\t",mapf,mapf);
                //printf("\n");
      }

      for(i=0;i<num_w;i++)
      {
                for(j=0;j<num_g;j++)
                {
                        if(j>=mapf && j<=mapf)
                        {
                              s=gx1*gx;
                              //printf("%lf \t",s);
                        }
                        else
                              s=0;
                }
      }
      
      for(i=0;i<num_w;i++)
      {
                for(j=0;j<num_g;j++)
                {
                        cb = double(s) + double(cb);// 计算成本
                }
      }
      //printf("%lf\t",cb);
      return cb;

}
gx_fun.h#ifndef _GX_FUN_H_
#define _GX_FUN_H_

double gx_fun(int path[]);// 适应度函数

#endif


cross_gx.cpp#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
/* 适应度函数 */
/*全局变量*/
#define num_g 10       /* 10个工序--粒子个体数目*/
#define num_w 5      /* 5个技工 */
extern double gx;

void cross_gx(int path1,int path)
{
      int j,j1,j2,j3,j4,j5,i=0,k,mm=0;
      int pathnew,jiaocha;
      double randk;
      srand((unsigned int)time(NULL));//随机种子
      srand(time(0));// 初始化随机种子
      randk = double(rand())/double(RAND_MAX); //0-1随机数
      j1 = int(ceil(num_g*randk));
      //printf("%d\n",j1 );
      randk = double(rand())/double(RAND_MAX); //0-1随机数
      j2 = int(ceil(num_g*randk));
      //j1和j2最小值
      if(j1<=j2)
      {
                j3 = j1;
                j4 = j2; //最大值
      }
      else
      {
                j3 = j2;
                j4 = j1; //最大值
      }

      for(j=0;j<num_g;j++)
      {
                pathnew = -2;
                jiaocha = -2;
      }

      for(i=j3-1;i<j4;i++)
      {
                pathnew = path;
      }
      k=0;
      for(i=0;i<num_g;i++)
      {
                mm=1;
                for(j=j3-1;j<j4;j++)
                {
                        if(path1==path)
                              mm=0;
                }
                if(mm==1)
                {
                        jiaocha = path1;
                        k=k+1;
                }
      }
      k=0;
      for(i=0;i<j3-1;i++)
      {
                pathnew = jiaocha;
                k=k+1;
      }
      for(i=j4;i<num_g;i++)
      {
                pathnew = jiaocha;
                k=k+1;
      }
      for(i=0;i<num_g;i++)
      {
                path1 = pathnew;
      }
}
cross_gx.h#ifndef _CROSS_GX_H_
#define _CROSS_GX_H_

void cross_gx(int path1[],int path[]);// 适应度函数

#endif





页: [1]
查看完整版本: 基于PSO算法的工序问题求解