void MH_FormationPlusMLE (MHproposal *MHp, Network *nwp) { static Vertex nnodes; static Edge nedges0; static Dyad ndyads; if(MHp->ntoggles == 0) { /* Initialize */ MHp->ntoggles=1; nnodes = nwp[0].nnodes; ndyads = DYADCOUNT(nnodes, 0, nwp[0].directed_flag); nedges0 = MHp->inputs[0]; return; } if(nedges0==ndyads){ /* Attempting formation on a complete graph. */ Mtail[0]=MH_FAILED; Mhead[0]=MH_IMPOSSIBLE; return; } BD_COND_LOOP({ /* Keep trying dyads until a one that is not an edge in the reference network is found. */ /* Generate. */ GetRandDyad(Mtail, Mhead, nwp); }, !dEdgeListSearch(Mtail[0],Mhead[0],MHp->inputs), 2);
int GetRandNonedge(Vertex *tail, Vertex *head, Network *nwp) { Edge ndyads = DYADCOUNT(nwp->nnodes, nwp->bipartite, nwp->directed_flag); if(ndyads-nwp->nedges==0) return(0); /* There are two ways to get a random nonedge: 1) keep trying dyads at random until you find one that's not an edge or 2) generate i at random and find ith nonedge. Method 1 works better in sparse networks, while Method 2, which runs in deterministic time, works better in dense networks. The expected number of attempts for Method 1 is 1/(1-e/d) = d/(d-e), where e is the number of edges and d is the number of dyads. */ // FIXME: The constant maxEattempts needs to be tuned. const unsigned int maxEattempts=10; unsigned int Eattempts = ndyads/(ndyads-nwp->nedges); Edge rane; if(Eattempts>maxEattempts){ // If the network is too dense, use the deterministic-time method: rane=1 + unif_rand() * (ndyads-nwp->nedges); FindithNonedge(tail, head, rane, nwp); }else{ do{ GetRandDyad(tail, head, nwp); }while(EdgetreeSearch(*tail, *head, nwp->outedges)); } return 1; }
/********************* void MH_randomtoggle Default MH algorithm *********************/ void MH_randomtoggle (MHproposal *MHp, Network *nwp) { /* *** don't forget tail-> head now */ if(MHp->ntoggles == 0) { /* Initialize randomtoggle */ MHp->ntoggles=1; return; } BD_LOOP({ GetRandDyad(Mtail, Mhead, nwp); });