// - Source Treminal Network Unrealiability - // Permutation Monte Carlo over a Static Network Model // Leslie Murray - FCEIA, Universidad Nacional de Rosario, Argentina // - July, 2023 - #include #include #include #include #include "mt.c" #define U genrand_real1() #define semilla(s) init_genrand(s) #define expo(lmbd) (-log(U)/lmbd) // Generador de numeros aleatorios con distribucion exponencial de tasa "lmbd" typedef struct link{ double rlb; // link reliability double lambda; // rate to sample the link from exponential ditribution double tau; // time when the link goes from failed to operative int op; // 1 if the link is operative and 0 if it remains failed int node1; // structure link models connection between node1 and node2 int node2; // (in both directions) i.e., from 1 to 2 and from 2 to 1 }lnk, *pt_lnk; int s; // network source node int t; // network target node int numnodes; // network number of nodes int numlinks; // network number of links int **list; // matrix to hold the adjacency lists lnk *E; // array to hold the set of all links such that: link from // x to y and from y to x share the same bucket. Links are // numbered from 0 to numlinks-1 // Nodes are numbered from 1 to numnodes (just like in the // text files where the network is loaded from). In the // data structures, node 0 is reserved for some algorithms // tricks void reset(); // sets tau=0 for all the links (among other things) int next(); // returns the number of the next link to become operative int *visited; // array of nodes such that 1 indicates that BFS has // visited the node and 0 that it hasn't int connected; // 1 if there's a path of operative links connecting s and // t and 0 otherwise double *lim; // array to set limits to sort from discrete distribution double previous_tau;// the latest time a node became operative void Initialize(char* filename); // takes the text file with the network info as input, // builds up the rest of the structures and initializes all // the variables int Phi(); // returns 1 if, for the set of links that are already // operative, the network is operative, and 0 otherwise void DFS(int node); // performs Depth First Search from "node" and, as soon as // node "t" is visited sets connected=1 and stops double tot; // the sum of the rates (lambdas) of all the nodes that are // still failed void accept(int n); // to be executed when the time just sorted (tau of link n) // is accepted void set_tau(int l); // Sort the time to become operative to link l double *D; // array to hold the rates of the exponential random // variables of the times between commutations int m; // index to save the number of occupied position of D void set_perm(); // sets a links permutation and updates array D double prob_perm(); // Estimates the probability that the permutation // built by set_perm() puts the network operative // in time t>1 int seed; // seed for the random numbers generator /******************************************************************** * The executable "e" runs as: ./e , where: * File: is the text file with the network (graph) info * Size: is the number of trajectories launched from 0 * Seed: is the seed for the random numbers generator ********************************************************************/ int main(int argc, char *argv[]){ int i,j,defined,size; double S,S2,X,V,Q,t; clock_t ti; if(argc<4){ printf("\n Some input data is missing! Run as:\n"); printf("\n ./executable \n\n"); exit(1); } if(argc>4){ printf("\n You've entered more data than necessary! Run as:\n"); printf("\n ./executable \n\n"); exit(1); } if((size=atoi(argv[2]))<1){ printf("\n The number of replications can not be less than 1! Run as:\n"); printf("\n ./executable \n\n"); exit(1); } if((seed=atoi(argv[3]))<0){ printf("\n The seed can not be negative! Run as:\n"); printf("\n ./executable \n\n"); exit(1); } Initialize(argv[1]); //------------- THE PERMUTATION MONTE CARLO ALGORITHM ------------- S=0.0; S2=0.0; ti = clock(); for(i=0;i=0;i--) lim[i]=lim[i+1]-E[i+1].lambda; // Allocate array D if((D=(double*)calloc(numlinks,sizeof(double)))==NULL){ printf("\n Fail attempting to allocate memory...\n"); exit(1); } for(i=0;i0){ list[i][k++]=0; } } // Build up the adjacency lists for all the sampled links for(i=0;i0){ k++; } list[n1][k]=n2; k=1; while(list[n2][k]>0){ k++; } list[n2][k]=n1; } } connected=0; for(k=1;k<=numnodes;k++) visited[k]=0; DFS(s); return connected; } /******************************************************************** * makes a Depth First Search from node "s" and: * - set connected=1 if node "t" is reached * - set connected=0 if node "t" is not reached ********************************************************************/ void DFS(int node){ int k; if(connected) return; if(node == t){ connected=1; return; } visited[node]=1; k=1; while(list[node][k]>0){ if(!visited[list[node][k]]) DFS(list[node][k]); k++; } return; } /******************************************************************** * clears tau and op for matrix E, and also previous_tau ********************************************************************/ void reset(){ int i; tot=0.0; for(i=0;i=0;i--) lim[i]=lim[i+1]-E[i+1].lambda; m=0; for(i=0;irnd) break; if(k>=numlinks) // there are no more links left to set tau to return -1; E[k].tau=previous_tau+expo(tot); return k; } /******************************************************************** * It accepts the link sampled by next() and updates some values ********************************************************************/ void accept(int n){ int i; E[n].op=1; previous_tau=E[n].tau; tot=tot-E[n].lambda; lim[n]=-1.0; for(i=n+1;i1 ********************************************************************/ double prob_perm(){ int i,j,k; double prod,prod_sum,sum; //for(i=0;i