See
- The definition networkstructure.h
- The description NetworkStructure
<project-file type=“source”/> <content> #include “networkstructure.h” #include <fstream> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include “ke_index.h”
NetworkStructure::NetworkStructure(const char* file) {
FILE *f = fopen(file, "r"); if (f == NULL) { std::cerr<<"Cannot open the network file "<<file<<" to read"<<std::endl; fclose(f); exit(1); } if (-1 == fseek(f, 0, SEEK_END)) { std::cerr<<"Cannot find the length of the network file "<<file<<std::endl; fclose(f); exit(1); } long file_length = ftell(f); char *content = new char[file_length + 1]; int l = 0; char c; rewind(f); for (int i = 0; i < file_length; i++) { c = getc(f); if (c == EOF) { std::cerr<<"Cannot read the network file "<<file<<std::endl; fclose(f); exit(1); } content[i] = c; } fclose(f); MaxDegree = 0; MaxExternalDegree = 0; MaxHouseholdSize = 0; content[file_length] = 0; int n = 1; for (int i = 0; i < file_length; i++) if (content[i] == '\n') n++; Nodes.reserve(n); Nodes.resize(n); IsInternal.reserve(n); IsInternal.resize(n); HouseholdStarts.reserve(n); HouseholdStarts.resize(n); HouseholdSizes.reserve(n); HouseholdSizes.resize(n); InHousehold.reserve(n); InHousehold.resize(n); // read in the numbers int pos = 0, house = -1, last_in_house = -1; int individual = 0; for (int line = 0; line < n; line++) { // count the number of neighbors int neighbors = 0; int household_size = 1; // a line starting with # is comment bool skip = content[pos] == '#'; if (!skip ) for (int i = pos; i < file_length; i++) { if (content[i] == 'e') ++neighbors; else if (content[i] == 'h') { ++neighbors; ++household_size; } else if (content[i] == '\n') break; else if (content[i] == '\r' && i< file_length - 1 && content[i+1] != '\n' || !isdigit(content[i])) { std::cerr<<"network file "<<file<<": wrong format at line "<<line<<std::endl; fclose(f); exit(1); } } // if an empty line, or a comment, or a wrong line, if (neighbors == 0 || skip) { while (pos < file_length && content[pos] != '\n') ++pos; continue; } int external_degree = neighbors - household_size + 1; if (MaxDegree < neighbors) MaxDegree = neighbors; if (MaxExternalDegree < external_degree) MaxExternalDegree = external_degree; if (MaxHouseholdSize < household_size) MaxHouseholdSize = household_size; Nodes[individual].reserve(neighbors); Nodes[individual].resize(neighbors); IsInternal[individual].reserve(neighbors); IsInternal[individual].resize(neighbors); for (int i = 0; i < neighbors; i++) { unsigned int neighbor = 0; char type; while (isdigit(content[pos])) { neighbor = neighbor * 10 + content[pos] - '0'; ++pos; } type = content[pos]; if (type != 'e' && type != 'h') { std::cerr<<"network file "<<file<<": wrong format at line "<<line<<std::endl; fclose(f); exit(1); } Nodes[individual][i] = neighbor; IsInternal[individual][i] = type == 'h'; // skip the digit while (isdigit(content[pos]) && pos < file_length && content[pos] != '\n') ++pos; // skip the type ++pos; } // skip to the end of the line while (pos < file_length && content[pos] != '\n') ++pos; // skip the end of line \n if (content[pos] == '\n') ++pos; if (individual > last_in_house) { ++house; HouseholdSizes[house] = household_size; HouseholdStarts[house] = individual; last_in_house = individual; for (int i = 0; i < neighbors; i++) if (IsInternal[individual][i]) last_in_house = Nodes[individual][i]; else break; } InHousehold[individual] = house; individual++; } ++house; Nodes.resize(individual); IsInternal.resize(individual); InHousehold.resize(individual); HouseholdSizes.resize(house); HouseholdStarts.resize(house); delete content;
}
void NetworkStructure::infect(const std::vector<int> &I0) {
int N = Nodes.size(), nI0 = I0.size(); Infected.reserve(N); Infected.resize(N, false); for (int i = 0; i < nI0; i++) { Infected[I0[i]] = true; }
}
void NetworkStructure::dumpEffectiveDegrees(std::ostream &logger) {
int M = MaxExternalDegree, N = Nodes.size(); if (M == 0) return;
int m = M * (M + 3) / 2 + 1; S.reserve(m); S.resize(m); I.reserve(m); I.resize(m); for (int i = 0; i < m; i++) S[i] = I[i] = 0; for (int i = 0; i < N; i++) { int k = Nodes[i].size(); int e = 0; int household = InHousehold[i]; int household_size = HouseholdSizes[household] - 1; for (int j = household_size; j < k; j++) if (Infected[Nodes[i][j]]) e++; if (Infected[i]) I[ke_index(k - household_size, e)]++; else S[ke_index(k - household_size, e)]++; } for (int index = 0, i = 0; i <= M; i++) for (int j = 0; j <= i; j++) logger << "Initial S : " << i << " : " << j << " : " << S[index++] << std::endl; for (int index = 0, i = 0; i <= M; i++) for (int j = 0; j <= i; j++) logger << "Initial I : " << i << " : " << j << " : " << I[index++] << std::endl;
}
void NetworkStructure::dumpHouseholdCompartments(std::ostream &logger) {
int M = MaxHouseholdSize, N = Nodes.size(); int households = HouseholdSizes.size(); if (M == 0) return;
int m = M * (M + 3) / 2 + 1; H.reserve(m); H.resize(m); std::vector<int> infected_in_household(households, 0); for (int i = 0; i < m; i++) H[i] = 0; for (int i = 0; i < N; i++) { int hh = InHousehold[i]; int household = InHousehold[i]; if (Infected[i]) ++infected_in_household[hh]; } for (int i = 0; i < households; i++) H[ke_index(HouseholdSizes[i], infected_in_household[i])]++; for (int index = 0, i = 0; i <= M; i++) for (int j = 0; j <= i; j++) logger << "Initial H : " << i << " : " << j << " : " << H[index++] << std::endl;
}
void NetworkStructure::dumpNet(std::ostream &logger) {
int N = Nodes.size(), i, j, M = MaxDegree;
for (i = 0; i < N; i++) { int k = Nodes[i].size(); logger << "node : " << i << " :"; for (int j = 0; j < k; j++) logger << Nodes[i][j] << (IsInternal[i][j]) ? "h" : "e"; logger << std::endl; }
} </content> <use name=“ke_index.h”/>