柔性车间调度问题:N个工件要在M台机器上加工。每个工件包含一道或多道工序,工序顺序是预先确定的,每道工序可以在多台不同加工机器上进行加工,工序的加工时间随加工机器的不同而不同。调度目标是为每道工序选择最合适的机器、确定每台机器上各个工序的最佳加工顺序以及开工时间,使整个系统 的某些性能指标达到最优。因此柔性作业车间调度问题包含两个子问题确定各工件的加工机器机器选择子问题和确定各个机器上的加工先后顺序工序排序子问题。
实验结果:
部分代码:
clear all
problem = 'la31.fjs';
%GLNSA Parameters
smart_number = 40;
generation_number = 250;
stagnation_number = 40;
elitism_prob = 0.02;
nieghbor_number = 2;
%Read problem data
[job_number, machine_number, operations_number, operations_number_vector, operations_start_vector, operations_vector, time_table, feasible_machines_table] = readProblemData(problem);
tic;
[so, sm, best_makespan, ~, ~, ~, convergence_curve] = GLNSA(smart_number, generation_number, stagnation_number, elitism_prob, nieghbor_number, job_number, machine_number, operations_number, operations_number_vector, operations_start_vector, operations_vector, time_table, feasible_machines_table);
execution_time=toc;
%Best solution
disp(['Best makespan: ' num2str(best_makespan)])
disp(['Execution time: ' num2str(execution_time)])
machineGanttDiagram(so, sm, job_number, machine_number, operations_number, operations_start_vector, time_table)
figure(2)
plot(1:size(convergence_curve,2),convergence_curve,'linewidth',1.5)
xlim([1,size(convergence_curve,2)])
title('Optimization of LA31 instance','fontsize',16)
xl=xlabel('Iteration','fontsize',14);
xl.Position(2)=xl.Position(2)-.2;
yl=ylabel('Makespan','fontsize',14);
yl.Position(1)=yl.Position(1)-.2;
yticks(1400:100:2800)
grid on
function [job_number, machine_number, operations_number, operations_number_vector, operations_start_vector, operations_vector, time_table, feasible_machines_table] = readProblemData(filename)
% The function reads the problem data table and returns the number of jobs, the number of machines,
% the vector with the number of operations per job, the vector with the
% previous operation number where each job starts, the base vector with repeated operations for each
% job (1, ..., 1,2, ..., 2, ..., n ... n), the table of times (operations / machines) and the vector
% of the initial operation number of each job, in which operation number starts from 0
% Data format:
% in the first line there are (at least) 2 numbers: the first is the number of jobs and the second the number
% of machines (the 3rd is not necessary, it is the average number of machines per operation)
% Every row represents one job: the first number is the number of operations of that job, the second number
% (let's say k>=1) is the number of machines that can process the first operation; then according to k, there are
% k pairs of numbers (machine,processing time) that specify which are the machines and the processing times;
% then the data for the second operation and so on...
% Example: Fisher and Thompson 6x6 instance, alternate name (mt06)
% 6 6 1
% 6 1 3 1 1 1 3 1 2 6 1 4 7 1 6 3 1 5 6
% 6 1 2 8 1 3 5 1 5 10 1 6 10 1 1 10 1 4 4
% 6 1 3 5 1 4 4 1 6 8 1 1 9 1 2 1 1 5 7
% 6 1 2 5 1 1 5 1 3 5 1 4 3 1 5 8 1 6 9
% 6 1 3 9 1 2 3 1 5 5 1 6 4 1 1 3 1 4 1
% 6 1 2 3 1 4 3 1 6 9 1 1 10 1 5 4 1 3 1
% first row = 6 jobs and 6 machines 1 machine per operation
% second row: job 1 has 6 operations, the first operation can be processed by 1 machine that is machine 3 with processing time 1.
% Reference: http://people.idsia.ch/~monaldo/fjsp.html
% Read file
file=fopen(filename,'r');
% Find all integer numeric data that define the problem
data=fscanf(file,'%f');
% Obtain job_number, machine_number
job_number=data(1);
machine_number=data(2);
% Third numerical data is not used
% Initialize operations_vector as empty
operations_vector=[];
% Indices to take jobs, operations and positions in the data array
indice=4;
nt=1;
% Loop to take jobs
while(nt<=job_number)
% Take number of operations for job nt and put it in the
% operations_number_vector and vector vectors
operations_number_vector(nt)=data(indice);
operations_start_vector(nt)=sum(operations_number_vector(1:nt-1));
% Add repeated operations for each job to form base solution
job_operations=ones(1,operations_number_vector(nt))*nt;
operations_vector=[operations_vector job_operations];
% Lopp to take operations of each job nt
for operations_number=1:operations_number_vector(nt)
% Read number of machines feasible to realize the current operation
indice=indice+1;
numMaq=data(indice);
% Loop to take machines and processing times for this operation
for i=1:numMaq
% Increase indice, read machine, increase indice, read time
indice=indice+1;
machine=data(indice);
indice=indice+1;
time=data(indice);
% Add time in time_table, at row
% operations_start_vector(nt)+operations_number an column machine
time_table(operations_start_vector(nt)+operations_number,machine)=time;
end
end
% Take data of the next job
indice=indice+1;
nt=nt+1;
end
% Operations number
operations_number=length(operations_vector);
% Fill table of feasible machines for each operation
feasible_machines_table=[];
% Loop to take operations in time table
for oper=1:length(time_table)
% Obtain feasible machines for operation oper
feasible_indices = time_table(oper,:) ~= 0;
feasible_machines_table=[feasible_machines_table; feasible_indices];
end
end
function [best_so, best_SM, best_makespan, Population_so, Population_SM, Population_makespan, convergence_curve] = GLNSA(smart_number, generation_number, stagnation_number, elitism_prob, nieghbor_number, job_number, machine_number, operations_number, operations_number_vector, operations_start_vector, operations_vector, time_table, feasible_machines_table)
% Implementation of the GLNSA
% Population array, simple to obtain execution speed
Population_so=zeros(smart_number,operations_number);
Population_SM=zeros(smart_number,operations_number);
Population_makespan=zeros(smart_number,1);
% Table with the features of each solution regarding to jobs,
% ordered by jobs and operations order (J_11, J_12, ... J_nm-1, J_nm)
% Rows keep information in this order:
% Assigned machine
% Processing position in the assigned machine
% Final time of operation
% Operation length
% Tail time of operation
% Position of the operation in so
% Position of the operation in SM
Population_jobs_table=zeros(6,operations_number,smart_number);
% Table with the features of each solution regarding to machines,
% ordered by machines and operations order (M_11, M_12, ... M_mo-1, M_mo)
% Rows keep information in this order:
% Programmed job
% Operation of the programmed job
% Final time of operation
% Operation length
% Tail time of operation
% Position of the operation in so
% Position of the operation in SM
Population_machines_table=zeros(6,operations_number,smart_number);
% Vector with the number of operations assigned to each machine for every solution
Population_machines_vector=zeros(smart_number,machine_number);
Population_machines_order_vector=zeros(smart_number,operations_number);
Population_PosMk=zeros(smart_number,1);
Population_PosTT=zeros(smart_number,operations_number);
Population_PosTM=zeros(smart_number,operations_number);
完整代码