数据结构课程设计社会网络分析系统的设计和实现Word文档格式.docx

上传人:b****6 文档编号:17205316 上传时间:2022-11-28 格式:DOCX 页数:28 大小:244.56KB
下载 相关 举报
数据结构课程设计社会网络分析系统的设计和实现Word文档格式.docx_第1页
第1页 / 共28页
数据结构课程设计社会网络分析系统的设计和实现Word文档格式.docx_第2页
第2页 / 共28页
数据结构课程设计社会网络分析系统的设计和实现Word文档格式.docx_第3页
第3页 / 共28页
数据结构课程设计社会网络分析系统的设计和实现Word文档格式.docx_第4页
第4页 / 共28页
数据结构课程设计社会网络分析系统的设计和实现Word文档格式.docx_第5页
第5页 / 共28页
点击查看更多>>
下载资源
资源描述

数据结构课程设计社会网络分析系统的设计和实现Word文档格式.docx

《数据结构课程设计社会网络分析系统的设计和实现Word文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计社会网络分析系统的设计和实现Word文档格式.docx(28页珍藏版)》请在冰豆网上搜索。

数据结构课程设计社会网络分析系统的设计和实现Word文档格式.docx

3.利用子图概念,分析社会网络的结构,找出小团体和联系小团体的桥接人物。

4.能查找任何人的交往圈子。

5)测试数据

三、概要设计

1)抽象数据类型定义描述

(对各类的成员及成员函数进行抽象描述,参见书或ppt及实验)

ADT 

Mgraph 

is

Data

存放图中社会网络人物的一维数组vertex[maxsize]

存放图中社会网络人物的关系的二维数组arc[maxsize][maxsize]

图中人物总数vertexnum和关系总数,arcnum

标志数组visited

Operation

◆Mgraph(构造函数)

初始化值:

社会网络中a[]人员名称,n总人数,e总关系数;

标志顶点访问的数组visited[i]置0。

动作:

将键盘输入的值带入,调用有向网的创建函数CreateHW。

◆CreateHW(创建有向网)

输入:

图的人数和关系数、存放图中人的数组、存放图中关系的数组

前置条件:

构造函数调用

功能:

创建有向网

输出:

后置条件:

有向网建立

◆PrintGraph(输出邻接矩阵)

有向网已经建立

输出邻接矩阵

邻接矩阵

◆Centre(核心人物)

有向网已经建立,设定核心人物的域值yu=20

找出社会网络的核心人物(计算每个顶点的入度,找度数大于域值的人物)

若找到则输出社会网络的核心人物,没有找到则输出“无”。

◆Huoyue(活跃人物)

有向网已经建立,设定活跃人物的域值yu=10

找出社会网络的活跃人物(计算每个顶点的出度,找度数大于域值的人物)

若找到则输出社会网络的活跃人物,没有找到则输出“无”。

◆Bianyuan(边缘人物)

有向网已经建立,设定边缘人物的域值yu=5

找出社会网络的边缘人物(计算每个顶点的出入度之和,找度数小于域值的人物)

若找到则输出社会网络的边缘人物,没有找到则输出“无”。

◆quanzi(交往圈子)

输入一个人员的数字代码(用于查找该人员的交往圈子)

查找交往圈子(与指定人物之间有边的人物就是与该人物有联系的,这些人就构成了一个交往圈子)。

输出指定人物的交往圈子

◆ADD(计算人员两两间的关系数)

有向网已经建立,给出两个人物的数字代码

计算指定人员两两间的联系数并返回(为查找小团体、桥接人做准备)

返回指定人员两两间的联系数

◆BY(返回边缘人物数字代码)

找边缘人物并返回该人物数字代码(为查找小团体、桥接人做准备)

返回边缘人物的数字代码

◆DFS(小团体)

有向网、ADD函数、BY函数都已经建立,初始化顶点标记矩阵(全部置0)

查找小团体,从指定的顶点开始进行深度优先遍历(如果当前人物没有被访问过,并且也不是边缘人物,输出该人物;

再从该人物开始进行深度遍历,如果找到与该人物交往密切的人物则输出,继续找下一个)

输出小团体

对访问过的顶点置1

◆DFS2(桥接人)

有向网、ADD函数、BY函数都已经建立

查找桥接人,从指定的顶点开始进行深度优先遍历

两个小团体中,有联系,但没有达到域值的人物

endADTMgraph

2)功能模块设计(如主程序模块设计)

1.主程序模块:

连接各种功能子模块,完成程序的基本操作实现功能

2.构造社会网络模块:

按照要求构建有向网

3.输出邻接矩阵模块:

根据用户输入的社会网络,输出该网络图的邻接矩阵

4.核心人物模块:

根据用户输入的社会网络,计算得出该社会网络中的核心人物

5.活跃人物模块:

根据用户输入的社会网络,计算得出该社会网络中的活跃人物

6.边缘人物模块:

根据用户输入的社会网络,计算得出该社会网络中的边缘人物

7.交往圈子模块:

根据用户输入的社会网络,计算得出该网络中指定人物的交往圈子

8.人物两两联系数模块:

根据用户输入的社会网络,返回指定人员两两间的联系数

9.判断边缘人物模块:

根据用户输入的社会网络,返回边缘人物的数字代码

10.小团体模块:

根据用户输入的社会网络,深度优先遍历得出该网络中的所有小团体

11.桥接人物模块:

根据用户输入的社会网络,深度优先遍历得出小团体间的桥接人物

3)模块层次调用关系图

四、详细设计

实现概要设计中定义的所有的类的定义及类中成员函数,并对主要的模块写出伪码算法。

#include<

iostream.h>

stdlib.h>

string.h>

constintmaxsize=100;

constintINFINITY=0;

//最大值无穷

定义一个Mgraph类,用来实现基本功能:

构造函数初始化值,根据用户输入的社会网络图构建有向网(邻接矩阵存储形式),查找该社会网络中的核心人物、活跃人物、边缘人物、小团体、桥接人物,查找任何人的交往圈子。

template<

classT>

classMgraph

{

public:

Mgraph(Ta[],intn,inte);

//构造函数,a[]结点数组,n顶点个数,e边数

voidPrintGraph();

//输出邻接矩阵

voidcentre(intn);

//核心人物成员函数

voidhuoyue(intn);

//活跃人物成员函数

voidbianyuan(intn);

//边缘人物成员函数

voidquanzi(intv);

//查找交往圈子函数

intADD(ints,intt);

//计算人员两两间联系数

intBY(intn);

voidDFS(intv,intn);

//查找小团体函数(深度优先遍历)

voidDFS2(intv,intn);

//查找桥接人函数(深度优先遍历)

private:

Tvertex[maxsize];

//存放顶点

intarc[maxsize][maxsize];

//存放边

intvertexnum,arcnum;

//顶点数,边数

voidCreateHW(Ta[],intn,inte);

//构建有向网

int*visited;

};

————————Mgraph构造函数————————

标志顶点访问的数组visited[i]置0;

调用有向网的创建函数CreateHW。

Mgraph<

T>

:

Mgraph(Ta[],intn,inte)

{visited=newint[vertexnum];

for(inti=0;

i<

vertexnum;

i++)

visited[i]=0;

CreateHW(a,n,e);

//创建

}

//————————CreateHW构建有向网————————

将用户输入的值带入,并完成存储:

人物名称放入一维数组vertex[i],人物间的Email发送数(权值)放入二维数组arc[i-1][j-1]。

template<

voidMgraph<

CreateHW(Ta[],intn,inte)

{intw;

//权值

vertexnum=n;

//顶点数

arcnum=e;

//边数

inti,j,k;

cout<

<

"

注意!

请将人名对应到数字代码输入"

endl;

输入格式为:

人员1人员2权值"

for(i=0;

i<

i++)

vertex[i]=a[i];

//顶点数组赋初值(放入一维数组)

i++)//初始化邻接矩阵

for(j=0;

j<

j++)

arc[i][j]=0;

for(k=0;

k<

arcnum;

k++)

{//依次输入每一条边,并修改邻接矩阵的相应元素

cout<

请输入第"

k+1<

条边:

;

cin>

>

i>

j>

w;

//边依附的两个顶点的序号

arc[i-1][j-1]=w;

//置有边标志,存放权值

}

//———————PrintGraph输出—————————

通过二重循环输出社会网络对应的邻接矩阵存储图

PrintGraph()

{//输出邻接矩阵

inti,j;

for(i=0;

i++)

{for(j=0;

j<

j++)

arc[i][j]<

'

\t'

cout<

}

//——————centre核心人物————————

若人物收到的Email总数大于20封,我认为就是核心人物,所以我设置了域为20,centre函数要完成的功能是找入度大于域值的人物,并输出。

centre(intn)

{vertexnum=n;

inti,j,count=0;

intx[maxsize]={0};

for(j=0;

j++)//计算每个顶点的入度

x[i]+=arc[j][i];

//x[j]存放入度数

—→核心人物是:

intyu=20;

//找度数大于域值的人物,域=20

i++)

{if(x[i]>

yu)

{cout<

vertex[i]<

"

count++;

if(count==0){cout<

无"

//————————huoyue活跃人物————————

若人物发出的Email总数大于10封,我认为就是活跃人物,所以我设置了域为10,huoyue函数要完成的功能是找出度大于域值的人物,并输出。

huoyue(intn)

inty[maxsize]={0};

i++)//计算每个顶点的出度

for(j=0;

y[i]+=arc[i][j];

//y[i]存放出度数

—→活跃人物是:

intyu=10;

//找度数大于域值的人物,域=10

{if(y[i]>

{cout<

//————————bianyuan边缘人物————————

若人物收到和发出的Email总数小于5封,我认为就是边缘人物,所以我设置了域为5,bianyuan函数要完成的功能是找入度与出度之和小于域值的人物,并输出。

bianyuan(intn)

intz[maxsize]={0};

i++)//计算每个顶点的度数

j++)

z[i]=z[i]+arc[i][j]+arc[j][i];

//z[i]存放入度+出度之和

—→边缘人物是:

intyu=5;

//找度数小于域值的人物,域=5

{if(z[i]<

//————————quanzi查找交往圈子————————

根据用户输入的一个人员的数字代码,查找该人员的交往圈子,我认为与指定人物之间有边的人物就是与该人物有联系的,这些人就构成了一个交往圈子。

quanzi(intv)

{

intcount=0;

—→"

vertex[v-1]<

的交往圈子是:

for(intj=0;

{if(arc[v-1][j]!

=INFINITY||arc[j][v-1]!

=INFINITY)//交往圈子:

与指定人物之间有边就算

vertex[j]<

count++;

if(count==0){cout<

//——————ADD计算人员间两两间联系数————————

intMgraph<

ADD(ints,intt)

{inttemp;

if(s>

t)

{temp=s;

s=t;

t=temp;

elsereturn(arc[s][t]+arc[t][s]);

//—————BY查找小团体中用来判断边缘人物——————

BY(intn)

{inti,j,count=0;

n;

//域=5

{

if(z[i]<

{

return(i);

if(count==0)

return(99);

//————————DFS查找小团体————————

查找小团体,从指定的顶点(我设置的是0也就是第一个人)开始进行深度优先遍历(如果当前人物A没有被访问过,并且也不是边缘人物,输出该人物A;

再从该人物A开始进行深度遍历,如果找到与该人物交往密切的人物B则输出,再从B开始继续找下一个),并且在查找过程中输出小团体成员。

DFS(intv,intn)//v控制递归n为总人数

if(v==0)//如果是第一次使用

for(intk=0;

k<

k++)

visited[k]=0;

//初始化顶点标记矩阵(全部置0代表没有访问过)

DFS(v+1,n);

//利用递归算法重复调用深度优先遍历DFS

else

{

if(visited[v-1]==0)//如果当前人物没有被访问过

{

if(v-1!

=BY(n))//并且也不是边缘人物

{intyu=10;

//域值

cout<

//输出该结点的值

visited[v-1]=1;

//将该结点置为访问过!

for(intk=0;

{

if(ADD(v-1,k)>

yu)//如果两个结点之间交往密切

{DFS(k+1,n);

}//找下一个

}

"

DFS(v+1,n);

}

elseDFS(v+1,n);

//————————DFS2查找桥接人————————

查找桥接人,两个小团体中,有联系,但没有达到域值的人物。

从指定的顶点开始进行深度优先遍历

DFS2(intv,intn)//v控制递归n为总人数

for(intk=v-1;

if(ADD(v-1,k)>

0&

&

ADD(v-1,k)<

yu&

v-1!

=BY(n)&

k!

=BY(n))//如果两个结点之间有边但交往不密切,并且分别属于两个小团体

{

vertex[k]<

//输出桥接人结点的值

DFS2(k+1,n);

//找下一个

if(v<

=n)

DFS2(v+1,n);

}

//————————主函数————————

测试刚刚的Mgraph类中的各种成员函数是否编写正确,完成要求的功能。

voidmain()

|欢迎使用社会网络分析系统|"

intn,e,m;

//n总人数,e总关系数,m某个人员的数字代码

请输入该社会网络总人数:

cin>

char*a=newchar[n];

//a是指针,a的值是新建数组的首地址,a[0],a[1]等

请依次输入人员名称:

{cin>

a[i];

请输入该社会网络的关系总数:

e;

Mgraph<

char>

G(a,n,e);

以下是该社会网络对应的邻接矩阵:

G.PrintGraph();

******************社会网络分析中******************:

G.centre(n);

G.huoyue(n);

G.bianyuan(n);

—→小团体是:

G.DFS(0,n);

—→联系小团体的桥接人物是:

G.DFS2(1,n);

请输入一个人员的数字代码(用于查找该人员的交往圈子):

m;

G.quanzi(m);

五、调试分析

(包括调试过程中遇到的问题及解决的方法、算法的时间空间复杂性分析、经验体会)

Ø

问题&

改进&

补充:

【问题1】:

小团体和桥接人的理解与定义

小团体:

小团体就是由交往比较密切的一群人构成的,因此要设一个域值,email数据(权值)超过这个域值才能算交往密切;

一个人不能单独构成一个小团体,小团体至少要2个成员组成。

桥接人:

桥接人就是联系两个小团体的中间人,也就是说一个小团体可以通过对应的桥接人和另外一个小团体取得联系,桥接人分属于两个不同的团体。

【问题2】:

参数传递问题

目的是在一个成员函数里调用另一个成员函数中的数据,一开始想到的是将代码段直接复制,但考虑到效率的问题,没有使用;

然后想到了利用全局变量,但又觉得不妥;

后来问了老师,老师建议我使用参数传递的方法,将需要的数据带回。

于是做了如下修改:

主函数中,增加charteam[20][20];

并将G.DFS(0);

改成G.DFS(0,n,team);

使DFS查找小团体的函数中,可以使用主函数中的数据n总人数;

使桥接人的函数中,可以使用DFS查找小团体的函数中的二维数组:

team[20][20]

【问题3】:

递归调用中的数据存储

为了实现桥接人的查找,要将小团体储存到一个二维数组中,在递归调用中存入数组真的不是一件简单的事,初始化数组的下标就是一件很麻烦的事情,因为递归调用每一次都会调用函数本身,若在函数体里面初始化数组下标的话,每调用一次,就会归零。

解决方法:

使用参数传递,将数组下标作为两个参数,每次调用时都将其传回,这样可以保证数组下标有效完成计数的功能。

主函数中,将G.DFS(0,n,team);

改成G.DFS(0,n,team,0,0)

头文件中,改成voidDFS(intv,intn,charteam[20][20],inti,intj)

【改进1】:

createHW构建有向网中,

原本老师PPT上演示的是:

arc[i][j]=1;

arc[j][i]=1;

之后改进为:

a

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

当前位置:首页 > 初中教育 > 理化生

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

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