1. 程式人生 > >SIS傳染病模型的C語言實現

SIS傳染病模型的C語言實現

思路:

  1. 隨機挑選一個或多個初始感染點,將它們置為I態;
  2. 開始一輪感染;
  3. 遍歷每一個I態節點的S態鄰居(每個節點沒輪只訪問一次);
  4. 遍歷上述鄰居的每個I態鄰居,統計其個數(若為k個),這個節點的感染概率為1-(1-beta)^k,其中beta為感染概率;
  5. 統計上一輪感染結束後網路中存在的感染點,按照恢復概率將它們恢復為S態;
  6. 感染結束,返回2。

C語言實現

# include <stdio.h>
# include <stdlib.h>
# include <math.h>
# include <time.h>
# define SUM_OF_VERTEX 1000 // 網路節點總數
# define RATE_OF_INFECTION 1 // 感染率 # define RATE_OF_RECOVER 1 // 恢復率 # define STEP 30 // 感染輪數 # define FILENAME_IN "WS_1000.txt" # define FILENAME_OUT "data_1.0.txt" struct Node { int is_infected; }vertex[SUM_OF_VERTEX + 1]; struct LNode { int index; struct LNode *next; }; void Initial_AdjacencyMatrix(); void
Free_AdjacencyMatrix(); void Read_File(); void Output_To_File(); void SIS_Diffusion(); int **AdjacencyMatrix; int sum_data_to_file[STEP + 1] = {0}; int main() { srand( ( unsigned )time( NULL ) ); Initial_AdjacencyMatrix(); Read_File(); SIS_Diffusion(); Output_To_File(); Free_AdjacencyMatrix(); } void
Initial_AdjacencyMatrix() { if( !( AdjacencyMatrix = ( int ** )malloc( sizeof( int * ) * ( SUM_OF_VERTEX + 1 ) ) ) ) { printf( "ERROR: **AdjecentMatrix malloc error.\n" ); exit( -1 ); } for( int i = 1; i <= SUM_OF_VERTEX; i ++ ) if( !( AdjacencyMatrix[i] = ( int * )malloc( sizeof( int ) * ( SUM_OF_VERTEX + 1 ) ) ) ) { printf( "ERROR: *AdjecentMatrix malloc error.\n" ); exit( -1 ); } } void Free_AdjacencyMatrix() { for( int i = 1; i <= SUM_OF_VERTEX; i ++ ) { free( AdjacencyMatrix[i] ); AdjacencyMatrix[i] = NULL; } free( AdjacencyMatrix ); AdjacencyMatrix = NULL; } void Read_File() { FILE *fp = fopen( FILENAME_IN, "r" ); if( fp == NULL ) { printf( "ERROR: No such file.\n" ); exit( -1 ); } for( int i = 1; i <= SUM_OF_VERTEX; i ++ ) { for( int j = 1; j <= SUM_OF_VERTEX; j ++ ) fscanf( fp, "%d", &AdjacencyMatrix[i][j] ); fscanf( fp, "\n" ); } } void Output_To_File() { FILE *fout = fopen( FILENAME_OUT, "a" ); if( fout == NULL ) { printf( "ERROR: No such file.\n" ); exit( -1 ); } for( int i = 1; i <= STEP; i ++ ) fprintf( fout, "%d ", sum_data_to_file[i] ); fprintf( fout, ";\n" ); } void SIS_Diffusion() { double infected_flag, recovered_flag; int initial_infected_vertex; int temp_infected_this_step[SUM_OF_VERTEX + 1] = {0}; int is_visited_this_step[SUM_OF_VERTEX + 1] = {0}; int sum_of_infected_vertices = 0; int count_infected_neighbors = 0; int count_infected_this_step = 0; int count_recovered_this_step = 0; int sequence_of_infected_vertices[STEP + 1][SUM_OF_VERTEX + 1] = {0}; // 按感染順序儲存每一個STEP被感染的節點序號 for( int i = 1; i <= SUM_OF_VERTEX; i ++ ) vertex[i].is_infected = 0; /*隨機取一個初始感染點*/ initial_infected_vertex = rand() % SUM_OF_VERTEX + 1; printf( "Initial = No.%d\n", initial_infected_vertex ); vertex[initial_infected_vertex].is_infected = 1; sequence_of_infected_vertices[0][1] = initial_infected_vertex; sum_of_infected_vertices ++; sum_data_to_file[0] = sum_of_infected_vertices; for( int step = 1; step <= STEP; step ++ ) { int k = 1; /*遍歷每個感染點的每個未被感染的鄰居,若該鄰居有k個被感染的鄰居,則它的感染率為: 1 - ( 1 - beta ) ^ k*/ for( int i = 1; i <= SUM_OF_VERTEX; i ++ ) if( vertex[i].is_infected ) // 感染點i for( int j = 1; j <= SUM_OF_VERTEX; j ++ ) // 遍歷i的鄰居 if( AdjacencyMatrix[i][j] && !vertex[j].is_infected && !is_visited_this_step[j] ) // 未被感染的鄰居j { for( int k = 1; k <= SUM_OF_VERTEX; k ++ ) if( AdjacencyMatrix[j][k] && vertex[k].is_infected ) // 統計j的感染鄰居的個數 count_infected_neighbors ++; infected_flag = rand() % ( SUM_OF_VERTEX + 1 ) / ( double )SUM_OF_VERTEX; if( infected_flag <= 1 - pow( 1 - RATE_OF_INFECTION, count_infected_neighbors ) ) { temp_infected_this_step[j] = 1; sequence_of_infected_vertices[step][k ++] = j; count_infected_this_step ++; } is_visited_this_step[j] = 1; count_infected_neighbors = 0; } for( int i = 1; i <= SUM_OF_VERTEX; i ++ ) if( temp_infected_this_step[i] ) vertex[i].is_infected = 1; for( int i = 1; i <= SUM_OF_VERTEX; i ++ ) temp_infected_this_step[i] = 0; for( int i = 1; i <= SUM_OF_VERTEX; i ++ ) is_visited_this_step[i] = 0; /*遍歷所有上一個step存在的感染點,依照恢復概率將它們恢復為易感態*/ for( int i = 0; i <= step - 1; i ++ ) for( int j = 1; j <= SUM_OF_VERTEX; j ++ ) { recovered_flag = rand() % ( SUM_OF_VERTEX + 1 ) / ( double )SUM_OF_VERTEX; if( sequence_of_infected_vertices[i][j] && recovered_flag < RATE_OF_RECOVER ) { vertex[sequence_of_infected_vertices[i][j]].is_infected = 0; sequence_of_infected_vertices[i][j] = 0; count_recovered_this_step ++; sum_of_infected_vertices --; } } /*統計輸出*/ sum_of_infected_vertices += count_infected_this_step; sum_data_to_file[step] = sum_of_infected_vertices; printf( "Step = %d\n", step ); printf( "Sum = %d\n", sum_of_infected_vertices ); printf( "There are %d vertices newly infected this step.\n", count_infected_this_step ); printf( "There are %d vertices newly recovered this step.\n\n", count_recovered_this_step ); // sum_of_infected_vertices += count_infected_this_step; count_recovered_this_step = 0; count_infected_this_step = 0; } }