首页 > 其他 > 详细

进行试验,对比

时间:2020-04-16 23:11:16      阅读:45      评论:0      收藏:0      [点我收藏+]

一.参考的对比:

技术分享图片

 

 

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<malloc.h>#include<math.h>#include<time.h>#define MaxVertexNum 90000#define RAND_MAX 0x7fff //边表节点typedef struct node{int adjvex;struct node *next;int visit;}EdgeNode;//顶点表节点typedef struct vnode{int vertex;int KS;//k-corefloat ec;//特征向量中心性int is_infected;int nodeState;int is_visit;int layer;//层int degree;//该节点的度EdgeNode* firstedge;//指向边表的指针}VertexNode;typedef VertexNode AdjList[MaxVertexNum];//图的结构typedef struct{AdjList adjlist;//顶点表(类似于数组的)int vexnum;//顶点个数int arcnum;//边个数}ALGraph;//返回文件行数(网络边数),有换行符"\n"就为一行int lines(char* str){int c;FILE* fp;int lines=0;fp=fopen(str,"r");if(fp){while((c=fgetc(fp))!=EOF)if(c==‘\n‘)lines++;fclose(fp);}return lines;}//返回文件最大数(网络节点数)int max(char* str){FILE* fp;char* p;int line=lines(str);int i=0;int a=0;int b=0;fp=fopen(str,"r");char buf[1024];if((fp=fopen(str,"r"))==NULL){perror("fail to read");exit(1);}//把文件的内容给buf
while(fgets(buf,line,fp)!=NULL){

//p就没有p=buf;sscanf(p,"%d %d",&a,&b);//输入源为p
//i始终为最大的if(a>i)i=a;if(b>i)i=b;}
return i;}//创建图void createAlgraph(ALGraph*  G,char* str){FILE* fp;int line=lines(str);int node=max(str);//其中最大数G->vexnum=node+1;//因为是从0开始,所以+1,多了一个0 G->arcnum=line;fp=fopen(str,"r");char buf[1024];int len;int m;int n;EdgeNode* s;char* p;int a=0;int b=0;int i=0;char StrLine[1024];//每个节点的顶点表(vn1(i),vn2(i))int vn1[line];//这里本来要用vn[line],如果是vc++就不能通过编译,有多少行就有多少(i,j)int vn2[line];//顶点录入for(int j=0;j<G->vexnum;j++){G->adjlist[j].vertex=j;G->adjlist[j].firstedge=NULL;G->adjlist[j].nodeState=1;}if((fp=fopen(str,"r"))==NULL){perror("faile to read");exit(1);}
while(!feof(fp))//因为行数等于边数,则读取行数个就可以把其他的节点的连接读完{
fgets(StrLine,1024,fp);sscanf(StrLine,"%d%d",&a,&b);
vn1[i]=a;vn2[i]=b;i++;}
//边节点放入链表//一行就是一个坐标,有多少行就有多少坐标 for(int k=0;k<line;k++)//有多少行就有多少节点,每个节点对应一个边链{m=vn1[k],n=vn2[k];int ii=0;EdgeNode* p;p=G->adjlist[m].firstedge;while(p!=NULL){if(p->adjvex==n){ii=1;break;}p=p->next;}if(ii!=1){s=(EdgeNode*)malloc(sizeof(EdgeNode));s->adjvex=n;//相连接的顶点s->next=NULL;s->next=G->adjlist[m].firstedge;//类似于自己写的链表 G->adjlist[m].firstedge=s;//无向图 有来回s=(EdgeNode*)malloc(sizeof(EdgeNode));s->adjvex=m;s->next=NULL;s->next=G->adjlist[n].firstedge;G->adjlist[n].firstedge=s;}}//深度为每个节点后面连接的链长度EdgeNode* q;for( i=0;i<G->vexnum;i++){int k=0;q=G->adjlist[i].firstedge;while(q!=NULL){k++;q=q->next;}G->adjlist[i].degree=k;}}//打印邻接表void printGraph(ALGraph* G){EdgeNode* s;for(int i=0;i<G->vexnum;i++){s=G->adjlist[i].firstedge;//s为一个带adjvex,next指针的边表节点 while(s){printf("(%d,%d)",G->adjlist[i].vertex,s->adjvex);s=s->next;}printf("\n");}}//所属层插入void insertLayer(ALGraph* G,int layer){for(int i=0;i<G->vexnum;i++){G->adjlist[i].layer=layer;}}//打印度中心性void printDegreeCentrality(ALGraph* G){for(int i=0;i<G->vexnum;i++){printf("node %d dgree centrality is:%d\n",i,G->adjlist[i].degree);}}

//计算特征向量中心性void eigenvector_centrality(ALGraph *G){    float e[G->vexnum];//记录上一次的指标(最终的特征向量中心性指标 ,因为会把最终的计算赋值给e);下面都用指标代表特征向量指标    float e1[G->vexnum];//记录这一次的指标     float max = 0;//这一次的最大指标     float max1 = 0;//记录上一次最大指标     int  flag=0;//当flag=1时,代表找到各个指标     for(int i=0; i<G->vexnum; i++)    {        e[i]=1;//将每个点初始化为1         e1[i]=0;    }    EdgeNode *p;    p=(EdgeNode*)malloc(sizeof(EdgeNode));    //循环开始     while(flag==0)    {        max1=max;//max1为上一次的最大值         max=0;        for (int i=0; i<G->vexnum; i++)        {            p=G->adjlist[i].firstedge;            while(p!=NULL)            {                e1[i]+=e[p->adjvex];//第一次的计算结果为他们各自的度                 p=p->next;            }            if(e1[i]>max)                max=e1[i];//记录本次的最大指标         }        for(int i=0; i<G->vexnum; i++)        {            if(e[i]!=e1[i])                break;            if(i==G->vexnum-1)                flag=1;//两次计算结果相同结束循环         }        if((1.0/max1-1.0/max)<0.01&&(1.0/max1-1.0/max)>-0.01)            flag=1;//当差值较小时也可结束循环             //保留这次的结果到e中,并且将ei重置为0,方便下次计算         for(int i=0; i<G->vexnum; i++)        {            e[i]=e1[i];             e1[i]=0;        }    }    for(int i=0; i<G->vexnum; i++)    {        e[i]=e[i]/max;        G->adjlist[i].ec=e[i];    }}/*1.SIR传播模型,改变node.state(0为感染,1为易感染,2为恢复。所有节点初始化为1) 2.SIR函数主要操作感染点,感染点会做两件事:①感染易感节点;②感染节点恢复 3.传播完成的标志为不能再感染新的节点,并返回处于恢复节点的个数 */void SIR1(ALGraph* G,int a,double inf,double rec,char* str)//传入的分别为网络,感染节点,感染率,恢复率,写入的文件 {double rate;//传入节点作为感染节点的感染规模 int i=0;int sum=0;//统计100次传播后的结果 FILE* fp;fp=fopen(str,"at"); //所有节点最开始为易感态 for(int k=0;k<100;k++){int Inf[G->vexnum];int newInf[G->vexnum];int recnum=0;//统计传播结束后,处于恢复状态的节点个数for(i=0;i<G->vexnum;i++){G->adjlist[i].nodeState=0;} //给感染节点赋值 G->adjlist[a].nodeState=1;//传入的j节点a为感染态 //把感染节点交给数组 Inf[0]=a;double infection=inf;//感染概率 int count=1;//当前网络中的感染个数srand((unsigned)time(NULL)); //设置种子,用于随机数产生 while(count>0)//还能继续感染 {int newInfLength=0;//表示新感染节点的个数 //节点感染 for(i=0;i<count;i++){int vert=Inf[i];//当前的感染点 EdgeNode* p;p=G->adjlist[vert].firstedge;//用当前节点去感染其他节点while(p!=NULL){int n=0; double infect_rate;//感染的概率为1-(1-λ)^n;其中λ为感染率,n为周围节点是感染者的个数 double test=rand()/(double)RAND_MAX;//rand()产生随机数为[1,32767],RAND_MAX设置为32767,那么test范围[0.1] ; //计算nint nodej=p->adjvex;//记录当前连接的节点//用s查看当前连接节点的周围有多少感染者 EdgeNode* s=G->adjlist[nodej].firstedge;while(s!=NULL){if(G->adjlist[s->adjvex].nodeState==1){n++;}s=s->next;} //计算感染率infect_rate infect_rate=1.0-pow(1.0-infection,n);//如果随机数比感染概率小(能感染),且节点状态为易感染,就感染该节点 if(test<=infect_rate&&G->adjlist[nodej].nodeState==0){newInf[newInfLength]=nodej;G->adjlist[nodej].nodeState=1;//被感染 newInfLength++;}p=p->next; } }//感染节点恢复(不包括上一步新感染的) for(i=0;i<count;i++) { double recovRate=rec; double test_1=rand()/(double)RAND_MAX;//rand()产生随机数为[1,32767],RAND_MAX设置为32767,那么test范围[0.1]  //此处当恢复率设置为1时所有感染节点都能恢复  //恢复分两种情况:1.能恢复,改变nodeState为2;2.不能恢复,放入新感染数组  if(test_1<=recovRate) { G->adjlist[Inf[i]].nodeState=2;  }   else  {  newInf[newInfLength]=Inf[i];  newInfLength++;  } } //newInf数组中元素两个来源:1.易感染节点被感染;2.感染节点未恢复  //再把新感染的数组newInf交给Inf进行下一次循环 for(i=0;i<newInfLength;i++) { Inf[i]=newInf[i];   }    count=newInfLength;//记录当前新感染的个数,作为继续循环的依据 }for(i=0;i<G->vexnum;i++){if(G->adjlist[i].nodeState==2){recnum++;} } sum+=recnum;// //重置所有会节点状态 ,作为下一轮感染准备 // recnum=0;//// Inf[G->vexnum]={0};////newInf[G->vexnum]={0};//for(i=0;i<G->vexnum;i++)//{//G->adjlist[i].nodeState=;// }  }   rate=(sum*1.0)/(G->vexnum*100); fprintf(fp,"%d    %lf     %lf\n",G->adjlist[a].degree,G->adjlist[a].ec,rate);//重置所有节点的node.statefclose(fp);return;}
void SIR(ALGraph *G,char* str,double beta){//0:易感染 1:感染 2:恢复     double gama=1.0;    srand(time( NULL ));    int sum_of_recovered;    int sum_of_infected;    FILE *fp;    fp=fopen(str,"w");    for(int node=0;node<G->vexnum;node++)    {        printf("%d  ",node);        int sum=0;        for(int k=0; k<100; k++)        {            sum_of_recovered =0;            //先把所有节点设置为易感染             for(int i=0; i<G->vexnum; i++)                G->adjlist[i].is_infected=0;                //最初那个节点设置为感染             G->adjlist[node].is_infected=1;            sum_of_infected=1;            //下面的while中一轮一轮的把所有节点进行感染             while(1)            {            //记录所有节点的感染状态                 int temp[G->vexnum];                for(int i=0; i<G->vexnum; i++)                    temp[i]=G->adjlist[i].is_infected;                    //下面把所有节点进行判断是否感染或易感                 for(int i=0; i<G->vexnum; i++)                {                    if(G->adjlist[i].is_infected==0)                    {                        EdgeNode *p;                        p=G->adjlist[i].firstedge;                        int count=0;//统计易感旁边感染的个数,用于计算感染的概率                         while(p!=NULL)                        {                            if(temp[p->adjvex]==1)                                count++;                            p=p->next;                        }                        double infect_rate=1-pow(1.0-beta,count);                        if(rand()/(double)RAND_MAX<=infect_rate)                        {                            G->adjlist[i].is_infected=1;                            sum_of_infected++;                        }                    }                    else if(G->adjlist[i].is_infected==1)                    {                        if(rand()/(double)RAND_MAX<=gama)                        {                            G->adjlist[i].is_infected=2;                            sum_of_infected--;                            sum_of_recovered++;                        }                    }                }                if(sum_of_infected==0)                    break;            }            sum+=sum_of_recovered;        }        double rate=(sum*1.0)/(G->vexnum*100.0);        fprintf(fp,"%d    %lf     %lf\n",G->adjlist[node].degree,G->adjlist[node].ec,rate);    }    fclose(fp);}
void DoubleNetworkSIR(ALGraph *G1,ALGraph* G2,ALGraph* G3,char* str,double beta1,double beta2) {//传入参数依次为(网络G1.连接边G2,网络G3,写入的文件,G1中的传播率,G2中的传播率) //0:易感染 1:感染 2:恢复     double gama=1.0;    srand(time( NULL ));    int sum_of_recovered;    int sum_of_infected;    FILE *fp;    fp=fopen(str,"w");    for(int node=0;node<(G1->vexnum+G3->vexnum);node++)    {        printf("%d  ",node);        int sum=0;        for(int k=0; k<100; k++)        {            sum_of_recovered =0;            //先把所有节点设置为易感染             for(int i=0; i<G1->vexnum; i++)                G1->adjlist[i].is_infected=0;            for(int i=0; i<G3->vexnum; i++)                G3->adjlist[i].is_infected=0;                //最初那个节点设置为感染(需要区分两个不同的网络)if(node<G1->vexnum)             G1->adjlist[node].is_infected=1;            else            G3->adjlist[node-(G1->vexnum)].is_infected=1;            sum_of_infected=1;            //下面的while中一轮一轮的把所有节点进行感染             while(1)            {                        //记录所有节点的感染状态                 int temp1[G1->vexnum];//G1中的感染点                 int temp2[G3->vexnum];//G3中的感染点                 for(int i=0; i<G1->vexnum; i++)                    temp1[i]=G1->adjlist[i].is_infected;                for(int i=0; i<G3->vexnum; i++)                    temp2[i]=G3->adjlist[i].is_infected;                    //下面把所有节点进行判断是否感染或易感                     //G1中的点                 for(int i=0; i<G1->vexnum; i++)                {                    if(G1->adjlist[i].is_infected==0)                    {                        EdgeNode *p;                        p=G1->adjlist[i].firstedge;                        int count1=0;//统计易感旁边感染的个数,用于计算感染的概率 (先统计自己网络的,再统计相连接网络的) ,这里为G1中的邻居 int count2=0;//统计G3中的邻居                         while(p!=NULL)                        {                            if(temp1[p->adjvex]==1)                                count1++;                            p=p->next;                        }                        //需要判断这个点是否与G3中的点相连(根据这个点是否在G2判断)  EdgeNode *s; s=G2->adjlist[i].firstedge; //如果相连,看相连G3中的点是否感染  while(s!=NULL) { if(temp2[s->adjvex]==1) count2++; s=s->next; }                        double infect_rate=1-pow(1.0-beta1,count1)*pow(1.0-beta2,count2);                        if(rand()/(double)RAND_MAX<=infect_rate)                        {                            G1->adjlist[i].is_infected=1;                            sum_of_infected++;                        }                    }                    else if(G1->adjlist[i].is_infected==1)                    {                        if(rand()/(double)RAND_MAX<=gama)                        {                            G1->adjlist[i].is_infected=2;                            sum_of_infected--;                            sum_of_recovered++;                        }                    }                }                //G3中的点                 for(int i=0; i<G3->vexnum; i++)                {                    if(G3->adjlist[i].is_infected==0)                    {                        EdgeNode *p;                        p=G3->adjlist[i].firstedge;                         int count1=0;//统计易感旁边感染的个数,用于计算感染的概率                          int count2=0;//统计G3的邻居                         while(p!=NULL)                        {                            if(temp2[p->adjvex]==1)                                count2++;                            p=p->next;                        }                        //需要判断这个点是否与G3中的点相连(根据这个点是否在G2判断)  EdgeNode *s; s=G2->adjlist[i].firstedge; //如果相连,看相连G3中的点是否感染  while(s!=NULL) { if(temp1[s->adjvex]==1) count1++; s=s->next; }                        double infect_rate=1-pow(1.0-beta1,count1)*pow(1.0-beta2,count2);                        if(rand()/(double)RAND_MAX<=infect_rate)                        {                            G3->adjlist[i].is_infected=1;                            sum_of_infected++;                        }                    }                    else if(G3->adjlist[i].is_infected==1)                    {                        if(rand()/(double)RAND_MAX<=gama)                        {                            G3->adjlist[i].is_infected=2;                            sum_of_infected--;                            sum_of_recovered++;                        }                    }                }                if(sum_of_infected==0)                    break;            }            sum+=sum_of_recovered;        }        double rate=(sum*1.0)/((G1->vexnum+G3->vexnum)*100.0);if(node<G1->vexnum)        fprintf(fp,"%d    %lf     %lf\n",G1->adjlist[node].degree,G1->adjlist[node].ec,rate);        else        fprintf(fp,"%d    %lf     %lf\n",G3->adjlist[node-(G1->vexnum)].degree,G3->adjlist[node-(G1->vexnum)].ec,rate);    }    fclose(fp);}
//创建连接的边,并写入文件void createLink(char* str){FILE* fp;fp=fopen(str,"w");srand((unsigned)time(NULL));for (int i=0;i<2000;i++){fprintf(fp,"%d    %d\n",rand()%2000,rand()%2000); //fpintf(fp,"%d    %d",rand()%2000,rand()%2000);}fclose(fp); } 
int main(){
char* str1="E:\\data_set\\netsci1.txt";//G1,网络 char* str2="E:\\data_set\\netsci2.txt";//G2,连边 char* str3="E:\\data_set\\netsci3.txt";//G3,网络  createLink(str2);//创建连边 
//G1、G3为两个网络,G2为他们的连接ALGraph* G1;ALGraph* G2;ALGraph* G3;G1=(ALGraph*)malloc(sizeof(ALGraph));G2=(ALGraph*)malloc(sizeof(ALGraph));G3=(ALGraph*)malloc(sizeof(ALGraph));//创建三个表的信息 createAlgraph(G1,str1);//分别插入图的地址,连接顶点信息createAlgraph(G2,str2);createAlgraph(G3,str3);//插入层数insertLayer(G1,1);insertLayer(G3,2);//计算特征向量中心性 eigenvector_centrality(G1);eigenvector_centrality(G3);//SIR,此处为单个节点推动 char* str4="E:\\data_set\\result.txt";//{//printf("%d ",i);//SIR1(G1,i,0.08,1,str4);//}//SIR(G1,str4,0.08); DoubleNetworkSIR(G1,G2,G3,str4,0.15,0.1);

return 0;}

进行试验,对比

原文:https://www.cnblogs.com/miaobo/p/12715924.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!