分支限界法运动员最佳配对实验总结Word下载.docx
- 文档编号:22011817
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:17
- 大小:19.85KB
分支限界法运动员最佳配对实验总结Word下载.docx
《分支限界法运动员最佳配对实验总结Word下载.docx》由会员分享,可在线阅读,更多相关《分支限界法运动员最佳配对实验总结Word下载.docx(17页珍藏版)》请在冰豆网上搜索。
intq;
coutcin>
>
k;
cout>
q;
while
{cout}cin>
MinPath;
}
init.houtput;
constintsize=00;
constintinf=1000;
//两点距离上界置为1000
constintn=12;
//图顶点个数加1
2/23
intprev[n];
//图的前驱顶点
intdist[]=
{0,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf};
//最短距离数组
intc[n][n]={{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,2,3,4,inf,inf,inf,inf,inf,inf,inf},
{0,inf,0,3,inf,7,2,inf,inf,inf,inf,inf},
{0,inf,inf,0,inf,inf,9,2,inf,inf,inf,inf},
{0,inf,inf,inf,0,inf,inf,2,inf,inf,inf,inf},
{0,inf,inf,inf,inf,0,inf,inf,3,3,inf,inf},
{0,inf,inf,inf,inf,inf,0,1,inf,3,inf,inf},
{0,inf,inf,inf,inf,inf,inf,0,inf,5,1,inf},
{0,inf,inf,inf,inf,inf,inf,inf,0,inf,inf,3},
{0,inf,inf,inf,inf,inf,inf,inf,inf,0,inf,2},
{0,inf,inf,inf,inf,inf,inf,inf,inf,2,inf,2},
{0,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,0},};
//矩阵
CirQueue.h
classMinHeapNode//创建极小堆用来存储活结点表
public:
inti;
//顶点编号
3/23
intlength;
//当前路长
};
classCirQueue//循环队列
private:
图的邻接
intfront,rear;
//头指针和尾指针
MinHeapNodedata[size];
public:
CirQueue//初始化建空队列
front=rear=0;
voidqueryIn//元素入队操作{
if%size!
=front)//队列未满{rear=%size;
//
插入新的队尾元素data[rear]=e;
//在队尾插入元素}
voidqueryOut//元素出队操作
if
front=%size;
//删除队头元素}
4/23
MinHeapNodegetQuery//读取队头元素,但不出队{
returndata[%size];
returndata[1];
运动员最佳配对问题
羽毛球队有男女运动员各n人.给定两个n×
n得矩阵P和Q.
P[i][j]是男运动员i和女运动员j配对组成混合双打的运动员竞赛优势.
Q[i][j]是女运动员i和男运动员j配合的女运动员竞赛优势.
由于技术配合和心理状态等各种因素影响,P[i][j]不一定等于Q[i][j].
男运动员i女运动员j配合组成混合双打的男女双方竞赛优势为P[i][j]×
Q[j][i].
设计一个算法,计算男女运动员最佳配对法,使各组男女双方竞赛优势的总和达到最大.
此题目的解空间显然是一棵排列树,可以套用搜索排列树的回溯法框架:
5/23
voidbacktrack
ifcompute;
else
for
swap;
backtrack;
voidcompute
inttemp=0;
temp+=p[i][r[i]]*q[r[i]][i];
best=temp;
bestr[i]=r[i];
6/23
无和集问题
设S是正整数集合。
S是一个无和集当且仅当x,y属于S,蕴含x+y不属于S。
对于任意正整数k,如果可将{1,2...k}划分为n个无和子集S1,S2...Sn,称正整
数k是n可分的。
记F=max{k|k是n可分的}。
试设计一个算法,对任意给定的n,计算F的值。
该题是子集选取问题,解空间显然是一棵子集树,同样可以套用搜索子集树的回溯法框架.
但是由于搜索的空间很大,用搜索时间控制搜索深度:
Boolsearch
t1=clock;
elapsed+=/double)clock_per_sec);
t0=t1;
Ifreturnfalse;
If{out;
returntrue;
for{
If{
t[dep]=I;
s[i][dep]=true;
forifsum[i][dep+j]++;
7/23
Ifreturntrue;
s[i][dep]=false;
t[dep]=0;
forifsum[i][dep+j]--;
Returnfalse;
整数变换问题
关于整数i的变换f和g。
f=3i,g=向下取整。
对于给定的两个整数m,n.要求从n变换为m。
如15,=ggfg
首先分析:
永远可以。
g操作就是对一个数字的二进制表示向ifreturnfalse;
For{
Intn1=f;
If||search{found=true;
out;
无优先级运算
#include"
stdio.h"
8/23
intn;
//给定数字的个数
inta[999];
//给定的数字
intm;
//利用给定的数字运算求出的数字mintnum[999];
intoper[999];
intflag[999];
found
intx=num[0];
switch
case0:
x+=num[i+1];
break;
case1:
x-=num[i+1];
case:
x*=num[i+1];
case:
x/=num[i+1];
}
return;
search
9/23
if)
returnfalse;
num[dep]=a[i];
flag[i]=1;
oper[dep]=j;
flag[i]=0;
10/23
main
cout>
n;
a[p];
flag[p]=0;
coutcin>
m;
cout//out;
cout}
运行:
算法设计与分析实验报告
实验报告细表
1实验题目
11/23
1.1算法设计思想
圆排列问题的解空间是一棵排列树。
按照回溯法搜索排列树的算法框架,设开始时a=[r1,r2,…,rn]是所给的N个圆的半径,则相应的排列树由a=[1:
n]的所有排列构成。
解圆的排列问题的回溯算法中circlePerm返回找到的最小圆排列长度。
初始时,数组a的输入N个圆的半径,计算结束后返回相应于最优解的圆排列。
Center用于计算当前所选择的圆在当前排列中圆心的横坐标。
compute用于计算当前圆排列的长度。
变量min用于记录当前最小圆排列的长度;
数组r表示当前圆排列;
数组x则记录当前圆排列中各圆的圆心横坐标。
算法中约定在当前圆排列中排在第一个的圆的横坐标为0。
在递归算法中bracktrack中,当i>
n时,算法搜索至叶结点,得到新的圆方案。
此时算法调用compute计算当前圆排列的长度,适时更新当前最优值。
当i1.程序源码
packageh06;
publicclassCircles{
publicintn;
//待排列圆的个数
publicfloatmin;
//当前最优值
publicfloat[]x;
//当前圆排列圆心横坐标
publicfloat[]r;
//当前圆排列
publicfloatcirclePerm{
12/23
n=nn;
r=rr;
min=1000000;
x=newfloat[n+1];
returnmin;
publicvoidbacktrack{
compute;
else{
floatcenterx=center;
if{//下界约束
x[t]=centerx;
13/23
publicvoidswap{
floattemp=r[i];
r[i]=r[j];
r[j]=temp;
publicfloatcenter{//计算当前所选择圆的圆心横坐标
floattemp=0;
floatvaluex=);
temp=valuex;
returntemp;
publicvoidcompute{//计算当前圆排列的长度
floatlow=0;
floathigh=0;
iflow=x[i]-r[i];
ifhigh=x[i]+r[i];
14/23
min=high-low;
publicstaticvoidmain{
System.out.println;
System.out.println;
intn=3;
float[]r={0,1,1,2};
//r下标从1开始,0无用,只是凑数
Circlesc=newCircles;
floatmin=c.circlePerm;
1.实验结论
1.心得体会
最后一份实验了~说说做这些报告的感受吧~
1、XX搜索代码和设计思想Ctrl+C。
2、打开工具。
3、Ctrl+V。
4、贴上上份报告的。
15/23
5、结束
总而言之,并没有加强多少对该算法的了解。
希望老师可以看看有没有更好的方式去做实验。
1)回溯法求解问题的一般思路,回溯法求解本问题的思路及其C/C++程序实现及效率分析。
回溯法求解本问题的思路:
假设男运动员已经按照1到n排好序不动,用一个数组w存放配对的女运动员的编号,即第i号男运动员配第w[i]号女运动员,初始时设w[i]=i,然后不断的重新排列w数组,每得到一次排列,就要计算在此排列下的配对总和,若发现比之前的总和大,则更新最优解。
套用排列树框架,做好初始化后开始回溯,关键在于到达叶子节点时,需要计算sum+=p[i][w[i]]*q[w[i]][i],若发现sum比之前的最优值大,则更新最优值和配对顺序,回溯完成后则可得到最大总和及其相应的运动员配对方法。
1)分支限界法求解问题的一般思路,分支限界法求解本问题的思路及其C/C++程序实现及
效率分析。
代码:
16/23
#include//文件输入输出流
#include//I/O流控制头文件
#include//vector是一个能够存放任意类型的动态数组,
//能够增加和压缩数据
usingnamespacestd;
vectorRe;
//全局变量,Re用来记录配对情况
vector>
P;
Q;
classPairUp{
friendintnPairUp;
boolPlace;
voidBacktrack;
//运动员个数
intbestsum;
vectorx;
//当前解
PairUp
{x.resize;
Re.resize;
n=c;
bestsum=b;
PairUp{}};
17/23
boolPairUp:
:
Place
{for
if//同一个男运动员和不同一个女运动员配对
returntrue;
voidPairUp:
Backtrack
{if{
intcurrentsum=0;
//第次还原为进行下次的累加
{currentsum+=*;
//累加,计算当前配对总和if//记录最大可行解
{bestsum=currentsum;
copy,x.end,Re.begin);
}}
{swap;
Backtrack;
}}
intnPairUp
{PairUpX;
//初始化X
vectorp;
18/23
p.push_back;
//当前的P数组尾部插入i的值
copy,p.end,X.x.begin);
X.Backtrack;
returnX.bestsum;
intmain{
ifstreamfin;
ofstreamfout;
intn,i,j,currentsum;
vectorr;
vectort;
fin>
r.push_back;
P.push_back;
t.push_back;
Q.push_back;
coutcoutfor
{for
{fin>
currentsum;
P.push_back;
for+1;
vr!
=r.end;
)
{vr=r.erase;
19/23
Q.push_back;
vt!
=t.end;
{vt=t.erase;
coutfor
{cout}foutreturn0;
效率分析:
回溯法用到的是递归的进行深度优先搜索整个排列树,算法中没有剪枝函数和限界函数,算法的时间复杂度为O,复杂度很高
2)分支限界法求解本问题
思路:
算法开始时创建一个最大堆,用于表示活结点优先队列堆中每个节点的val值是优先队列的优先级。
接着算法计算出图中每个顶点的最大val如果搜索到所搜索的排队树的叶子节点,算法即告结束。
20/23
int**P;
//女运动员和男运动员配对的竞赛优势
int**Q;
//男运动员和女运动员配对的竞赛优势
intbest;
//最优解
int*w;
//当前男运动员排列
classArgNode{
intx;
//arg[1:
x]已排列
intcsum;
//此种排列的竞赛优势值
ArgNode{
w=newint[n+1];
{w[i]=one.w[i];
x=one.x;
csum=one.csum;
this->
w=newint[n+1];
21/23
for{
w[i]=w[i];
x=x;
this->
csum=csum;
};
//大顶堆
booloperatorif
{returnfalse;
elsereturntrue;
voidcompute;
//计算当前节点值};
voidArgNode:
compute{
csum=0;
{csum+=P[i][w[i]]*Q[w[i]][i];
intAthletes{
//初始化
priority_queueHeap;
int*iniArr=newint[n+1];
inti=0;
{iniArr[i]=i;
ArgNode*initial=newArgNode;
deleteiniArr;
Heap.push;
22/23
while){
ArgNodefatherNode=Heap.top;
Heap.pop;
if//是一个全排列,则比较节点内值是否比当前最优值更佳{if
{best=fatherNode.csum;
for//广度优先所搜子树
{ArgNodenewNode;
//把子节点内容先复制为父节点内容++newNode.x;
//深度++
newNode.w[newNode.x]=fatherNode.w[i];
//选择第i个女选手newNode.w[i]=fatherNode.w[newNode.x];
23/23
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 分支 限界 运动员 最佳 配对 实验 总结