WS小世界网络模型构造算法

/***********************************************************************************************************************
 * WS小世界模型构造算法:
 * 		(1)从规则图开始:给定一个含有N个节点的环状最近邻耦合网络,
 * 		     其中的每个节点都与它左右相邻的各K/2个节点相连,K是偶数。
 * 		(2)随机化重连:以概率p随机的重新连接网络中的原有的每一条边,
 * 		     即把每一条边的一个端点保持不变,另外一个端点改取网络中随机
 * 		     选择的另外的一个端点,其中规定不可以有自连和重边。
 *
 * 	Note: p = 0对应于完全规则网络,p = 1对应于完全的随机网络。通过调整p的值可以实现从规则网络
 * 	       到随机网络的过渡。在具体的算法的实现时,可以把网络中的所有的节点编号为1,2,3,..N,对于
 * 	       每一个节点 i ,顺时针的选取与 i 相连的K/2条边中的每一条,边的一个端点仍然固定为i,以
 * 	       概率p随机的选取网络中的任一节点作为该边的另一端点。
 ***********************************************************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define NETWORK_SIZE 	100	//网络的大小
#define K		6	//最近邻耦合网络中的K,表明:每一个节点和左右相邻的各K/2个节点相连。K是偶数
#define P		0.3	//以概率p决定是否要对原来的边进行随机的重连

int adjacentMatrix[NETWORK_SIZE + 1][NETWORK_SIZE + 1];
void generate_NearestNeighborCoupledNetwork();
void generateSmallWorld();
void writeDataToFile();

int main(){
	srand((unsigned)time(NULL));
	generate_NearestNeighborCoupledNetwork();
	generateSmallWorld();
	writeDataToFile();
	return 0;
}

/*
 * 首先产生最邻近藕合网络:每一个节点和他的左右各K/2个节点相连
 * */
void generate_NearestNeighborCoupledNetwork(){
	int i;
	int j;
	for( i = 1; i <= NETWORK_SIZE; i++ )
	{
		for( j = 1; j <= NETWORK_SIZE; j++ )
		{
			adjacentMatrix[i][j] = 0;
		}
	}
	for( i = 1; i <= NETWORK_SIZE; i++ )
	{
		for( j = 1; j <= K/2; j++ )
		{
			if( i - j >= 1 && i + j <= NETWORK_SIZE )
			{
				adjacentMatrix[i][i - j] = 1;
				adjacentMatrix[i][i + j] = 1;
			}
			else if( i - j < 1 )
			{
				adjacentMatrix[i][NETWORK_SIZE + i - j] = 1;
				adjacentMatrix[i][i + j] = 1;
			}
			else if( i + j > NETWORK_SIZE )
			{
				adjacentMatrix[i][i + j - NETWORK_SIZE] = 1;
				adjacentMatrix[i][i - j] = 1;
			}
		}
	}
	//test
	/*
	for( i = 1; i <= NETWORK_SIZE; i++ )
	{
		for( j = 1; j <= NETWORK_SIZE; j++ )
		{
			printf("%d ", adjacentMatrix[i][j]);
		}
		printf("\n");
	}
	*/
	//test END
}

/*
 * 构造WS小世界模型
 * */
void generateSmallWorld(){
	int i;
	int j;
	double isChange = 0.0;			//随机产生的0~1之间的数,决定是否要对选择的边进行重连,当isChange<p时,进行重连
	int re_connectRandomNode;		//在决定了要重连某一条边时,随机的选择一个将要连接到的端点(不可以是本身,不可以是重边)
	int hasEage[NETWORK_SIZE + 1];		//用于在选择另外一个节点进行重连的时候,判断是否重边,以及是否随机选择了自身
	int number_changedEage = 0;
	for( i = 1; i <= NETWORK_SIZE; i++ )
	{
		for( j = 1; j <= K/2; j++ )
		{
			//重连的边是:adjacentMatrix[i][i + j]; 或者: adjacentMatrix[i][i + j - NETWORK_SIZE];
			isChange = (rand()%NETWORK_SIZE)/(double)NETWORK_SIZE;
			//printf("(%d, %d)random probability is %f\n", i, i+j, isChange);
			if( isChange < P )	//重连
			{
				while( 1 )	//随机选择一个端点:不可以产生自连和重边
				{
					re_connectRandomNode = (rand() % NETWORK_SIZE) + 1;
					if( adjacentMatrix[i][re_connectRandomNode] == 0 && re_connectRandomNode != i )
						break;
				}
				if( i + j <= NETWORK_SIZE )
				{
					adjacentMatrix[i][i + j] = 0;
					adjacentMatrix[i + j][i] = 0;
				}
				else	//i + j > NETWORK_SIZE
				{
					adjacentMatrix[i][i + j - NETWORK_SIZE] = 0;
					adjacentMatrix[i + j - NETWORK_SIZE][i] = 0;
				}
				adjacentMatrix[i][re_connectRandomNode] = 1;
				adjacentMatrix[re_connectRandomNode][i] = 1;
				number_changedEage++;
			}
			else
			{
				//printf("(%d, %d) no change\n", i, i+j);
			}	
		}
	}
	//test
	printf("------------Small World NetWork------------------\n");
	for( i = 1; i <= NETWORK_SIZE; i++ )
	{
		for( j = 1; j <= NETWORK_SIZE; j++ )
		{
			printf("%d", adjacentMatrix[i][j]);
		}
		printf("\n");
	}
	printf("the number of changed eage is %d, ratio is %f\n", number_changedEage, (double)number_changedEage/(NETWORK_SIZE * K / 2));
}

/*
 * 将产生的小世界网络的adjacentMatrix写入文件中
 * */
void writeDataToFile(){
	FILE* fout;
	int i;
	int j;
	if( NULL == (fout = fopen("smallWorldNetwork.data", "w")))
	{
		printf("open file(smallWorldNetwork.data) error!");
		exit(0);
	}
	for( i = 1; i <= NETWORK_SIZE; i++ )
	{
		for( j = 1; j <= NETWORK_SIZE; j++ ){
			fprintf(fout, "%d ", adjacentMatrix[i][j]);
		}
		fprintf(fout,"\n");
	}
	fclose(fout);
}

以下是计算小世界网络聚类系数的代码片段:

/*
 * 计算小世界网络模型的聚类系数
 * */
double clusterArray[NETWORK_SIZE + 1];
double calculateCluter(){
	int i;
	int j;
	int k = 1;
	int t, n;
	int numberOfNeighbor = 0;
	int* neighborArray;
	int cluster = 0;
	double finalcluster = 0.0;
	for( i = 1; i <= NETWORK_SIZE; i++ )
	{
		numberOfNeighbor = 0;
		cluster = 0;
		k = 1;
		for( j = 1; j <= NETWORK_SIZE; j++ )
		{
			if( adjacentMatrix[i][j] == 1 )
			{
				numberOfNeighbor++;
			}
		}
		neighborArray = (int*)malloc(sizeof(int)*(numberOfNeighbor + 1));
		if( neighborArray == NULL )
		{
			printf("malloc error!\n");
			exit(0);
		}
		//记录了i的邻居有哪些
		for( j = 1; j <= NETWORK_SIZE; j++ )
		{
			if( adjacentMatrix[i][j] == 1 )
			{
				neighborArray[k++] = j;
			}
		}
		//test
		/*
		for( j = 1; j <= numberOfNeighbor; j++ )
			printf("%d ", neighborArray[j]);
		printf("\n");
		*/
		//testEND
		for( t = 1; t < numberOfNeighbor; t++ )
		{
			for( n = t + 1; n <= numberOfNeighbor; n++ )
			{
				if( adjacentMatrix[neighborArray[t]][neighborArray[n]] == 1 )
					cluster++;
			}
		}
		//printf("%d\n", cluster);
		clusterArray[i] = cluster/(double)(numberOfNeighbor * (numberOfNeighbor - 1) / 2);
		free(neighborArray);
	}
	
	for( i = 1; i <= NETWORK_SIZE; i++ )
		finalcluster += clusterArray[i];
	finalcluster = finalcluster/(double)NETWORK_SIZE;
	//test
	/*
	printf("print cluster of all node is \n");
	for( i = 1; i <= NETWORK_SIZE; i++ )
	{
		printf("%f\t", clusterArray[i]);
	}
	*/
	//test END
	return finalcluster;
}



你可能感兴趣的:(c,WS小世界模型构造算法,聚类稀疏计算代码)