1、3.利用子图概念,分析社会网络的结构,找出小团体和联系小团体的桥接人物。4.能查找任何人的交往圈子。5)测试数据三、概要设计1)抽象数据类型定义描述(对各类的成员及成员函数进行抽象描述,参见书或ppt及实验)ADTMgraphisData存放图中社会网络人物的一维数组vertexmaxsize存放图中社会网络人物的关系的二维数组arcmaxsizemaxsize图中人物总数vertexnum和关系总数,arcnum标志数组visitedOperationMgraph (构造函数)初始化值:社会网络中 a人员名称,n总人数,e总关系数;标志顶点访问的数组visitedi置0。 动作:将键盘输入的
2、值带入,调用有向网的创建函数CreateHW。CreateHW(创建有向网)输入:图的人数和关系数、存放图中人的数组、存放图中关系的数组前置条件:构造函数调用功能:创建有向网输出:无后置条件:有向网建立PrintGraph(输出邻接矩阵)有向网已经建立输出邻接矩阵邻接矩阵Centre(核心人物)有向网已经建立,设定核心人物的域值yu=20找出社会网络的核心人物(计算每个顶点的入度,找度数大于域值的人物)若找到则输出社会网络的核心人物,没有找到则输出“无”。Huoyue(活跃人物)有向网已经建立,设定活跃人物的域值yu=10找出社会网络的活跃人物(计算每个顶点的出度,找度数大于域值的人物)若找到
3、则输出社会网络的活跃人物,没有找到则输出“无”。Bianyuan(边缘人物)有向网已经建立,设定边缘人物的域值yu=5找出社会网络的边缘人物(计算每个顶点的出入度之和,找度数小于域值的人物)若找到则输出社会网络的边缘人物,没有找到则输出“无”。quanzi(交往圈子)输入一个人员的数字代码(用于查找该人员的交往圈子)查找交往圈子(与指定人物之间有边的人物就是与该人物有联系的,这些人就构成了一个交往圈子)。输出指定人物的交往圈子ADD(计算人员两两间的关系数)有向网已经建立,给出两个人物的数字代码计算指定人员两两间的联系数并返回(为查找小团体、桥接人做准备)返回指定人员两两间的联系数BY(返回边
4、缘人物数字代码)找边缘人物并返回该人物数字代码(为查找小团体、桥接人做准备)返回边缘人物的数字代码DFS(小团体)有向网、ADD函数、BY函数都已经建立,初始化顶点标记矩阵(全部置0)查找小团体,从指定的顶点开始进行深度优先遍历(如果当前人物没有被访问过,并且也不是边缘人物,输出该人物;再从该人物开始进行深度遍历,如果找到与该人物交往密切的人物则输出,继续找下一个)输出小团体对访问过的顶点置1DFS2(桥接人)有向网、ADD函数、BY函数都已经建立查找桥接人,从指定的顶点开始进行深度优先遍历两个小团体中,有联系,但没有达到域值的人物end ADT Mgraph2)功能模块设计(如主程序模块设计
5、)1. 主程序模块:连接各种功能子模块,完成程序的基本操作实现功能2. 构造社会网络模块:按照要求构建有向网3. 输出邻接矩阵模块:根据用户输入的社会网络,输出该网络图的邻接矩阵4. 核心人物模块:根据用户输入的社会网络,计算得出该社会网络中的核心人物5. 活跃人物模块:根据用户输入的社会网络,计算得出该社会网络中的活跃人物6. 边缘人物模块:根据用户输入的社会网络,计算得出该社会网络中的边缘人物7. 交往圈子模块:根据用户输入的社会网络,计算得出该网络中指定人物的交往圈子8. 人物两两联系数模块:根据用户输入的社会网络,返回指定人员两两间的联系数9. 判断边缘人物模块:根据用户输入的社会网络
6、,返回边缘人物的数字代码10. 小团体模块:根据用户输入的社会网络,深度优先遍历得出该网络中的所有小团体11. 桥接人物模块:根据用户输入的社会网络,深度优先遍历得出小团体间的桥接人物3)模块层次调用关系图四、详细设计实现概要设计中定义的所有的类的定义及类中成员函数,并对主要的模块写出伪码算法。#includestdlib.hstring.hconst int maxsize=100;const int INFINITY=0;/最大值无穷定义一个Mgraph类,用来实现基本功能:构造函数初始化值,根据用户输入的社会网络图构建有向网(邻接矩阵存储形式),查找该社会网络中的核心人物、活跃人物、边缘
7、人物、小团体、桥接人物,查找任何人的交往圈子。templateclass Mgraph public: Mgraph(T a,int n,int e);/构造函数,a结点数组,n顶点个数,e边数 void PrintGraph();/输出邻接矩阵 void centre(int n); /核心人物成员函数 void huoyue(int n);/活跃人物成员函数 void bianyuan(int n);/边缘人物成员函数 void quanzi(int v); /查找交往圈子函数 int ADD(int s,int t) ;/计算人员两两间联系数 int BY(int n) ; void D
8、FS(int v,int n) ; /查找小团体函数(深度优先遍历) void DFS2(int v,int n) ; /查找桥接人函数(深度优先遍历) private: T vertexmaxsize;/存放顶点 int arcmaxsizemaxsize; /存放边 int vertexnum,arcnum;/顶点数,边数 void CreateHW(T a,int n,int e);/构建有向网 int *visited;Mgraph 构造函数标志顶点访问的数组visitedi置0;调用有向网的创建函数CreateHW。Mgraph:Mgraph(T a,int n,int e) vis
9、ited=new intvertexnum; for(int i=0;ivertexnum;i+) visitedi=0; CreateHW(a,n,e); /创建/CreateHW 构建有向网将用户输入的值带入,并完成存储:人物名称放入一维数组vertexi,人物间的Email发送数(权值)放入二维数组arci-1j-1。template void MgraphCreateHW(T a,int n,int e) int w; /权值 vertexnum=n; /顶点数 arcnum=e; /边数 int i,j,k; cout 注意!请将人名对应到数字代码输入endl; 输入格式为:人员1
10、人员2 权值 for (i=0; i i+) vertexi=ai;/顶点数组赋初值(放入一维数组) i+) /初始化邻接矩阵 for (j=0; j j+) arcij=0; for (k=0; karcnum; k+) /依次输入每一条边,并修改邻接矩阵的相应元素 cout请输入第k+1ijw; /边依附的两个顶点的序号 arci-1j-1=w; /置有边标志,存放权值 /PrintGraph 输 出通过二重循环输出社会网络对应的邻接矩阵存储图PrintGraph()/输出邻接矩阵 int i,j; for(i=0;i+) for(j=0;jj+)arcijt coutyu) coutve
11、rtexi count+ ; if(count=0) cout cout/bianyuan边缘人物若人物收到和发出的Email总数小于5封,我认为就是边缘人物,所以我设置了域为5,bianyuan函数要完成的功能是找入度与出度之和小于域值的人物,并输出。bianyuan(int n) int zmaxsize=0;i+)/计算每个顶点的度数j+) zi=zi+arcij+arcji; /zi存放入度+出度之和边缘人物是: int yu=5; /找度数小于域值的人物, 域=5 if(zi/quanzi查找交往圈子根据用户输入的一个人员的数字代码,查找该人员的交往圈子,我认为与指定人物之间有边的人
12、物就是与该人物有联系的,这些人就构成了一个交往圈子。quanzi(int v) int count=0;vertexv-1的交往圈子是: for (int j=0; if (arcv-1j!=INFINITY|arcjv-1!=INFINITY) /交往圈子:与指定人物之间有边就算vertexj count+; if(count=0) cout/ADD 计算人员间两两间联系数int Mgrapht) temp=s; s=t; t=temp; else return (arcst+arcts);/BY 查找小团体中用来判断边缘人物BY(int n) int i,j,count=0;n; / 域=
13、5 if(zi return(i); if(count=0) return(99);/DFS 查找小团体查找小团体,从指定的顶点(我设置的是0也就是第一个人)开始进行深度优先遍历(如果当前人物A没有被访问过,并且也不是边缘人物,输出该人物A;再从该人物A开始进行深度遍历,如果找到与该人物交往密切的人物B则输出,再从B开始继续找下一个),并且在查找过程中输出小团体成员。DFS(int v,int n) /v控制递归 n为总人数 if (v=0)/如果是第一次使用 for (int k=0;kk+) visitedk=0; /初始化顶点标记矩阵(全部置0 代表没有访问过) DFS(v+1,n);
14、/利用递归算法重复调用深度优先遍历DFS else if (visitedv-1=0)/如果当前人物没有被访问过 if(v-1!=BY(n)/并且也不是边缘人物 int yu=10; /域值 coutyu)/如果两个结点之间交往 密切 DFS(k+1,n); /找下一个 , DFS(v+1,n); else DFS(v+1,n);/DFS2 查找桥接人查找桥接人,两个小团体中,有联系,但没有达到域值的人物。从指定的顶点开始进行深度优先遍历DFS2(int v,int n) /v控制递归 n为总人数 for (int k=v-1; if (ADD(v-1,k)0 & ADD(v-1,k)yu &
15、 v-1!=BY(n)& k!=BY(n)/如果两个结点之间有边但交往不密切,并且分别属于两个小团体 vertexk/输出桥接人结点的值 DFS2(k+1,n); /找下一个 if (v char *a=new charn; /a是指针,a的值是新建数组的首地址,a0,a1等请依次输入人员名称: cinai;请输入该社会网络的关系总数:e; Mgraph G(a,n,e);以下是该社会网络对应的邻接矩阵: G.PrintGraph();*社会网络分析中*: G.centre(n); G.huoyue(n); G.bianyuan(n);小团体是: G.DFS(0,n);联系小团体的桥接人物是:
16、 G.DFS2(1,n);请输入一个人员的数字代码(用于查找该人员的交往圈子):m; G.quanzi(m);五、调试分析 (包括调试过程中遇到的问题及解决的方法、算法的时间空间复杂性分析、经验体会)问题&改进&补充:【问题1】:小团体和桥接人的理解与定义小团体:小团体就是由交往比较密切的一群人构成的,因此要设一个域值,email数据(权值)超过这个域值才能算交往密切;一个人不能单独构成一个小团体,小团体至少要2个成员组成。桥接人:桥接人就是联系两个小团体的中间人,也就是说一个小团体可以通过对应的桥接人和另外一个小团体取得联系,桥接人分属于两个不同的团体。【问题2】:参数传递问题 目的是在一个
17、成员函数里调用另一个成员函数中的数据,一开始想到的是将代码段直接复制,但考虑到效率的问题,没有使用;然后想到了利用全局变量,但又觉得不妥;后来问了老师,老师建议我使用参数传递的方法,将需要的数据带回。于是做了如下修改:主函数中,增加char team2020; 并将G.DFS(0); 改成G.DFS(0,n,team);使DFS查找小团体的函数中,可以使用主函数中的数据n总人数;使桥接人的函数中,可以使用DFS查找小团体的函数中的二维数组:team2020【问题3】:递归调用中的数据存储为了实现桥接人的查找,要将小团体储存到一个二维数组中,在递归调用中存入数组真的不是一件简单的事,初始化数组的下标就是一件很麻烦的事情,因为递归调用每一次都会调用函数本身,若在函数体里面初始化数组下标的话,每调用一次,就会归零。解决方法:使用参数传递,将数组下标作为两个参数,每次调用时都将其传回,这样可以保证数组下标有效完成计数的功能。主函数中,将G.DFS(0,n,team); 改成G.DFS(0,n,team,0,0)头文件中,改成void DFS(int v,int n,char team2020,int i,int j)【改进1】:createHW 构建有向网中,原本老师PPT上演示的是:arcij=1; arcji=1;之后改进为 :a
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1