圆排列问题Word格式.docx

上传人:b****4 文档编号:17387157 上传时间:2022-12-01 格式:DOCX 页数:10 大小:16.62KB
下载 相关 举报
圆排列问题Word格式.docx_第1页
第1页 / 共10页
圆排列问题Word格式.docx_第2页
第2页 / 共10页
圆排列问题Word格式.docx_第3页
第3页 / 共10页
圆排列问题Word格式.docx_第4页
第4页 / 共10页
圆排列问题Word格式.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

圆排列问题Word格式.docx

《圆排列问题Word格式.docx》由会员分享,可在线阅读,更多相关《圆排列问题Word格式.docx(10页珍藏版)》请在冰豆网上搜索。

圆排列问题Word格式.docx

compute用于计算当前圆排列的长度

变量min用于记录当前最小圆排列的长度;

数组r表示当前圆排列;

数组x则记录当前圆排列中各圆的圆心横坐标

算法中约定在当前圆排列中排在第一个的圆的横坐标为0

  在递归算法中bracktrack中

当i>

n时

算法搜索至叶结点

得到新的圆方案

此时算法调用compute计算当前圆排列的长度

适时更新当前最优值

  当i<

当前扩展结点位于排列树的第I-1层

此时算法选择下一个要排列的圆

并计算相应的下界函数

在满足下界约束的结点处

以深度优先的方法递归地对相应子树搜索

对于不满足结点的结点

则剪去相应的子树

三、程序

/*********************************

*程序名

版本:

*开发日期:

2005.10.24

*简要说明:

将N个大小不等的圆排进一矩形中

且各圆与矩形框底边相切

从所有

排列中找出最小长度的圆排列

***********************************/

#include"

math.h"

//预编译

iostream.h"

#defineN100//宏定义

voidSwap(float&

a,float&

b)//交换两个值

{

intt;

t=a;

a=b;

b=t;

}

classCircle

{

friendfloatCirclePerm(int,float*);

//定义友好类

public:

//定义公共子函数

floatCenter(intt);

voidCompute(void);

voidBacktrack(intt);

//定义变量

floatmin,//当前最优值

*x,//当前圆排列圆心横坐标

*r;

//当前圆排列

intn;

//待排列的圆的个数

};

 

/*******************************************

*函数名:

Circle:

:

Center

*传入值:

当前要排列圆的半径

*输出值:

当前所选圆的圆心横坐标

*简要说明:

计算当前所选圆的圆心横坐标

*******************************************/

floatCircle:

Center(intt)//计算当前所选圆的圆心横坐标

floattemp=0;

for(intj=1;

j<

t;

j++)

{

floatvaluex=x[j]+2*sqrt(r[t]*r[j]);

cout<

<

"

shuchuv"

<

endl;

valuex<

if(valuex>

temp)temp=valuex;

}

returntemp;

Circle:

Compute

当前搜索圆的横坐标和半径

当前搜索圆排列的长度

计算当前圆排列的长度

voidCircle:

Compute(void)//计算当前圆排列的长度

floatlow=0,high=0;

for(inti=1;

i<

=n;

i++)

if(x[i]-r[i]<

low)low=x[i]-r[i];

if(x[i]+r[i]>

low)high=x[i]+r[i];

}

if(high-low<

min)min=high-low;

endl<

shumin"

;

min<

Backtrack

1

当前圆排列的最优值

查找当前最优值

Backtrack(intt)//查找当前最优值

{

if(t>

n)Compute();

else

for(intj=t;

=n;

Swap(r[t],r[j]);

r[t]<

r[j]<

floatcenterx=Center(t);

if(centerx+r[t]+r[1]<

min)

x[t]=centerx;

Backtrack(t+1);

jiaohuaner:

"

;

r[t]<

r[j]<

CirclePerm

n

a

当前找到的圆的最小长度

计算找到的最小圆排列长度

floatCirclePerm(intn,float*a)//计算找到的最小圆排列长度

CircleX;

X.n=n;

X.r=a;

X.min=100000;

float*x=newfloat[n+1];

//申请空间

X.x=x;

X.Backtrack

(1);

delete[]x;

//释放空间

returnX.min;

main

圆排列的最小长度

调用各个子程序

输出所有

排列中找出最小长度

voidmain(void)

//定义变量

floata[N],k;

intm,n;

yuangeshu:

cin>

>

n;

for(m=1;

m<

m++)

a[m];

k=CirclePerm(n,a);

shuchuzuixiaomin"

k<

endl;

四、与圆排列随机化算法的比较

解圆排列问题的一个随机化算法如下.

voidCircle_search(int*x)

random_perm(x);

found=true;

while(found){

found=false;

for(inti=1;

i<

=n;

i++)

for(intj=1;

j<

j++)

if(swap(x[i],x[j])reduceslength){

swap(x[i],x[j]);

其中,random_perm(x)产生x的一个随机排列

定义圆排列类

classCircle{

friendfloatCirclePerm(int,float*);

//返回找到的最小圆排列长度

private:

voidCenter(void);

//计算当前所有的圆在当前圆排列中圆心的横坐标

floatCompute(void);

//计算当前圆排列的长度

voidShuffle(void);

//随机洗牌算法

voidCircleSearch(void);

//解圆排列随机算法

floatmin,//当前最优值

result,//最优值

*x,//当前圆排列圆心横坐标

*r;

//当前圆排列

intn;

//等排列圆的个数

随机洗牌

Shuffle(void)

staticRandomNumberrnd;

for(inti=0;

iintj=rnd.Random(n-i)+i;

Swap(r[i],r[j]);

解圆排列随机算法

CircleSearch(void)

{Shuffle();

Center();

min=Compute();

boolfound=true;

ifor(intj=0;

jSwap(r[i],r[j]);

floatlength=Compute();

if(lengthmin=length;

elseSwap(r[i],r[j]);

}

返回找到的最小圆排列长度

floatCirclePerm(intn,float*a)

{CircleX;

X.n=n;

X.r=a;

float*x=newfloat[n];

iX.x=x;

X.CircleSearch();

X.result=X.min;

for(i=1;

iX.min){

delete[]x;

returnX.result;

五、算法效率比较

  设循环次数为k;

圆排列随机化算法函数Center(void)计算时间需O(n2);

函数Circle:

CircleSearch(void)计算时间需O(n4);

整个算法时间复杂度O(Kn4)

圆排列问题的回溯算法在最坏情况下时间复杂度为O((n+1)!

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1