关闭

SI疾病传播模型实现

标签: SI疾病传播模型复杂网络gephi可视化
1852人阅读 评论(0) 收藏 举报
分类:

在SI疾病传播模型中,网络中的节点在任一时刻有两种可能的状态,易感态susceptible(S)和感染态infected(I)。处于易感态(S)的节点当被感染后转变为感染态(I)并且不能恢复。我们假设在t_0时刻网络中除了一个节点被感染了之外,这个节点就是传播源,其余的所有节点都处于易感态。之后传播源以一定的疾病传播概率(rates of infection)感染它的邻居,与此同时,疾病或者是信息开始在网络中传播。


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

@sourceNode为疾病的传播源

@rateOfInfection为疾病的传播概率

思路:从传播源开始,对于该传播源的所有的邻居节点,以一定的概率将疾病传染给这些邻居节点。(在传播的时候,随机选择邻居进行传播而不是按照一定的顺序,例如节点的id)。然后统计网络中所有被疾病感染的节点,对于这些节点,随机依次的选择其中的节点作为“传播源”将疾病试图传染给自己未被感染的邻居。(同样在选择邻居进行传染的时候,也是随机的挑选邻居尝试传染)。

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进行可视化

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

int network_size;
int edges_size; 
short** adjacentMatrix;
double rateOfInfection;
char filename[100];

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

void init();
void readNetworkAndTransformFormat();
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();
	readNetworkAndTransformFormat();
	SI(sourceID, rateOfInfection);
	saveSIResult();
	return 0;
}

void init()
{
	int i, j;
	if( !(adjacentMatrix = (short**)malloc(sizeof(short*) * (network_size + 1))) )
	{
		printf("adjacentMatrix** malloc error");
		exit(0);
	}
	for( i = 1; i <= network_size; i++ )
	{
		if( !(adjacentMatrix[i] = (short*)malloc(sizeof(short) * (network_size + 1))) )
		{
			printf("adjacentMatrix[%d]* malloc error");
			exit(0);
		}
	}
	for( i = 1; i <= network_size; i++ )
		for( j = 1; j <= network_size; j++ )
			adjacentMatrix[i][j] = 0;
	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,在这里进行转化为邻接矩阵
 * */
void readNetworkAndTransformFormat()
{
	int i, j, source, target;
	source = target = 0;
	FILE* fread;
	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);
		}
		adjacentMatrix[source][target] = adjacentMatrix[target][source] = 1;
	}
	fclose(fread);
	/*
	for( i = 1; i <= network_size; i++ )
	{
		for( j = 1; j <= network_size; j++ )
			printf("%d ", adjacentMatrix[i][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);
			}else if( adjacentMatrix[i][j] )
			{
				//printf("%d --- %d\n", i, j);
				fprintf(fEdgeInfo, "%d,%d\n", i, j);
			}
		}
	}
	fclose(fEdgeInfo);
}

代码中使用了USArir网络(美国航空网络,数据下载地址:http://vlado.fmf.uni-lj.si/pub/networks/data/mix/USAir97.net)。原网络为含权网路,包含332个机场和2126条航线。

下图为使用gephi可视化该网络的结果。


运行以上代码,通过输出的csv文件,可以绘制出疾病传播的趋势,黄色的节点为传播源,深红到深蓝的渐变表示感染时间的增加。即越红的节点表示越早感染,越蓝的节点表示该节点越晚被感染。


如果只是保留有疾病传播的路径那么可以得到下图



0
0
查看评论

SIR疾病传播模型理论(通俗易懂)

youtube上看的视频,然后截下图做的笔记。 视频中用的是一个学校,儿童爆发麻疹的的例子。 S是易感染的人群(即目前是健康,未感染的人), I是感染了的人群 R是感染后好了的,被移除了的人。(即不会再被感染) 他们各自的速率 由这张图可以很清楚地看到他们的关系 被移除...
  • normol
  • normol
  • 2018-01-24 20:42
  • 103

SIR模型 matlab模拟

需要一个单独的m文件: %即写上三个微分方程 function y=SIRModel(t,x,lambda,mu) y=[-lambda*x(1)*x(2),lambda*x(1)*x(2)-mu*x(2),mu*x(2)]'; 再进行作图 >> ts=0:1:100;...
  • normol
  • normol
  • 2018-01-24 21:01
  • 132

si,sisi,sir模型

  • 2014-06-25 20:49
  • 88KB
  • 下载

matlab求解常微分方程组/传染病模型并绘制SIR曲线

本文用matlab求解常微分方程组。 看了很多关于传染病模型的matlab程序,大都是绘制出两条曲线(I、S)的,本文最大的不同是绘出SIR三条曲线。 先给出SIR微分方程组       函数文件: run的程序: matlab输出: 图像输出:
  • u013159040
  • u013159040
  • 2016-04-19 14:34
  • 5568

算法提高 传染病控制

1019: 算法提高 传染病控制 时间限制: 1 Sec  内存限制: 512 MB 提交: 8  解决: 4 [提交][状态][讨论版] http://115.159.67.147/problem.php?id=1...
  • wyxeainn
  • wyxeainn
  • 2017-02-25 19:41
  • 851

【美赛·算法】SEIR 传染病模型 及其实现

SEIR是属于遗传病学的经典算法, SUSCEPTIBLES--those able to contract the disease EXPOSED--those who have been infected but are not yet infectious INFECTIVES--th...
  • u011613321
  • u011613321
  • 2015-02-11 22:56
  • 1928

传播力模型的初步探讨

    做了一个关于"传播力"的调研,下面是一部分的内容(关于整合力等子模型就不贴出了);主要有些问题,大家感兴趣的可以和偶一起讨论.我觉得这个概念还是非常有意思的,不妨再把最后的小结说明贴一下:综合三、四、五的讨论,我们基本上可以得到一个传播力模型...
  • cs_
  • cs_
  • 2007-01-18 11:00
  • 2438

复杂网络上的传播动力学

复杂网络: 复杂网络是指具有复杂阔普结构和动力学行为的大规模网络,它是由大量的节点通过边的相互连接而构成的图。 经典传播模型: SIR模型、SIS模型 其中,S指Susceptible,易感者;I指Infective,感染者;R指Recoved或Removed,不同的地方不同的叫法。 经典...
  • wu18663419760
  • wu18663419760
  • 2017-01-15 22:36
  • 772

Codevs 1091 传染病控制

1091 传染病控制 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 【问题背景】 近来,一种新的传染病肆虐全球。蓬莱国也发现了零星感染者,为防止该病在蓬莱国 大范围流行,该国政府决定不惜一切代价控制传染病的蔓延。...
  • qq_35776409
  • qq_35776409
  • 2017-03-30 08:00
  • 202

《改进SIR 模型在社交网络信息传播中的应用》仿真实现

摘要基于《改进SIR 模型在社交网络信息传播中的应用》一文中提出的改进SIR模型,使用Matlab进行了仿真实现。另外,基于原文的模型,依据实际话题热度进行了其它仿真和分析。背景信息在社交网络中的传播方式与传染病在人群中的传播方式存在一定的相似性。将经典的传染病SIR模型进行改进,构建基于改进SIR...
  • sqyx008
  • sqyx008
  • 2017-03-14 19:07
  • 2744
    个人资料
    • 访问:219612次
    • 积分:3189
    • 等级:
    • 排名:第12760名
    • 原创:95篇
    • 转载:0篇
    • 译文:0篇
    • 评论:65条
    最新评论