西工大计算机实习报告.docx
- 文档编号:24274746
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:17
- 大小:1.04MB
西工大计算机实习报告.docx
《西工大计算机实习报告.docx》由会员分享,可在线阅读,更多相关《西工大计算机实习报告.docx(17页珍藏版)》请在冰豆网上搜索。
西工大计算机实习报告
计算机实习报告
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): 无向图一: 无向图二:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 西工大 计算机 实习 报告