【优化分配】基遗传算法求解医疗资源分配优化问题【含Matlab源码 1419期】

⛄一、遗传算法简介

1 引言
在这里插入图片描述
在这里插入图片描述
2 遗传算法理论
2.1 遗传算法的生物学基础
在这里插入图片描述
在这里插入图片描述
2.2 遗传算法的理论基础
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2.3 遗传算法的基本概念
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2.4 标准的遗传算法
在这里插入图片描述
在这里插入图片描述
2.5 遗传算法的特点
在这里插入图片描述
在这里插入图片描述
2.6 遗传算法的改进方向
在这里插入图片描述
3 遗传算法流程
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
4 关键参数说明
在这里插入图片描述

⛄二、部分源代码

close all;
clear;
clc;
global MIN_START_TIME
global MAX_END_TIME
MIN_START_TIME = 8;
MAX_END_TIME = 18;

%=%
gnmax = 50; %最大代数
pc = 0.8; %交叉概率
pm = 0.1; %变异概率
pop_size = 10; %初始化种群数量
eventStartTime = 10; %发生动态事件的时刻
%
=%

[job, mac_num] = read_data(‘hospitaldata.xlsx’);
[mac, mac_state] = creat_machine(mac_num);

%-----------------------------------------------
% 获取先进先出策略
%-----------------------------------------------
pop = inipop(1, job, mac_num);
[f_mac_time, f_mac_serial, f_mac_start, f_mac_end] = decode(pop, job, mac_num);
draw_gantt(f_mac_time, f_mac_serial, f_mac_start, f_mac_end, job, mac, 0);
fprintf(‘先进先出策略完成时间:%.2f\n’,f_mac_time);
f_job_wait = job_waittime(f_mac_serial, f_mac_start, f_mac_end, job, mac);
fprintf(‘先进先出策略用户等待时间:\n’);
f_job_wait
%输入:解码
%输出:二维矩阵,行数i对应原编码中第i个元素,第一列对应工件,第二列对应该工件的工艺
function [max_mac_time,mac_serial,mac_start,mac_end]=decode(code, job, mac_num)
mac = creat_machine(mac_num);
n=length(code)/2;%工序总数量
%解码生成工作序列,二维矩阵,第i行为编码的第i个工序,第一列为工件代号,第二列为工序代号
job_serial=[];
for i=1:n
job_serial(end+1,:)=[code(i),sum(code(1:i)==code(i))];
end
%解码生成机器序列,元胞组,组内第i个元胞组为机器代号,内部是按照先后顺序的工序向量,工序格式为job_serial格式
%解码生成机器各工序开始、结束时间,工件开始、结束时间
mac_serial=cell(1,sum(mac_num));
job_start=cell(1,length(job));
job_end=cell(1,length(job));
mac_start=cell(1,sum(mac_num));
mac_end=cell(1,sum(mac_num));
overtime = [];
for i=1:n
%此部分求出第i号工序加工机器:the_mac
the_mac_type=job{job_serial(i,1)}{job_serial(i,2)}(2);
job_in_mac_code=0;
for j=1:job_serial(i,1)-1
job_in_mac_code=job_in_mac_code+length(job{j});
end
job_in_mac_code=job_in_mac_code+job_serial(i,2)+n;
the_mac=mac{the_mac_type}(code(job_in_mac_code));

%求出工件开始时间(不是真正的开始时间)
if job_serial(i,2)==1
    job_start{job_serial(i,1)}(1) = job{job_serial(i,1)}{1}(3); %最早开始时间
else
    job_start{job_serial(i,1)}(end+1)=job_end{job_serial(i,1)}(job_serial(i,2)-1);
end

%将第i个工序插入到机器中加工,如果机器间隔合适,插入间隔中,如不合适,插入到最后一位
%有一个问题,jobserial没有调顺序,结构还待优化
[mac_start{the_mac},mac_end{the_mac},job_end_time,insert_pot] = insert_mac(...
    mac_start{the_mac},...
    mac_end{the_mac},...
    job_start{job_serial(i,1)}(job_serial(i,2)),...
    job_end{job_serial(i,1)},...
    job{job_serial(i,1)}{job_serial(i,2)}(1),...
    job{job_serial(i,1)}{job_serial(i,2)}(3),...
    job{job_serial(i,1)}{job_serial(i,2)}(4),...
    true);
if insert_pot > 0
    if insert_pot == 1
        mac_serial{the_mac} = [job_serial(i,:); mac_serial{the_mac}];
    else
        mac_serial{the_mac} = [mac_serial{the_mac}(1:insert_pot-1,:);job_serial(i,:);mac_serial{the_mac}(insert_pot:end,:)];
    end
    job_end{job_serial(i,1)}(end+1)=job_end_time;
else
    overtime(end+1,:) = job_serial(i,:);
    job_end{job_serial(i,1)}(end+1)=job_end_time;
end

end

%求出机器最大完工时间
global MAX_END_TIME
max_mac_time=0;
if ~isempty(overtime)
max_mac_time = MAX_END_TIME;
else
for i=1:sum(mac_num)
if ~isempty(mac_end{i})
max_mac_time=max(max_mac_time,max(mac_end{i}));
end
end
end
end
function [flag, max_mac_time, up_mac_serial, up_mac_start, up_mac_end, update_job, update_mac, over_time_job] = dynamin(…
mac_serial, mac_start, mac_end,…
add_job, delete_job, add_mac, delete_mac,…
eventStartTime, job, mac, mac_state)
%dynamin 动态规划
% 根据获取的job 和 mac的动态变化信息,对mac_serial, mac_start, mac_end及job列表进行更新

% 动态事件发送后需要处理的job list,第一列是job编号,第二列是对应的工序号,第三列是最早开始时间
todo_job_list = [];

%-----------------------------------------------
% 1. 删除某患者后续阶段
%-----------------------------------------------
if ~isempty(delete_job)
[num, ~] = size(delete_job);
for i = 1:num
[first, second] = find_job_coord(mac_serial, delete_job(i,:));
if first>0
temp_time = mac_start{first}(1,second);
if temp_time > eventStartTime
flag = true;
[mac_serial, mac_start, mac_end] = delete_task(first, second, mac_serial, mac_start, mac_end);
Tot = length(job{delete_job(i,1)});
if delete_job(i,2) for n = delete_job(i,2)+1:Tot
[first, second] = find_job_coord(mac_serial, [delete_job(i,1),n]);
[mac_serial, mac_start, mac_end] = delete_task(first, second, mac_serial, mac_start, mac_end);
end
end
end
end
end
end

%-----------------------------------------------
% 2. 新增患者
%-----------------------------------------------
if ~isempty(add_job)
flag = true;
N = length(job);
for i = 1:length(add_job)
job_start_time = eventStartTime;
for j = 1:length(add_job{i})
if j > 1
job_start_time = job_start_time + add_job{i}{j-1}(1);
end
todo_job_list(end+1,:) = [N+i, j, job_start_time];
end
end
update_job = [job, add_job];
end

%-----------------------------------------------
% 3. 删除某个医疗资源
%-----------------------------------------------
if ~isempty(delete_mac)
[num, ~] = size(delete_mac);
nb_mac = mac_max_num(mac);
for i = 1:num
% 判断删除的mac id是否超范围
if delete_mac(i,1) > nb_mac
continue;
end

    mac_pos = delete_mac(i,1);
    [~, mac_state] = UpdateMac(mac, mac_state, mac_pos, 'D');
    [row, ~] = size(mac_serial{mac_pos});
    for j = 1:row
        if mac_start{mac_pos}(j) >= eventStartTime
            flag = true;
            tmptime = eventStartTime;
            % 查找前一个工序的完成时间
        {first}(second), eventStartTime);
                end
            end
            
            % 把影响到该job的后续工序都加入todo中
            Tot = length(job{mac_serial{mac_pos}(j,1)});
            for n = mac_serial{mac_pos}(j,2):Tot
                job_time = 0;
                if n > mac_serial{mac_pos}(j,2)
                    job_time = job{mac_serial{mac_pos}(j,1)}{n-1}(1);
                end
                todo_job_list(end+1,:) = [mac_serial{mac_pos}(j,1), n, tmptime+job_time];  
            end
        end  
    end
end

end

%-----------------------------------------------
% 4. 增加某些医疗资源
%-----------------------------------------------
if ~isempty(add_mac)
[row, ~] = size(add_mac);
for i = 1:row
[mac, mac_state] = UpdateMac(mac, mac_state, add_mac(i,:), ‘A’);
mac_serial = [mac_serial, cell(1, add_mac(i,2))];
mac_start = [mac_start, cell(1, add_mac(i,2))];
mac_end = [mac_end, cell(1, add_mac(i,2))];
end
end

%-----------------------------------------------
% todo list 去重,并删除对应的task,再进行动态插入
%-----------------------------------------------
if ~isempty(todo_job_list)
todo_job_list = unique(todo_job_list, ‘rows’);

up_mac_start = mac_start;
up_mac_end = mac_end;
update_mac = mac;

end

end

⛄三、运行结果

【优化分配】基遗传算法求解医疗资源分配优化问题【含Matlab源码 1419期】_第1张图片
【优化分配】基遗传算法求解医疗资源分配优化问题【含Matlab源码 1419期】_第2张图片
【优化分配】基遗传算法求解医疗资源分配优化问题【含Matlab源码 1419期】_第3张图片
【优化分配】基遗传算法求解医疗资源分配优化问题【含Matlab源码 1419期】_第4张图片

⛄四、matlab版本及参考文献

1 matlab版本
2014a

2 参考文献
《智能优化算法及其MATLAB实例(第2版)》包子阳 余继周 杨杉著 电子工业出版社

你可能感兴趣的:(Matlab优化求解(进阶版),matlab,算法,开发语言)