遗传模拟退火算法对流水车间调度优化,目标为最小化最大流程时间,输出甘特图和收敛图,matlab完整代码如何编写
时间: 2024-01-30 08:03:11 浏览: 92
以下是遗传模拟退火算法对流水车间调度优化的matlab完整代码,包含甘特图和收敛图的输出:
```matlab
% 遗传模拟退火算法对流水车间调度优化
% 目标为最小化最大流程时间
clc;
clear;
% 设置参数
job_num = 10; % 工件数目
machine_num = 3; % 机器数目
pop_size = 50; % 种群大小
max_gen = 100; % 最大迭代次数
pc = 0.8; % 交叉概率
pm = 0.1; % 变异概率
T0 = 100; % 初始温度
Tf = 1; % 最终温度
alpha = 0.98; % 降温系数
% 生成初始种群
pop = zeros(pop_size, job_num);
for i = 1:pop_size
pop(i, :) = randperm(job_num);
end
% 计算初始种群适应度
fitness = zeros(pop_size, 1);
for i = 1:pop_size
[makespan, ~] = schedule(pop(i, :), job_num, machine_num);
fitness(i) = makespan;
end
% 记录最优解和最优解对应的适应度
best_sol = pop(1, :);
best_fitness = fitness(1);
% 记录每一代的最优解和平均适应度
best_fitness_each_gen = zeros(max_gen, 1);
avg_fitness_each_gen = zeros(max_gen, 1);
% 记录退火过程中的最优解和最优解对应的适应度
sa_best_sol = pop(1, :);
sa_best_fitness = fitness(1);
% 记录退火过程中每一步的最优解和最优解对应的适应度
sa_best_fitness_each_step = zeros(max_gen, 1);
% 迭代
for gen = 1:max_gen
% 交叉
for i = 1:2:pop_size
if rand < pc
% 选择父代
p1 = tournament_selection(pop, fitness, 2);
p2 = tournament_selection(pop, fitness, 2);
% 交叉
[c1, c2] = crossover(p1, p2);
% 更新种群
pop(i, :) = c1;
pop(i+1, :) = c2;
end
end
% 变异
for i = 1:pop_size
if rand < pm
% 变异
c = mutation(pop(i, :));
% 更新种群
pop(i, :) = c;
end
end
% 计算种群适应度
for i = 1:pop_size
[makespan, ~] = schedule(pop(i, :), job_num, machine_num);
fitness(i) = makespan;
end
% 选择
[pop, fitness] = elitist_selection(pop, fitness, pop_size);
% 记录最优解和最优解对应的适应度
if fitness(1) < best_fitness
best_sol = pop(1, :);
best_fitness = fitness(1);
end
% 记录每一代的最优解和平均适应度
best_fitness_each_gen(gen) = best_fitness;
avg_fitness_each_gen(gen) = mean(fitness);
% 退火
T = T0 * alpha^(gen-1); % 当前温度
for i = 1:pop_size
% 选择邻域解
c = pop(i, :);
neighbor = mutation(c);
% 计算邻域解适应度
[neighbor_makespan, ~] = schedule(neighbor, job_num, machine_num);
% 计算适应度差
delta_fitness = neighbor_makespan - fitness(i);
% 判断是否接受邻域解
if delta_fitness < 0 || rand < exp(-delta_fitness/T)
pop(i, :) = neighbor;
fitness(i) = neighbor_makespan;
end
% 记录退火过程中的最优解和最优解对应的适应度
if neighbor_makespan < sa_best_fitness
sa_best_sol = neighbor;
sa_best_fitness = neighbor_makespan;
end
end
% 记录退火过程中每一步的最优解和最优解对应的适应度
sa_best_fitness_each_step(gen) = sa_best_fitness;
end
% 输出结果
fprintf('最优解:\n');
disp(best_sol);
fprintf('最优解对应的适应度:\n');
disp(best_fitness);
fprintf('退火过程中的最优解:\n');
disp(sa_best_sol);
fprintf('退火过程中的最优解对应的适应度:\n');
disp(sa_best_fitness);
% 绘制甘特图
[makespan, start_time] = schedule(best_sol, job_num, machine_num);
plot_gantt_chart(job_num, machine_num, start_time, makespan);
% 绘制收敛图
figure;
plot(1:max_gen, best_fitness_each_gen, 'r', 'LineWidth', 2);
hold on;
plot(1:max_gen, avg_fitness_each_gen, 'b', 'LineWidth', 2);
plot(1:max_gen, sa_best_fitness_each_step, 'g', 'LineWidth', 2);
legend('最优解', '平均适应度', '退火过程中的最优解');
xlabel('迭代次数');
ylabel('适应度');
title('收敛图');
% 选择函数
function selected = tournament_selection(pop, fitness, k)
pop_size = size(pop, 1);
selected = zeros(k, size(pop, 2));
for i = 1:k
idx = randperm(pop_size, 2);
if fitness(idx(1)) < fitness(idx(2))
selected(i, :) = pop(idx(1), :);
else
selected(i, :) = pop(idx(2), :);
end
end
end
% 交叉函数
function [c1, c2] = crossover(p1, p2)
len = length(p1);
idx = randperm(len, 2);
start = min(idx);
stop = max(idx);
c1 = p1;
c2 = p2;
for i = start:stop
j1 = find(c1 == p2(i), 1);
j2 = find(c2 == p1(i), 1);
c1([i j1]) = c1([j1 i]);
c2([i j2]) = c2([j2 i]);
end
end
% 变异函数
function c = mutation(p)
len = length(p);
idx = randperm(len, 2);
start = min(idx);
stop = max(idx);
rev = fliplr(p(start:stop));
c = [p(1:start-1) rev p(stop+1:end)];
end
% 精英选择函数
function [pop, fitness] = elitist_selection(pop, fitness, pop_size)
[sorted_fitness, idx] = sort(fitness);
pop = pop(idx, :);
fitness = sorted_fitness;
if size(pop, 1) > pop_size
pop = pop(1:pop_size, :);
fitness = fitness(1:pop_size);
end
end
% 调度函数
function [makespan, start_time] = schedule(job_seq, job_num, machine_num)
processing_time = rand(job_num, machine_num); % 生成随机处理时间
start_time = zeros(job_num, machine_num); % 记录每道工序的开始时间
end_time = zeros(job_num, machine_num); % 记录每道工序的结束时间
for j = 1:machine_num
if j == 1
start_time(1, j) = 0;
else
start_time(1, j) = end_time(1, j-1);
end
end_time(1, j) = start_time(1, j) + processing_time(job_seq(1), j);
end
for i = 2:job_num
for j = 1:machine_num
if j == 1
start_time(i, j) = end_time(i-1, j);
else
start_time(i, j) = max(end_time(i, j-1), end_time(i-1, j));
end
end_time(i, j) = start_time(i, j) + processing_time(job_seq(i), j);
end
end
makespan = max(end_time(:, end));
end
% 绘制甘特图函数
function plot_gantt_chart(job_num, machine_num, start_time, makespan)
color = lines(job_num);
figure;
for i = 1:job_num
for j = 1:machine_num
x = [start_time(i, j) start_time(i, j) start_time(i, j)+start_time(job_num, machine_num)];
y = [i-0.4 i+0.4 i];
patch(x, y, color(i, :));
end
end
xlabel('时间');
ylabel('工件');
xlim([0 makespan]);
ylim([0 job_num+1]);
title('甘特图');
end
```
阅读全文