课程设计算法设计与分析 飞行员配对问题.docx
《课程设计算法设计与分析 飞行员配对问题.docx》由会员分享,可在线阅读,更多相关《课程设计算法设计与分析 飞行员配对问题.docx(6页珍藏版)》请在冰豆网上搜索。
课程设计算法设计与分析飞行员配对问题
吉林财经大学
算法设计与分析课程设计
专业:
计算机科学与技术
学号:
姓名:
一·课设内容分析
1)问题描述
第二次世界大战时期,英国皇家空军从沦陷国征募了大量外籍飞行员。
由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2名飞行员,其中1名是英国飞行员,另1名是外籍飞行员。
在众多的飞行员中,每一名外籍飞行员都可以与其他若干名英国飞行员很好地配合。
如何选择配对飞行的飞行员才能使一次派出最多的飞机。
对于给定的外籍飞行员与英国飞行员的配合情况,试设计一个算法找出最佳飞行员配对方案,使皇家空军一次能派出最多的飞机。
2)问题分析
基础的二分图最大匹配问题。
给定一个二分图G,M为G边集的一个子集,如果M满足当中的任意两条边都不依附于同一个顶点,则称M是一个匹配。
极大匹配是指在当前已完成的匹配下,无法再通过增加未完成匹配的边的方式来增加匹配的边数。
最大匹配是所有极大匹配当中边数最大的一个匹配。
选择这样的边数最大的子集称为图的最大匹配问题。
如果一个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配,也称作完备匹配。
求二分图最大匹配可以用最大流或者匈牙利算法。
3)建模方法
在二分图的基础上增加源S和汇T。
(1):
S向X集合中每个顶点连一条容量为1的有向边。
(2):
Y集合中每个顶点向T连一条容量为1的有向边。
(3):
XY集合之间的边都设为从A集合中的点到B集合之中的点,容量为1的有向边。
4)建模分析
基本的二分图最大匹配,可以直接用匈牙利算法或Hopcroft_Karp算法解决,更一般的方法是网络最大流。
求网络最大流,流量就是匹配数,所有满流边是一组可行解。
可行解的输出:
枚举所以边,如果u∈X,v∈Y,并且满流,那么当前边为可行解的一组匹配。
二·课程设计目的
通过课程设计,提高用计算机解决实际问题的能力,提高独立实践的能力,将课本上的理论知识和实际有机的结合起来,锻炼分析解决实际问题的能力。
提高结合实际的编程能力。
在实际的编程和调试综合试题的基础上,把高级语言程序设计的思想、编程巧和解题思路进行总结与概括,通过比较系统地练习达到真正比较熟练地掌握计算机编程的基本功,为后续的学习打下基础。
最重要的事培养自己的理性思维,无论是在编程还是在以后的工作生活中养成一个良好的思维习惯。
三·算法原理及思路
运用数学上的短除法让一个整数对二取余,然后再让这个整数除以二,取整数部分,然后继续对二取余,如此继续循环,中间只要对二取余的结果是一,就累加一次,直到该整数最后为零,最后把累加的结果输出,就是该整数转换成二进制数后里面有多少个一。
四·源代码
#include
#include
#include
#include
#definemaxn10020
#defineINF100000000
usingnamespacestd;
intn,m,s,t,tot,ans,d[maxn],head[maxn],dist[maxn];
structE
{
intfrom;
intto;
intnext;
inttab;
}edge[maxn];
voidadd_edge(intu,intv,intf)
{
tot++;
edge[tot].from=u,edge[tot].to=v,edge[tot].tab=f,edge[tot].next=head[u],head[u]=tot;
tot++;
edge[tot].from=v,edge[tot].to=u,edge[tot].tab=0,edge[tot].next=head[v],head[v]=tot;
}
intmin(inta,intb)
{
if(a>b)
returnb;
else
returna;
}
intdfs(intx,intlow)
{
inta;
if(x==t)
returnlow;
for(inti=head[x];i!
=-1;i=edge[i].next)
if(edge[i].tab>0&&dist[edge[i].to]==dist[x]+1&&(a=dfs(edge[i].to,min(edge[i].tab,low))))
{
edge[i].tab-=a,edge[i^1].tab+=a;
returna;
}
return0;
}
intbfs()
{
intl,r,k;
memset(dist,0xff,sizeof(dist));
d[0]=0;
d[1]=s;
l=0,r=1;
dist[s]=0;
while(l{
k=d[++l];
for(inti=head[k];i!
=-1;i=edge[i].next)
if(edge[i].tab>0&&dist[edge[i].to]<0)dist[edge[i].to]=dist[k]+1,d[++r]=edge[i].to;
}
if(dist[t]>0)return1;elsereturn0;
}
voiddinic()
{
ans=0;
while(bfs())
ans+=dfs(0,INF);
}
voidprint()
{
if(ans==0)
{
printf("NoSulotion\n");
return;
}
printf("%d\n",ans);
for(inti=0;i<=tot;i+=2)
if(edge[i].tab==0&&edge[i].from!
=s&&edge[i].to!
=t)printf("%d%d\n",edge[i].from,edge[i].to);
}
intmain()
{
FILE*file=NULL;
file=fopen("data/air0.in","r");
if(file==NULL)
{
cout<<"don'topenthefile"<exit(0);
}
intx,y,i;
memset(head,0xff,sizeof(head));
tot=-1;
while(fscanf(file,"%d%d",&m,&n)!
=EOF)
{
s=0,t=n+1;
for(i=1;i<=m;i++)
add_edge(0,i,1);
for(i=m+1;i<=n;i++)
add_edge(i,t,1);
while(fscanf(file,"%d%d",&x,&y)!
=EOF)
{
if(x==-1&&y==-1)
break;
else
add_edge(x,y,1);
}
dinic();
print();
}
return0;
}
五·个人总结
在这次课程设计的学习中,我学到了很多,也找到了自己身上的不足。
感受良多,获益匪浅。
在课程设计的过程中,经历了奋斗的酸甜苦辣。
分享了成功的喜悦。
这次的课程设计对我来说是一个挑战。
课程设计中文档的撰写我从来就没有担心过,就是代码的编写我真的很担心,平时对这方面的知识的就不是很扎实。
所以在这次的课程设计中,刻意的去锻炼了自己的宏观分析能力,无论是在前期的命题分析,还是在代码的编写,以及最终的调试和排错上,都一步一步的按照既定的规则与步奏,也是慢慢的克服了自己心急,粗心的习惯,养成了看待问题的缜密性思维。
总之,这次的课程设计让我获益良多,将会使我终身受益。