C ++ simulation ant colony algorithm for Job Shop Scheduling (Job-Shop Scheduling Problem, JSP)

A job shop scheduling problem described

Job Shop Scheduling (Job Shop Scheduling, JSP) is one of the most classic of several NP-hard problem. Its extremely wide range of applications, involving aircraft scheduling, dispatching aircraft airport, port cargo scheduling, automotive and other processing lines.

JSP Problem Description: a processing system M machines, required machining N jobs, wherein the jobs i contains the number of steps of Li . So , the L the total number of steps for the task set. Wherein each step of the processing time has been determined, and must be processed in the order of each job step. Scheduled task is to arrange all processing operations on Scheduling, while the constraint condition is satisfied, so that performance is optimized .

Job Shop Scheduling consider the following constraints:

Cons . 1: each process on the specified machining, and can begin to be processed after a step before its completion processing;

Cons 2: 1 at a time machine can only process a job;

Cons . 3: processing each job only once on a single machine;

Cons . 4: step and the order of job processing time is known, does not change with changes in the ordering process.

Second, the mathematical model of job shop scheduling problem

In the design and implementation of an integrated part of this course, we will work to optimize target shop scheduling problem to minimize the makespan: Let ( i , j ) indicates that the job i of the j th process. Sij and Tij represent the ( I , J ) processing starting time and process time. Zijk represents ( I , J ) is in the first k on the machining table: If ( I , J ) at the k processing on the machine, Zijk =. 1; otherwise, Zijk = 0. Ck is the first k machine completion time, the mathematical model are as follows:

(1)

(2)

(3)

(4)

Equation (1) as the objective function, so that the machine finishes the latest completed as soon as possible, i.e. the shortest machining time; Equation (2) represents a post-processing a job can be completed prior to processing in a step after step; Equation (3) 1 represents a first processing step of starting operation time is greater than or equal to 0; equation (4) do not simultaneously represent one or more processing operations on a machine tool.

Third, the problem instance

An example is given below of the job shop scheduling problem in which a pair of values ​​denoted by (m, P) on each step, where, m represents the current step to be processed on the first machine m, P m denotes the current processing machine processing time required for the step. (Note: number of machines and jobs start at 0)

  1. jop0 = [(0,3), (1,2), (2,2)]
  2. jop1=[(0,2),(2,1),(1,4)]
  3. jop2 = [(1,4), (2,3)]

In this example, there are three jobs jop0 steps of: marked on its first step has a (0,3), which represents a first step must be processed on the first machine 0 and requires three processing units time; it is marked on the first step with a 2 (1,2), which represents the 2 step must be processed on the first machine, and the processing time required 2 units; empathy remaining. In general, in this example a total of eight steps.

A feasible solution to this problem is L = 8 are arranged a start time step, and satisfies the constraint problem. The following figure shows a feasible solution (Note: This solution is not the optimal solution) Example:

In the figure, we can see each step of the processing operation carried out in the order given problem, and there is no overlap between each time interval. This result is feasible solution 12, i.e., three processing operations are completed.

Fourth, algorithm design

For this issue, I use ant colony algorithm to solve job shop scheduling problem.

1. regarding ant colony algorithm:

Ant System (Ant Colony System) by Italian scholars Dorigo, Maniezzo and others in the 1990s first proposed. In their study of ants foraging in the process, we found that a single ant behavior is relatively simple, but it may reflect some of the ant colony as a whole intelligent behavior. For example ant colony can be in different environments, to find the shortest path to reach the food source. This is because the ants in the ant colony transmission of information can be achieved through some mechanisms. After further study found that the ants will release substance might be called "pheromone" is on its way through the ants in the ant to "pheromone" having the ability to perceive, they along "pheromones "higher concentration walking paths, and each passing on the road will be left ant" pheromone ", which form a similar positive feedback mechanism, so that over time, the entire ant will arrive along the shortest path a food source.

When the ant ants reached the finish line will return immediately, a short distance from the road: the ants find the shortest path thanks to the pheromone and the environment, assuming that there are two paths leading to food from the ant nest, ants at the start of a similar number two on the road round trip time is short, fast repetition rate, and from the number of ants in the unit of time, the more, leaving a pheromone and more, will attract more ants come, it will leave more pheromone.

In the shop scheduling problem, ant is walking on one of its optional active mode configuration of Fig, project scheduling problem solution in this case is the order of the sequence and its mode of activity occurring constituted a road map, which the goal is that all work is done in the shortest time it takes, ants pheromone release in its active mode corresponding to the selected, so the design ant Colony algorithm, constituted shortest project duration the path, with the updated pheromone that pheromone content of each point of its path will accumulate the highest probability of ants choose to go the most.

Specifically, each ant in the absence of prior notice of food under the premise where the start in search of food. When a finding food, it releases into the environment a volatile secretions pheromone (called pheromones, the substance over time will gradually disappear volatile, characterized by the size of the path distance pheromone concentration) pheromone let other ants perceive and thus play a guiding role. When the pheromone generally have a plurality of paths, the ants will prefer a high concentration of pheromone in the path, so that a high concentration of a higher concentration of pheromone path, forming a positive feedback. Some ants are not like other ants always repeat the same way, they will look for other ways to open up the road if the other is shorter than the other way original, then, gradually, more ants are attracted to this shorter road to . Finally, after a period of time to run, there may be a shortest path is repeated most of the ants. Eventually, the path with the highest concentration of pheromone that is ultimately selected optimal path of the ants.

2. The establishment of workshop scheduling model:

Job-Shop scheduling problem because of its high complexity and randomness of strong, multi-constrained, the characteristics of multi-objective, we should use ant colony algorithm in which a key issue is how to Job-Shop scheduling problem into a suitable ant colony algorithm a natural expression model.

We can each process a workpiece as a TSP problem in cities, formed one to one relationship with a feasible schedule using the ant path obtained in the step of traversing each of the workpieces, each workpiece to be machined and the machining step time as distance, the total completion time as a total distance traveled of ants. Results while Job-Shop Scheduling must satisfy four constraints previously mentioned.

FIG bit disjunctive model G Job-Shop Scheduling Problem (V, A, E), where V is the set of nodes, including all operations of all jobs and two special nodes, a starting point, the terminating node, and representing the scheduled start End. A is a conjunctive arc processing sequence showing the same direction of the workpiece. E is a disjunctive arcs, two connection operation to be performed in the same processing machine. Figure is a general model:

3. FIG traversal:

Initially, super placed ant unified source, and the pheromone throughout all paths to a fixed value of FIG. Thereafter, all the ants to the end of action, together with the influence will be ant pheromones, ant path selection mode is currently walking path ant pheromones summed and taken as the maximum value of m random numbers, random number m and optionally pheromone, ants calculated path selection. When all the ants are coming to an end, when the full according to FIG pheromone pheromone dissipation dissipates parameters, and calculate the path of ants. This path A work order processing, in this order workpiece calculated time T. By this time, the calculated new ant pheromones W = Q / T (Q is a constant). Before this ant pheromone on the path are coupled with experienced W. When all the ant pheromones which all add to the map of the time. All ants and put back to the beginning, repeating the previous steps, with the increase in the number of repetitions, the ants will become increasingly closer toward the optimal solution.

4. Flowchart:

5. looking for the optimal solution:

In ant walking path computation process, it will record the current time appeared, processing time is the shortest. After the end of the program, the shortest processing time to output it.

Fifth, the pseudo-code

(1) machining time calculation function:

定义几个用来记录目前机器加工总时间的临时变量sum。然后是真正机器的总加工总时间的数组MachineWorkTime[maxn]。接下来是加工持续时间,目前加工步数,记录加工次序的变量的定义。在加工总工数的限定下,记录现在加工工件的工序、取加工顺序最晚加工完成的的时间作为下一个工件开始的时间、还有现在加工工件的件号、加工结束时间、持续时间、还有这是第几个加工机器。最后算出机器加工的时间。再接着往下计算下一工件在不同机器的加工时间。最后选出最大机器加工结束时间,以作为下一机器,下一工件的开始时间。继续下一个循环。

int time_caculation(int 加工需要的步数,bool 假) //计算需要加工的时间的函数
{
    int 总加工时间
    int 机器加工时间
    int J/加工持续时间
    int 加工进行到的步数
    recording 记录加工次序结构体数组
    //清空以上数组
    for(int k=0; k<工序总数; k++)
    {
        //记录现在加工工件的工序
        //取加工顺序里面最晚加工完成的作为起始点
        rec[k].job=i;//现在加工工件的件号
        rec[k].endd=rec[k].start +job[i][JobStep[i]].len;//加工结束时间
        JobLast[i]=rec[k].endd; //持续时间
        rec[k].machine=job[i][JobStep[i]].machine; //第几个加工机器
        MachineWorkTime[job[i][JobStep[i]].machine]=rec[k].endd;
        JobStep[i]++;
    }
    for(int i=0; i<m; i++)
    {
        max 取最大加工时间(作为下一个工件的开始时间)
    }
  //甘特图绘制
    return sum; //返回总加工时间
}

(2)甘特图绘画部分:

在time_calculation(int Job[],bool draw),设定了一个draw变量,如果draw=false 仅输出sum,即机器的最大加工时间。如果draw=true即执行上面的代码段,在加工工序数量和机器总最大加工时间的限定下,输出甘特图。

    if(条件为真) 
    {
        int 甘特图数组
        memset 清空数组
        for(int i=0; i<工序总数; i++)
        {
            for(int j=开始点; j<结束时间; j++)
            {
                把工件序号依次输出作为甘特图
            }
        }
        循环输出甘特图
    }

(3)正反馈机制过程:

除了蚂蚁走过时会形成信息素,接下来是定义一个reward变量模拟反馈机制。如果加工时间越短,说明距离短,说明蚂蚁往返一次时间短,重复频率高,单位时间内往返蚂蚁的数量就更多,留下的信息素就更多,会吸引的蚂蚁就更多,然后会留下更多的信息素。形成一个正反馈作用,记录这些反馈作用增加信息素的位置,再将这个正反馈形成的信息素加到信息素数组Pheromone[][][][]中。

            for(int i=0; i<蚂蚁数量; i++)
            {
                int 临时记录加工时间变量=time_caculation(ant[i].Path,false);
                if(ans <最优加工时间 && 总工序数所需要时间 <=临时最优加工时间)
                {
                    最优加工时间=临时记录加工时间
                    bestAnt=ant[i];
                }
                int reward =2000/ans; //回馈机制中的回馈,数字越小,回馈越大。
                for(int j=0; j<ant[i].Pathlen-1; j++)
                {
	  记录信息素增加的位置。
	  并且将增加的信息素加上原来的信息素:
                    Pheromone[a][b][c][d]+=reward;
                }
            }

(4)蚂蚁寻优过程:

首先定义蚂蚁数量,定义一个蚂蚁结构体,还有记录最佳次序的蚂蚁,还有记录最优加工时间的变量。设置随机数种子,循环进行蚂蚁寻道的过程。我们设定一个类似网络流里的超级源点,让蚂蚁随机在一个超级源点开始寻道。当蚂蚁行走时候(也就是蚂蚁选择了一个工件进行加工),如果选择的这个跟现在机器进行加工的工件以及次序是一样的,就进行信息素的累加。接下来是在加工数量有限的工序下,记录信息素的变化情况。

        int 蚂蚁数量
        Ant 蚂蚁结构体数组
        Ant 最优的蚂蚁
        把最优加工时间设定为无限大
        for(int i=0; i<10; i++)//进行10次迭代
        {
            //初始化随机数发生器,并且设置启动种子。生成随机数
            for(int j=0; j<antnum; j++) //第j只蚂蚁的旅程。
            {
                设定一个作为图的超级源点
                蚂蚁进行到的起始步数=SUPER_START;
                for(int k=0; k<Total_Step; k++)
                {
                    int allpre=0;//累计信息素
                    for(int l=0; l<m; l++)
                    {
                        if(蚂蚁现在加工的工件步数= 实际上机器加工的工件步数)
                        {
                            continue;
                        }
                        计算现在累计的信息素
                    }
                    int 一个随机选择数字
                    while(随机选择数字>=0)
                    {
                        if(现在蚂蚁加工的工件已经加工过了)
                        {
                            选择下一个工件,继续循环
                        }
                        将蚂蚁遍历过的路径“剪掉”,选择另一条路径进行加工
	      并且接着选择下一个工件
                    }
                }

 

六、程序代码及运行结果

源代码:

#include <bits/stdc++.h>
#define maxn 60 //最大工作量
#define Initialize_Pre 3000 //道路初始信息素量
#define DIS 0.5 //信息素消散速率
#define SUPER_START 48 //超级源点
using namespace std;

int Total_Step; //总步数
int Step[maxn]; //记录步数
int Pheromone[maxn][maxn][maxn][maxn]; //信息素,费洛蒙
int n ; //工件的数量
int m; //机器的数量
const int INF=9999999;

struct Pair
{
    int i;
    int j;
    void get(int a,int b)
    {
        i=a;
        j=b;
    }
} Jobnum[maxn];

struct Job
{
    int machine; //机器数量
    int len; //加工需要的时间段
} job[maxn][maxn];

struct Ant
{
    int JobStep[maxn]; //任务已经加工的步数
    int Path[maxn]; //记录最优加工次序的数组
    int Pathlen; //长度
    int get_Full_Path()
    {
        int sum=0;
        for(int i=0; i<Pathlen; i++)
        {
            sum+=Path[i];
        }
        return sum;
    }
    Pair paths[maxn];
};

void Initialize() //初始化函数
{
    memset(Pheromone,0,sizeof(Pheromone));
    for(int i=0; i<Total_Step; i++)
    {
        for(int j=0; j<Total_Step; j++)
        {
            for(int k=0; k<Total_Step; k++)
            {
                for(int l=0; l<Total_Step; l++)
                {
                    Pheromone[i][j][k][l]=Initialize_Pre; //初始化信息素道路的信息素
                }
            }
        }
    }
    for(int i=0; i<Total_Step; i++)
    {
        for(int j=0; j<Total_Step; j++)
        {
            Pheromone[SUPER_START][SUPER_START][i][j]=Initialize_Pre;
        }
    }
    return;
}

void Dissipation() //信息素消散函数
{
    for(int i=0; i<Total_Step; i++)
    {
        for(int j=0; j<Total_Step; j++)
        {
            for(int k=0; k<Total_Step; k++)
            {
                for(int l=0; l<Total_Step; l++)
                {
                    Pheromone[i][j][k][l] *=DIS; //乘以消散率,随着时间消散
                }
            }
        }
    }
    for(int i=0; i<Total_Step; i++)
    {
        for(int j=0; j<Total_Step; j++)
        {
            Pheromone[SUPER_START][SUPER_START][i][j] *=DIS;
        }
    }
    return;
}

struct recording
{
    int start; //开始的时间
    int endd; //结束的时间
    int job; //工件
    int machine; //机器
};

int time_caculation(int Job[],bool draw) //计算需要加工的时间的函数
{
    int sum=0; //总加工时间
    int MachineWorkTime[maxn]; //机器加工时间
    int JobLast[maxn]; //加工持续时间
    int JobStep[maxn]; //加工进行到的步数
    recording rec[maxn]; //记录加工次序
    //清空数组
    memset(MachineWorkTime,0,sizeof(MachineWorkTime));
    memset(JobLast,0,sizeof(JobLast));
    memset(JobStep,0,sizeof(JobStep));
    memset(rec,0,sizeof(rec));
    for(int k=0; k<Total_Step; k++)
    {
        int i=Job[k];//记录现在加工工件的工序
        rec[k].start=max(JobLast[i],MachineWorkTime[job[i][JobStep[i]].machine]);
        //取加工顺序里面最晚加工完成的作为起始点
        rec[k].job=i;//现在加工工件的件号
        rec[k].endd=rec[k].start +job[i][JobStep[i]].len;//加工结束时间
        JobLast[i]=rec[k].endd; //持续时间
        rec[k].machine=job[i][JobStep[i]].machine; //第几个加工机器
        MachineWorkTime[job[i][JobStep[i]].machine]=rec[k].endd;
        JobStep[i]++;
    }
    for(int i=0; i<m; i++)
    {
        sum=max(sum,MachineWorkTime[i]);
    }
    if(draw==true) //甘特图绘制
    {
        int gantt[maxn][maxn];//甘特图数组
        memset(gantt,0,sizeof(gantt));//清空数组
        for(int i=0; i<Total_Step; i++)
        {
            for(int j=rec[i].start; j<rec[i].endd; j++)
            {
                gantt[rec[i].machine][j]=rec[i].job+1;
            }
        }
        for(int i=0; i<m; i++)
        {
            for(int j=0; j<sum; j++)
            {
                printf("%d%c",gantt[i][j],j==sum-1?'\n':' '); //输出甘特图
            }
        }
    }
    return sum; //返回总加工时间
}

int main()
{
    cout << "请输入工件的数量以及机器的数量:"<< endl;
    while(cin >> n >> m)
    {
        Total_Step=0;
        for(int i=0; i<n; i++)
        {
            cout << "请输入加工所需要的步骤数量:"<< endl;
            cin >> Step[i];
            Total_Step+=Step[i];
            cout << "请输入需要在其加工的机器号码以及所需要加工的时间:"<< endl;
            for(int j=0; j<Step[i]; j++)
            {
                cin >> job[i][j].machine >> job[i][j].len;
            }
        }
        Initialize(); //初始化信息素
        //这部分是蚂蚁行走部分
        int antnum=Total_Step*2;//蚂蚁数量
        Ant ant[antnum+5];
        Ant bestAnt;
        int Best_Process_Time=INF;
        for(int i=0; i<10; i++)
        {
            srand(time(0)); //初始化随机数发生器,并且设置启动种子。生成随机数
            memset(ant,0,sizeof(ant));
            for(int j=0; j<antnum; j++) //第j只蚂蚁的旅程。
            {
                int nowJob=SUPER_START;//作为图的超级源点
                ant[i].JobStep[nowJob]=SUPER_START;
                for(int k=0; k<Total_Step; k++)
                {
                    int allpre=0;
                    for(int l=0; l<m; l++)
                    {
                        if(ant [i].JobStep[l]==Step[l])
                        {
                            continue;
                        }
                        allpre+=Pheromone[nowJob][ant[i].JobStep[nowJob]][l][ant[i].JobStep[l]];
                    }
                    int randSelectNum=rand()*rand()%allpre;
                    int select=0;
                    while(randSelectNum>=0)
                    {
                        if(ant[i].JobStep[select]==Step[select])
                        {
                            select++;
                            continue;
                        }
                        randSelectNum -= Pheromone[nowJob][ ant[i].JobStep[nowJob] ][select][ ant[i].JobStep[select] ];
                        select++;
                    }
                    select--;
                    ant[i].Path[ant[i].Pathlen]=select;
                    ant[i].paths[ant[i].Pathlen++].get(select,ant[i].JobStep[select]);
                    //ant[i].JobStep[select]++;
                    nowJob=select;
                }
            }
            Dissipation();//每次蚂蚁行走完之后,信息素都会消散
            //这部分是反馈部分
            for(int i=0; i<antnum; i++)
            {
                int ans=time_caculation(ant[i].Path,false);
                if(ans <Best_Process_Time && Total_Step <=ans)
                {
                    Best_Process_Time =ans;
                    bestAnt=ant[i];
                }
                int reward =2000/ans; //回馈机制中的回馈,数字越小,回馈越大。
                for(int j=0; j<ant[i].Pathlen-1; j++)
                {
                    int a=ant[i].paths[j].i;
                    int b=ant[i].paths[j].j;
                    int c=ant[i].paths[j+1].i;
                    int d=ant[i].paths[j+1].j;
                    Pheromone[a][b][c][d]+=reward;
                }
            }
            cout << "最佳的加工时间是:"<< Best_Process_Time << endl;
            cout << "甘特图是:"<< endl;
            time_caculation(bestAnt.Path,true);
            cout << "加工顺序是:"<< endl;
            for(int i=0; i<Total_Step; i++)
            {
                printf("%d%s",bestAnt.Path[i]+1,i==Total_Step-1?"\n":"->");
            }
        }
        return 0;
    }
}

1.进行一次迭代的结果图:

2.进行10次迭代的结果:

七、总结

经过本项目,初次接触NP完全问题,较好地理解车间调度问题的解决方案以及对蚁群算法更好的认识。

蚁群算法有以下特点,总结如下:

1.从算法的性质而言,蚁群算法是在寻找一个比较好的局部最优解,而不是强调全局最优解

2.开始时算法收敛速度较快,在随后寻优过程中,迭代一定次数后,容易出现停滞现象

3.蚁群算法对JSP、TSP及相似问题具有良好的适应性,无论车间规模大还是小,都能进行有效地求解,而且求解速度相对较快

4.蚁群算法解得稳定性较差,及时参数不变,每次执行程序都有可能得到不同界,为此需要多执行几次,已寻找最佳解。

5.蚁群算法中有多个需要设定的参数,而且这些参数对程序又都有一定的影响,所以选择合适的参数组合在算法设计过程中也非常重要

八、参考文献

[1]https://blog.csdn.net/qq_41249282/article/details/84318943

[2]https://blog.csdn.net/weixin_33690367/article/details/87979062

[3]https://blog.csdn.net/weixin_42715356/article/details/83590449

[4]https://blog.csdn.net/qq_41249282/article/details/84797347

[5]吴 统 威 . 遗传蚁群算法在Job_Shop调度的应用研究

[6]ZHANG Xiaoling, HE Caixiang, CHEN Jianhua . Ant Colony Algorithm for Solving Job-Shop Scheduling Problem(College of Mathematics and Computer Science,Dali University, Dali,Yunnan 671003,China)

[7]曹 岩,雷 蕾,房亚东.蚁群算法在离散型车间派工中的应用(西安工业大学 机电工程学院,西安 710032)

发布了57 篇原创文章 · 获赞 9 · 访问量 3602

Guess you like

Origin blog.csdn.net/Jayphone17/article/details/103434555