SI疾病传播模型实现

1852人阅读 评论(0)

SI传播模型的C语言实现（完整代码见下）

@sourceNode为疾病的传播源

@rateOfInfection为疾病的传播概率

void SI(int sourceNode, double rateOfInfection)
{
int i, j;
double probability_infected = 0.0;
int clock = 1;
int stop = 0;
int I_nodes, S_neighbors, count1, count2,temp_I_array_length, temp_S_array_length;
int rand_infected_node_index, rand_infected_node_id, rand_sus_node_index, rand_sus_node_id;
I_nodes = S_neighbors = count1 = count2 = 0;
int* I_node_array;
int* S_neighbor_array;

infected_sequences[sourceNode].S_or_I = infected_sequences[sourceNode].times = 1;
infected_sequences[sourceNode].from = 0;

while(1)
{
clock++;                                        //记录感染时间
I_nodes = 0;                                        //记录被感染的节点的个数
for( i = 1; i <= network_size; i++ )
if( infected_sequences[i].S_or_I )
I_nodes++;
if( !(I_node_array = (int*)malloc(sizeof(int) * (I_nodes + 1))) )
{
printf("malloc I_node_array* error\n");
exit(0);
}
count1 = 1;
for( i = 1; i <= network_size; i++ )
if( infected_sequences[i].S_or_I )
I_node_array[count1++] = i;                        //构造已经被感染的节点的集合

temp_I_array_length = I_nodes;
for( i = 1; i <= I_nodes; i++ )
{
rand_infected_node_index = rand() % temp_I_array_length + 1;            //随机选择已经感染的节点
rand_infected_node_id = I_node_array[rand_infected_node_index];
I_node_array[rand_infected_node_index] = I_node_array[temp_I_array_length--];

S_neighbors = 0;
for( j = 1; j <= network_size; j++ )                        //统计已感染节点的没有感染的邻居节点个数
if( adjacentMatrix[rand_infected_node_id][j] && !( infected_sequences[j].S_or_I ) )
S_neighbors++;
if( S_neighbors == 0 )
continue;
if( !(S_neighbor_array = (int*)malloc(sizeof(int) * (S_neighbors + 1))) )
{
printf("malloc S_neighbor_array* error\n");
exit(0);
}
int count2 = 1;
for( j = 1; j <= network_size; j++ )
if( adjacentMatrix[rand_infected_node_id][j] && !( infected_sequences[j].S_or_I ) )
S_neighbor_array[count2++] = j;

temp_S_array_length = S_neighbors;
for( j = 1; j <= S_neighbors; j++ )
{
//随机选择没有感染的节点进行传播
rand_sus_node_index = rand() % temp_S_array_length + 1;
rand_sus_node_id = S_neighbor_array[rand_sus_node_index];
S_neighbor_array[rand_sus_node_index] = S_neighbor_array[temp_S_array_length--];

probability_infected = (double)(rand() % 1000) / (double)1000;
if( infected_sequences[rand_sus_node_id].S_or_I = probability_infected < rateOfInfection ? 1 : 0 )
{
infected_sequences[rand_sus_node_id].times = clock;
infected_sequences[rand_sus_node_id].from = rand_infected_node_id;
}
}
free(S_neighbor_array);
S_neighbor_array = NULL;
}
free(I_node_array);
I_node_array = NULL;

stop = 0;
for( i = 1; i <= network_size; i++ )
stop += infected_sequences[i].S_or_I;
if( network_size == stop )
break;
}

//可以输出到文件进行保存
//printf("SI process:\n");
//printf("node id   :");for( i = 1; i <= network_size; i++ )printf("%5d", i);printf("\n");
//printf("node times:");for( i = 1; i <= network_size; i++ )printf("%5d", infected_sequences[i].times);printf("\n");
//printf("node from :");for( i = 1; i <= network_size; i++ )printf("%5d", infected_sequences[i].from);printf("\n");
}


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>

int network_size;
int edges_size;
double rateOfInfection;
char filename[100];

typedef struct{
int S_or_I;	//标记该节点是否被感染
int times;	//记录该节点的感染时间
int from;	//记录该节点的感染来源
}SI_Node;
SI_Node* infected_sequences;

void init();
void SI(int sourceNode, double rateOfInfection);
void saveSIResult();

int main(int argc, char** argv)
{
if( argc != 6 )
{
printf("This algorithm require 3 paramenters\n");
printf("\t1.network size(vertaies number)\n");
printf("\t2.edges size\n");
printf("\t3.propagation probability\n");
printf("\t4.file name contain edges information\n");
printf("\t5.the source node ID\n");
printf("\t\texample: a.exe 332 2126 0.5 edgesForSIModel.data 255\n");
exit(0);
}
srand((unsigned)time(NULL));
network_size = atoi(argv[1]);
edges_size = atoi(argv[2]);
rateOfInfection = atof(argv[3]);
strcat(filename, argv[4]);
int sourceID = atoi(argv[5]);
printf("show information of input: network_size: %d,edges number: %d,propagation probability: %f,file name: %s, source node ID: %d\n", network_size, edges_size, rateOfInfection, filename, sourceID);

init();
SI(sourceID, rateOfInfection);
saveSIResult();
return 0;
}

void init()
{
int i, j;
if( !(adjacentMatrix = (short**)malloc(sizeof(short*) * (network_size + 1))) )
{
exit(0);
}
for( i = 1; i <= network_size; i++ )
{
if( !(adjacentMatrix[i] = (short*)malloc(sizeof(short) * (network_size + 1))) )
{
exit(0);
}
}
for( i = 1; i <= network_size; i++ )
for( j = 1; j <= network_size; j++ )
if( !(infected_sequences = (SI_Node*)malloc(sizeof(SI_Node) * (network_size + 1))) )
{
printf("infected_sequences* malloc error");
exit(0);
}
for( i = 1; i <= network_size; i++ )
infected_sequences[i].S_or_I = infected_sequences[i].times = infected_sequences[i].from = 0;
}

/*
* 	大多数的真实网络给出的形式为source target,在这里进行转化为邻接矩阵
* */
{
int i, j, source, target;
source = target = 0;
if( NULL == (fread = fopen(filename, "r")) )
{
printf("open file error");
exit(0);
}
for( i = 1; i <= edges_size; i++ )
{
if( 2 != fscanf(fread, "%d %d", &source, &target) )
{
printf("fscanf error: %d", i);
exit(0);
}
}
/*
for( i = 1; i <= network_size; i++ )
{
for( j = 1; j <= network_size; j++ )
printf("\n");
}
*/
}

/*
* 	使用SI模型进行传播
* */
void SI(int sourceNode, double rateOfInfection)
{
int i, j;
double probability_infected = 0.0;
int clock = 1;
int stop = 0;
int I_nodes, S_neighbors, count1, count2,temp_I_array_length, temp_S_array_length;
int rand_infected_node_index, rand_infected_node_id, rand_sus_node_index, rand_sus_node_id;
I_nodes = S_neighbors = count1 = count2 = 0;
int* I_node_array;
int* S_neighbor_array;

infected_sequences[sourceNode].S_or_I = infected_sequences[sourceNode].times = 1;
infected_sequences[sourceNode].from = 0;

while(1)
{
clock++;										//记录感染时间
I_nodes = 0;										//记录被感染的节点的个数
for( i = 1; i <= network_size; i++ )
if( infected_sequences[i].S_or_I )
I_nodes++;
if( !(I_node_array = (int*)malloc(sizeof(int) * (I_nodes + 1))) )
{
printf("malloc I_node_array* error\n");
exit(0);
}
count1 = 1;
for( i = 1; i <= network_size; i++ )
if( infected_sequences[i].S_or_I )
I_node_array[count1++] = i;						//构造已经被感染的节点的集合

temp_I_array_length = I_nodes;
for( i = 1; i <= I_nodes; i++ )
{
rand_infected_node_index = rand() % temp_I_array_length + 1;			//随机选择已经感染的节点
rand_infected_node_id = I_node_array[rand_infected_node_index];
I_node_array[rand_infected_node_index] = I_node_array[temp_I_array_length--];

S_neighbors = 0;
for( j = 1; j <= network_size; j++ )						//统计已感染节点的没有感染的邻居节点个数
if( adjacentMatrix[rand_infected_node_id][j] && !( infected_sequences[j].S_or_I ) )
S_neighbors++;
if( S_neighbors == 0 )
continue;
if( !(S_neighbor_array = (int*)malloc(sizeof(int) * (S_neighbors + 1))) )
{
printf("malloc S_neighbor_array* error\n");
exit(0);
}
int count2 = 1;
for( j = 1; j <= network_size; j++ )
if( adjacentMatrix[rand_infected_node_id][j] && !( infected_sequences[j].S_or_I ) )
S_neighbor_array[count2++] = j;

temp_S_array_length = S_neighbors;
for( j = 1; j <= S_neighbors; j++ )
{
//随机选择没有感染的节点进行传播
rand_sus_node_index = rand() % temp_S_array_length + 1;
rand_sus_node_id = S_neighbor_array[rand_sus_node_index];
S_neighbor_array[rand_sus_node_index] = S_neighbor_array[temp_S_array_length--];

probability_infected = (double)(rand() % 1000) / (double)1000;
if( infected_sequences[rand_sus_node_id].S_or_I = probability_infected < rateOfInfection ? 1 : 0 )
{
infected_sequences[rand_sus_node_id].times = clock;
infected_sequences[rand_sus_node_id].from = rand_infected_node_id;
}
}
free(S_neighbor_array);
S_neighbor_array = NULL;
}
free(I_node_array);
I_node_array = NULL;

stop = 0;
for( i = 1; i <= network_size; i++ )
stop += infected_sequences[i].S_or_I;
if( network_size == stop )
break;
}

//可以输出到文件进行保存
//printf("SI process:\n");
//printf("node id   :");for( i = 1; i <= network_size; i++ )printf("%5d", i);printf("\n");
//printf("node times:");for( i = 1; i <= network_size; i++ )printf("%5d", infected_sequences[i].times);printf("\n");
//printf("node from :");for( i = 1; i <= network_size; i++ )printf("%5d", infected_sequences[i].from);printf("\n");
}

/*
* 	用于gephi作图
* */
void saveSIResult()
{
int i, j;
FILE *fNodeInfo, *fEdgeInfo;
if( NULL == (fNodeInfo = fopen("nodeInfo.csv", "w")) )
{
printf("nodeInfo.csv open error");
exit(0);
}
if( NULL == (fEdgeInfo = fopen("edgeInfo.csv", "w")) )
{
printf("edgeInfo.csv open error");
exit(0);
}
//节点和节点的感染时间
fprintf(fNodeInfo, "id,label,color\n");
for( i = 1; i <= network_size; i++ )
fprintf(fNodeInfo, "%d,%d,%d\n", i, i, infected_sequences[i].times);
fclose(fNodeInfo);

fprintf(fEdgeInfo, "source,target\n");
for( i = 1; i <= network_size; i++ )
{
for( j = i + 1; j <= network_size; j++ )
{
if( adjacentMatrix[i][j] && infected_sequences[i].from == j )
{
//printf("%d --> %d\n",j, i);
fprintf(fEdgeInfo, "%d,%d\n", j, i);
}else if( adjacentMatrix[i][j] && infected_sequences[j].from == i )
{
//printf("%d --> %d\n", i, j);
fprintf(fEdgeInfo, "%d,%d\n", i, j);
{
//printf("%d --- %d\n", i, j);
fprintf(fEdgeInfo, "%d,%d\n", i, j);
}
}
}
fclose(fEdgeInfo);
}


0
0

个人资料
• 访问：219612次
• 积分：3189
• 等级：
• 排名：第12760名
• 原创：95篇
• 转载：0篇
• 译文：0篇
• 评论：65条
最新评论