模拟退火算法解决工作台加工工件问题

#include<iostream>
#include <cmath>
#include <stdio.h>
#include<cstring>



using namespace std;
const int MAXN = 60;           //最大约束数n
const double INIT_T = 2000;      //初始温度
const double RATE = 0.95;        //温度衰减率
const double FINAL_T = 0;    //终止温度
const int IN_LOOP = 13000;      //内层循环次数
const int OUT_LOOP = 20000;       //外层循环次数



const double D[60] = { 9.1247,9.7379,0.07237,2.1816,6.409,6.3541,2.3457,3.1771,4.6829,1.2265,
9.4124,1.0524,7.9937,8.7719,1.0097,5.476,2.5046,3.6155,5.9472,6.4145,
3.1391,2.1592,7.9639,3.1333,3.9956,9.5806,1.98,2.8754,3.6676,4.8098,
4.5182,5.6604,9.0938,0.22301,1.2916,6.445,2.488,7.5405,0.63019,6.8949,
7.3177,2.2226,4.1681,6.062,8.5309,3.4265,8.1251,2.6999,9.4159,4.6161,
9.8756,9.1219,7.3772,0.60151,0.675,1.2037,2.1443,7.1115,6.0297,9.8993,};




int x[8][60], z[8] = {}, z2[8] = {}, temp;
int  oldwork[8][60] = {}, bestwork[8][60] = {}; //新指派最优指派
double tim, oldtim, besttim;                  //当前时间和最优时间
double cost[8] = {};
int  a[60];                  //初始解序列



/*void swap(int *y, int *p)         //交换两个数
{
 
}
*/

void totaldist()        //计算总时间
{
 double  max = 0;
 for (int i = 0; i < 8; i++)
 {
  if (cost[i]>max)
   max = cost[i];
 }
 tim=max;
}
void init()                     //借的初始化,并计算时间
{
 for (int j = 0; j < 8; j++)
 {
  for (int b = 0; b <= z[j]; b++)
  {
   x[j][b] = 0;
  }
 }
 for (int i = 0; i < 8; ++i)
  cost[i] = 0;
 for (int i = 0; i < 8; ++i)
  z[i] = 0;
 for (int c= 0; c < 8; ++c)
 {
  x[c][0] = a[c];
  cost[c] = D[a[c]];
 }
 int c = 8, k ;
 while (c < 60)     //赋初值
 {
  double min = 100;
  for (int j = 0; j < 8; j++)
  {
   if (cost[j] < min)
   {
    min = cost[j];
    k = j;
   }
  }
  z[k]++;
  x[k][z[k]] = a[c];
  z[k]--;
  cost[k] = cost[k] + D[a[c]];
  z[k]++;
  c++;
 }
 totaldist();
}


/***********************************************************************    
                 产生指派方法
***********************************************************************/

/*
void getnext()   //新解产生函数
{
    int l=0,f =0;
    while (l == f)
    {
        l= rand() % 60;
        f= rand() % 60;
    }
    int t;
    t = a[l]; a [l]=a[f];a[f] = t;
    init();
}
*/

/***********************************************************************                    
                        退火和降温过程
**********************************************************************/

void sa()
{
    double T;               //温度
 
    int i,t,m, A_t = 0;
    double delta;
    T = INIT_T;     //赋值初始温度
    for (int j = 0; j < 8; j++)
    {
        for (int b = 0; b <= z[j]; b++)
        {
            bestwork[j][b] = x[j][b];
        }
    }
    for (int j = 0; j < 8; j++)
        z2[j] = z[j];
    besttim = tim;
    while (true)                           //外循环
    {
        for (i = 1; i <= IN_LOOP; i++)
        {
            if (i >59)//获取新路径
            {
                m = i / 60;
                m = i -m*60;
            }
            else
                m = i;
            t = a[m]; a[m] = a[m+1]; a[m+1] = t;
            init();
            delta = tim -besttim;
            if (delta < 0.0)
            {
                for (int j = 0; j < 8; j++)
                {
                    for (int b = 0; b <=z2[j]; b++)
                    {
                        bestwork[j][b] = 0;
                    }
                }
                for (int j = 0; j < 8; j++)
                    z2[j] = z[j];
                for (int j = 0; j < 8; j++)
                {
                    for (int b = 0; b <= z[j]; b++)
                    {
                        bestwork[j][b] = x[j][b];
                    }
                }
                besttim = tim;
            }
            else
            {
                double rnd = rand() % 1001 / 1000;     //随机产生0-1的浮点数
                double p = exp(-delta / T);
                if (p<rnd&&p>0)
                {
                    for (int j = 0; j < 8; j++)
                    {
                         for (int b = 0; b <= z2[j]; b++)
                         {
                             bestwork[j][b] = 0;
                         }
                    }
                    for (int j = 0; j < 8; j++)
                        z2[j] = z[j];
                    for (int j = 0; j < 8; j++)
                    {
                        for (int b = 0; b <=z[j]; b++)
                        {
                            bestwork[j][b] = x[j][b];
                        }
                    }
                    besttim = tim;
                }
            }
            A_t++;
        }
        T = T * RATE;    //降温
        if (A_t >= OUT_LOOP || T < FINAL_T)
            break;       //外循环停止条件
        }
}


/***********************************************************************                
                        程序主函数
*********************************************************************/

int main()
{
    int a2[60] = {}, n;
    for (int i = 0; i < 60; i++)
    {
        a2[i] = 60;
    }
  
    for (int i = 0; i < 60; i++)
    {
        n = rand() % 60;
        if (a2[n]== 60)
        {
            a[i] = n;
            a2[n] = n;
        }
        else
        {
            i--;
            continue;
        }
     }
     init();
     cout << "初始解和初始工作时间" << endl;
     for (int i = 0; i < 8;i++ )
     {
         cout << (i + 1) << "号工作台:";
         for (int j = 0; j<=z[i]; j++)
         cout <<x[i][j]<<"->";
         cout << endl;
     }
     cout <<"花费时间"<< tim<<endl;

     sa();
     cout << "最优解和最优工作时间" << endl;
     for (int i = 0; i < 8; i++)
     {
         cout << (i + 1) << "号工作台:";
         for (int j = 0; j<=z2[i]; j++)
         cout << bestwork[i][j] << "->";
         cout << endl;
     }
     cout << "最优时间" << besttim << endl;
     system("pause");

     return 0;
}

对8个工作台,60个工件,没有加工工序,。工作台加工能力相同,工件被加工时间不同。求怎样非配,加工结束时工作时间最短


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值