您的位置:首页 > 其它

数学建模__药品研发任务分配

2016-06-05 18:18 239 查看
                                                                                                       药品研发任务分配

有一家制药公司,为了提高企业的竞争力,决定加大科研力度,在研究了市场的需要,分析了当前药物的不足并且拜会了大量对有良好前景的医药领域进行 研究的科学家之后,选定了五位科学家开发五个项目,为了保证这些这些科学家都能够到他们感兴趣的项目中去,为此建立了一个投标系统,这五位科学家每个 人都有 1000点的投标点,他们向每一个项目投标,并且把较多的投标点投向自 己最感兴趣的项目中,下表显示了这五位科学家进行投标的情况



1. 根据所给出的投标情况,需要为每一个项目指派一位资深的科学家并且

使得科学家的总满意度最高,那么应当怎么进行指派?(人数需和项目数相等)

2. 罗博士接到了北大医学院的邀请去完成一个教学任务,而公司却非常想

把他留下来,但是北大的声望会使他选择离开公司。如果这种情况真的发生的话,

公司就只有放弃那个最缺乏热情的项目,那么公司应当放弃哪一个项目?

3. 当然公司并不愿意放弃任何一个项目,公司决定让朱博士或者王博士同

时完成两个项目,那么在只有 4 位科学家的情况下,让哪一位科学家领导哪一个

项目才能使得对项目的热情最大?(有人可以同时完成两个项目)

 

这题是一个典型的指派问题。最优化的目标是满意度最大,满意度的定义可以各不相同,我认为投标点数越大满意度越大,所以分配之后投标点数之和最大即为总满意度最高。

针对这个问题,

第一问,我们可以使用匈牙利算法,将投标点矩阵代入即可得到结果。

第二问,将罗博士的投标点全置为零,按第一问求解,得到分配结果,找出投标点最小的那个项目放弃掉。

第三问,分别将罗博士的投标点置为朱博士和王博士的,找出投标点最大那个方案,这样即可决定由哪个博士多带哪个项目。

附MATLAB代码如下:

function [z,answ]=allocation1(marix1)

%//////////////////////////////////////////////////
%输入效率矩阵 marix 为方阵;
%若效率矩阵中有 M,则用一充分大的数代替;
%输出z为最优解,ans为 最优分配矩阵;
%//////////////////////////////////////////////////
a=marix1;
s=length(a);%确定矩阵维数
b=a;
%1.行归约:
%确定矩阵行最小值,进行行减
ml=min(a');
for i=1:s
a(i,:)=a(i,:)-ml(i);
end

%2.列归约:
%确定矩阵列最小值,进行列减
mr=min(a);
for j=1:s
a(:,j)=a(:,j)-mr(j);
end

%3.试指派:
%4.画盖0线:
%5.更新矩阵:
%6.重复3-5直到成功。
% start working
num=0;
while(num~=s) %终止条件是“(0)”的个数与矩阵的维数相同
%index用以标记矩阵中的零元素,若a(i,j)=0,则index(i,j)=1,否则index(i,j)=0
index=ones(s);
index=a&index;
index=~index;
%flag用以标记划线位,flag=0 表示未被划线,
%flag=1 表示有划线过,flag=2 表示为两直线交点
%ans用以记录 a 中“(0)”的位置
%循环后重新初始化flag,ans
flag = zeros(s);
answ = zeros(s);
%一次循环划线全过程,终止条件是所有的零元素均被直线覆盖,
%即在flag>0位,index=0
while(sum(sum(index)))
%按行找出“(0)”所在位置,并对“(0)”所在列划线,
%即设置flag,同时修改index,将结果填入ans
for i=1:s
t=0;
l=0;
for j=1:s
if(flag(i,j)==0&&index(i,j)==1)
l=l+1;
t=j;
end
end
if(l==1)
flag(:,t)=flag(:,t)+1;
index(:,t)=0;
answ(i,t)=1;
end
end
%按列找出“(0)”所在位置,并对“(0)”所在行划线,
%即设置flag,同时修改index,将结果填入ans
for j=1:s
t=0;
r=0;
for i=1:s
if(flag(i,j)=
c69b
=0&&index(i,j)==1)
r=r+1;
t=i;
end
end
if(r==1)
flag(t,:)=flag(t,:)+1;
index(t,:)=0;
answ(t,j)=1;
end
end
end %对 while(sum(sum(index)))
%处理过程
%计数器:计算ans中1的个数,用num表示
num=sum(sum(answ));
% 判断是否可以终止,若可以则跳出循环
if(s==num)
break;
end
%否则,进行下一步处理
%确定未被划线的最小元素,用m表示
m=max(max(a));
for i=1:s
for j=1:s
if(flag(i,j)==0)
if(a(i,j)<m)
m=a(i,j);
end
end
end
end
%未被划线,即flag=0处减去m;线交点,即flag=2处加上m
for i=1:s
for j=1:s
if(flag(i,j)==0)
a(i,j)=a(i,j)-m;
end
if(flag(i,j)==2)
a(i,j)=a(i,j)+m;
end
end
end
end %对while(num~=s)
%计算最优(min)值
zm=answ.*b;
z=0;
z=sum(sum(zm));
disp('answ');
disp(answ);
disp('z');
disp(-z);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: