西工大计算机实习报告.docx

上传人:b****4 文档编号:24274746 上传时间:2023-05-25 格式:DOCX 页数:17 大小:1.04MB
下载 相关 举报
西工大计算机实习报告.docx_第1页
第1页 / 共17页
西工大计算机实习报告.docx_第2页
第2页 / 共17页
西工大计算机实习报告.docx_第3页
第3页 / 共17页
西工大计算机实习报告.docx_第4页
第4页 / 共17页
西工大计算机实习报告.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

西工大计算机实习报告.docx

《西工大计算机实习报告.docx》由会员分享,可在线阅读,更多相关《西工大计算机实习报告.docx(17页珍藏版)》请在冰豆网上搜索。

西工大计算机实习报告.docx

西工大计算机实习报告

计算机实习报告

1、趣味题

彩色的圆环:

分析图形可知,一共有n个同心圆,外面大圆n等分,然后从每个等分点作所有同心圆的两条切线。

如果用极坐标表示,可以很容易求解切点,代码如下所示:

n=10;%同心圆数量

m=40;%等分点数

R=1;%外圆半径

s=0:

0.01*pi:

2*pi;%控制圆的光滑程度的极坐标角度

t=0:

2*pi/m:

2*pi;%等分点极坐标角度

x0=R*cos(t);y0=R*sin(t);%等分点直角坐标

color=['b','r','c','g','m','y'];%画图颜色

lc=length(color);%颜色数量长度,超出后从头开始

fori=1:

n%开始同心圆循环

r=R/n*i;%当前同心圆半径

a=acos(r/R);%切线与圆心线角度(弧度制)

x1=r*cos(t-a);y1=r*sin(t-a);%任意等分点相对当前同心圆的第一个切点

x2=r*cos(t+a);y2=r*sin(t+a);%任意等分点相对当前同心圆的第二个切点

plot(r*cos(s),r*sin(s),color(mod(i,lc)+1));holdon;%画同心圆

forj=1:

m%对每一个等分点循环plot([x0(j),x1(j)],[y0(j),y1(j)],color(mod(i,lc)+1));holdon;

%第一条切线

plot([x0(j),x2(j)],[y0(j),y2(j)],color(mod(i,lc)+1));holdon;

%第二条切线

end

end

axsiequal;%横纵坐标比例一致

实验绘图结果如下图所示:

2、算法题

求无向图的最短路径(Dijkstra算法):

实验原理分析、原理及代码如下所示(此实验代码不仅包含了实验所要求的求带权无向图最短路径,我还拓展了求有向、无向、带权有向图最短路径的内容):

#include

#include

usingnamespacestd;

#definewuqiong0

classtu

{

public:

intchazhao(int);//查找

voidzjdingdian(intx);//增加顶点

tu();

voidzengjia();//控制增加弧边和点

voidzjhubian();//增加弧边

voidbianli();//控制遍历

voidshendu(int);//深度

voidguangdu(int);//广度

voidjindui(int);//进队列

intchudui();//出对了

boolpankong();//判空

//上面所有的函数与邻接矩阵有关

voidzxgouzao();//初始化与最小路劲有关的东东

voidzxshuchu();//求S中的最小路劲

private:

intkind;//类图;

intlength;//顶点个数

int*dingdian;//顶点

int*juzhen;//矩阵

intnum;//最大顶点数目

int*visted;//访问情况

int*duilie;//模拟队列

intduichang;//队列长度

//上面所有的变量与邻接矩阵有关

int*s;//存放当前顶点

intslength;//当前顶点的长度

 

int*dist;//存放最小路劲

int*pre;//存放路劲;

int*final;//存放顶点

};

tu:

:

tu()//初始化图

{

cout<<"请输入图的种类1:

有向.2:

无向.3:

带权有向.4:

带权无向"<

cin>>kind;

cout<<"请输入图的顶点数目"<

cin>>num;

dingdian=newint[num];//为顶点分配内存保存

juzhen=newint[num*num];//产生矩阵

if(kind==1||kind==2)//为无权图初始化矩阵

{

for(inti=0;i

juzhen[i]=0;

}

else//有权图初始化矩阵

{

for(inti=0;i

juzhen[i]=wuqiong;

}

length=0;

}

//增加顶点

voidtu:

:

zjdingdian(intx)

{

if(chazhao(x)!

=-1||length==num)

cout<<"图内有此顶点或图内无空间可插入,插入失败"<

else

{

dingdian[length]=x;

length++;

}

}

//增加边

voidtu:

:

zjhubian()

{

inti;//弧头

intj;//弧尾

if(kind==1||kind==2)//无权图

{

cout<<"请输入弧的头和尾"<

cin>>i>>j;

if(kind==1)//有向图

{

juzhen[i*num+j]=1;

}

else//无向图,两边同时取值

{

juzhen[i*num+j]=1;

juzhen[j*num+i]=1;

}

}

else//权值,同上,将1改为K(权值)即可

{

intk;

cin>>i>>j>>k;

if(kind==3)

{

juzhen[i*num+j]=k;

}

else

{

juzhen[i*num+j]=k;

juzhen[j*num+i]=k;

}

}

}

//查找,将该数所在位置返回,若无则返回-1

inttu:

:

chazhao(intx)

{

for(inti=0;i

if(x==i)

returni;

return-1;

}

//控制遍历函数

voidtu:

:

bianli()//遍历函数

{

cout<<"该图的邻接矩阵为:

";

inti;

intj;

for(i=0;i

{

cout<

for(j=0;j

cout<

}

cout<

visted=newint[length];//为设置访问状态定义内存空间

cout<<"深度搜索:

";

for(i=0;i

visted[i]=0;

shendu(0);//将0作为0点运用深度访问函数

 

cout<

cout<<"广度搜索:

";

for(i=0;i

visted[i]=0;

duilie=newint[length+1];

duilie[0]=-1;//队列初始化

duichang=0;

guangdu(0);//将0作为0点运用广度访问函数

}

//深度遍历

voidtu:

:

shendu(intx)//采用递归的手法

{

intp;

visted[x]=1;//访问后置1防止重复访问

cout<

p=x*length+1;

while(p%length!

=0)

{

if(juzhen[p]!

=0&&visted[p%length]!

=1)shendu(p%length);

p++;

}

}

//广度遍历

voidtu:

:

guangdu(intx)

{

intp;

visted[x]=1;

cout<

p=length*x+1;

while(p%length!

=0)//没有遍历属于根节点的后代的所有兄弟结点加入到队列中(这样可以先进先出,后来的子代加入后也是先输出父亲结点)

{

if(juzhen[p]!

=0&&visted[p%length]!

=1)

{

visted[p%length]=1;//判断是否已经加入队列或访问

jindui(p%length);

}

p++;//进行下一个判断

}

while(pankong())//加入所有的子代兄弟节点后现在出队列并且访问,访问的方式一致会访问后优先加入其子代结点然后出队列访问

{

guangdu(chudui());

}

}

//进队列,在队头插入一个函数,这个出队入队为了广度输出

voidtu:

:

jindui(intx)

{

duilie[duichang+1]=-1;

duilie[duichang]=x;

duichang++;

}

//出队列,将队列中的最后一个数返回

inttu:

:

chudui()

{

intj;

j=duilie[0];

for(inti=0;i

duilie[i]=duilie[i+1];

duichang--;

returnj;

}

//判空函数,函数为空的时候返回0

booltu:

:

pankong()

{

if(duichang==0)

returnfalse;

else

returntrue;

}

 

//控制增加函数

voidtu:

:

zengjia()

{

intj;

for(inti=0;i

zjdingdian(i);

cout<<"请输入需要增加的弧数(最少"<

cin>>j;

cout<<"请输入弧的头和尾和权值"<

for(i=0;i

{

//cout<<"插入第"<

zjhubian();

}

}

/*

**算法思想:

依次递增序列求出最小路劲,首先将顶点加入到S当中(本程序默认为0号顶点),然后用dist数组保存到每一个顶点的最小路径长度

**dist起始为顶点到其他顶点的权值(到自身为0,到无弧顶点为无穷大)

**1:

然后每次取v0-vk(k属于V-S)最小的路劲长度,取完之后将Vk加入S当中。

**2:

重新对所有的dist[i(属于v-s的i)]赋值,如果新加入的那个点到i的权值小于原来的权值则dist[i]=dist[k]+wki;

**重复1,2知道S=V;退出程序

*/

voidtu:

:

zxgouzao()//最短路径求解

{

intn,i;//n为顶点

n=0;

final=newint[length];//访问状态

s=newint[length];//所求的顶点集合

dist=newint[length];//所有的最短路径

pre=newint[length];//每一个最短路径的前驱结点(利用这个将最短路径求出)

for(i=0;i

{

pre[i]=n;//起初全部将前驱赋为源点

final[i]=0;//访问状态为0(即没有加入S当中)

if(i==n)//源点自身的dist为0

dist[i]=0;

else

dist[i]=juzhen[n*length+i];//源点到目标顶点的dist初始化为权值

}

pre[n]=-1;//源点前驱设为-1

s[0]=dingdian[0];//加入源点(本程序默认源点为0)

final[0]=1;//源点加入S当中

slength=1;//S的长度为1

inth,h1;//定义两个要用到的变量

while(slength

{

h=wuqiong+1;//首先将路劲设置成最大化,这样就可以将所有的路劲比较一番而后取最小值,这个值尽量比所有的权值要大!

for(i=0;i

{

if(!

final[i]&&dist[i]<=h)//依次对任意顶点进行判断是否已经加入S当中,如果没加入则判断他的路劲是否最小,取最小路劲

{

h=dist[i];

h1=i;

}

}

s[h1]=h1;//取完之后将其保存到S当中

slength++;//S的长度+1

final[h1]=1;//h1已经访问了加入到S当中,将其设为0

for(i=0;i

{

if(!

final[i]&&dist[h1]+juzhen[h1*length+i]

{

dist[i]=dist[h1]+juzhen[h1*length+i];

pre[i]=h1;

}

}

}

zxshuchu();//循环完毕,算法执行完毕,将最小路径输出

}

//输出函数

voidtu:

:

zxshuchu()

{

inti,pr;//循环变量I,以及目标点PR

cout<

int*p=newint[length];//定义一个保存最短路径的栈

inttop;//栈顶

cout<<"所有的最短路径为↓"<

for(i=1;i

{

top=0;//栈顶初始化0

cout<<"到"<

";

pr=i;

while(pr!

=-1)//如果pr的前驱不为-1(即pr!

=源点)则输出pr并且将pr赋为他的前驱,为-1的话说明pr这条路径已经往回走到头

{

p[top++]=pr;

pr=pre[pr];

}

while(top!

=0)//出栈,输出上面保存的路劲

{

cout<

}

cout<

}

}

 

//主函数

voidmain()

{

tua;

a.zengjia();//增加函数

a.bianli();//遍历

a.zxgouzao();//最小路径求解

}

实验结果如下图所示(其中0代表inf):

无向图一:

无向图二:

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

当前位置:首页 > 总结汇报 > 学习总结

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

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