//------------------------------------------------------------------------------ void NiceGraph::removeEdge (int from, int to) { bool okflag; if (isDirected) okflag = testFromToConnected(from,to); else okflag = testConnected(from,to); // test connected first to make sure the connection exists if (okflag) { int edgeID = getEdgeID(from,to); removeEdge(edgeID); if (!isDirected) removeEdge(to,from); } }
void ER_con_test() { int nodeNum; int linkNum; struct network* target; int num; int i; nodeNum=100; linkNum=200; for(i=1;i<=10;i++) { target=(struct network *)mem_alloc(sizeof(struct network)); erModel_1(target, nodeNum, linkNum); num=convertUnconnectedToConnected(target); printf("\n link number = %d , connected = %d \n ", num,testConnected(target)); } }
//------------------------------------------------------------------------------ void NiceGraph::addEdge (int fromID, int toID) { // if not already connected, add the edge // otherwise do nothing // also, can't connect to self bool goFlag; if (isDirected) // directed graph goFlag = !testFromToConnected(fromID,toID); else // undirected graph goFlag = !testConnected(fromID,toID); if (fromID == toID) goFlag = false; if (goFlag) { Vertex *vFrom = vertexList[fromID]; Vertex *vTo = vertexList[toID]; Edge *newEdge = new Edge(); edgeList[edgeIDCounter] = newEdge; edgeList[edgeIDCounter]->from = vFrom; edgeList[edgeIDCounter]->to = vTo; edgeList[edgeIDCounter]->eID = edgeIDCounter; // DEFAULT WEIGHT UNLESS OTHERWISE SPECIFIED edgeList[edgeIDCounter]->weight = 1.0; // also add the edge to the vertex neighbor list vFrom->out[edgeIDCounter] = newEdge; vTo->in[edgeIDCounter] = newEdge; if (!isDirected) // add the reciprocal edge if the graph is not directed addEdge(toID,fromID); edgeIDCounter++; } }
//------------------------------------------------------------------------------ void NiceGraph::makeRandomGraph(int numVertices, float density) { makeEmptyGraph(numVertices); // first initialize all the vertices int total = density * (float) numVertices * (numVertices - 1.0); // bounds checking if ((density > 0) && (total < 1)) total = 1; while (total > 0) { int v1 = rand() % numVertices; int v2 = rand() % numVertices; if (isDirected) // directed graph { if (!testFromToConnected(v1,v2)) { addEdge(v1,v2); total--; } } else // undirected graph { if (!testConnected(v1,v2)) { addEdge(v1,v2); addEdge(v2,v1); total--; total--; } } } }
/* get the statistical characters of connected complex network */ int getConnectedNetInfo( struct network * target, /*input: target network */ struct connectedNetInfo ** pro) /*output: the properties of the complex network*/ { int i,j,x,y,num,n; double k,c,l,c_i,e; int *D; int error; struct connectedNetInfo* p_c; int max_l; int max_k; int min_k; p_c=(struct connectedNetInfo*)mem_alloc(sizeof(struct connectedNetInfo)); n=target->nodeNum; if (testConnected(target)==0) { error=UNCONNECTED; printf("network is unconnected !\n"); goto exit_1; } error=0; D=(int *)mem_alloc((1+n)*sizeof(int)); // 1) average path length --- (for connected network) //network efficiency --- (for both connected network and unconnected network) l=0.0; e=0.0; max_l=0; for(i=1;i<=n;i++) { BFS(target, i, D, NULL); for(j=1;j<=n;j++) { if(D[j]==n) //unconnected network { error=UNCONNECTED; printf("network is unconnected !\n"); goto exit_2; } l=l+D[j]; if(D[j]>max_l) { max_l=D[j]; } if(D[j]!=0&&D[j]!=n) { e+=(double)((double)1/(double)D[j]); } } } l=(double)(l/(n*(n-1))); e=(double)(e/(n*(n-1))); p_c->av_l=l; p_c->max_l=max_l; p_c->e_glob=e; // 2) clustering coefficient c=0.0; for(i=1;i<=n;i++) { num=0; if(target->nodes[i].numadj==1) { c=c+0.0; continue; } for(j=1;j<target->nodes[i].numadj;j++) { int a=target->nodes[i].adj[j]; for(y=1;y<=target->nodes[a].numadj;y++) { int b=target->nodes[a].adj[y];; for(x=j+1;x<=target->nodes[i].numadj;x++) { if(b==target->nodes[i].adj[x]) { num++; break; //no rebundant links between two nodes } } } } c_i=(double)((target->nodes[i].numadj*(target->nodes[i].numadj-1)))/2; c+=(double)((double)num/c_i); } c=c/(double)n; p_c->av_c=c; // 3) degree distribution k=0; max_k=0; min_k=target->nodeNum; for(i=1;i<=n;i++){ k=k+target->nodes[i].numadj; if(target->nodes[i].numadj>max_k) { max_k=target->nodes[i].numadj; } if(target->nodes[i].numadj<min_k) { min_k=target->nodes[i].numadj; } } k=k/n; p_c->av_k=k; p_c->max_k=max_k; p_c->min_k=min_k; exit_2: mem_free(D); exit_1: *pro=p_c; return error; }
int getBasicNetInfo(struct network * target, /*input: target network */ struct netInfo * netinfo) /*output*/ { int deadNum; int max_k,av_k; int i,j,x,y,l,num; int connected; double c,ci,cw,ci_w,e_loc,ei; double nnk,nnk_w; double ui,yi; int a,b; double val; // 0) if connected connected=testConnected(target); //netinfo->target=target; netinfo->connected=connected; // 1) node degree max_k=0; av_k=0; deadNum=0; for(i=1;i<=target->nodeNum;i++) { netinfo->ninfo[i].nodeid=i; netinfo->ninfo[i].degree=target->nodes[i].numadj; netinfo->ninfo[i].status=target->nodes[i].status; av_k+=target->nodes[i].numadj; if(max_k<target->nodes[i].numadj) { max_k=target->nodes[i].numadj; } if(target->nodes[i].status==NODE_DEAD) { deadNum++; } } netinfo->deadNum=deadNum; netinfo->activeNum=target->nodeNum-deadNum; if(netinfo->activeNum!=0) { netinfo->av_k=(double)av_k/(double)netinfo->activeNum; }else{ netinfo->av_k=0.0; } netinfo->max_k=max_k; // 2) node strength for(i=1;i<=target->nodeNum;i++) { val=0.0; for(j=1;j<=target->nodes[i].numadj;j++) { val+=target->nodes[i].weight[j]; } target->nodes[i].strength=val; netinfo->ninfo[i].strength=val; } // 3) node strength-degree diversity & link info l=0; for(i=1;i<=target->nodeNum;i++) { if(target->nodes[i].numadj!=0) { ui=(double)(netinfo->ninfo[i].strength/(double)netinfo->ninfo[i].degree); }else { ui=0.0; } yi=0.0; nnk=0.0; nnk_w=0.0; for(j=1;j<=target->nodes[i].numadj;j++) { yi+=pow(target->nodes[i].weight[j]/target->nodes[i].strength, 2); a=target->nodes[i].adj[j]; nnk+=target->nodes[a].numadj; nnk_w+=(target->nodes[i].weight[j]*target->nodes[a].numadj); l++; netinfo->linfo[l].from=i; netinfo->linfo[l].to=target->nodes[i].adj[j]; netinfo->linfo[l].k1=target->nodes[i].numadj; netinfo->linfo[l].k2=target->nodes[a].numadj; netinfo->linfo[l].weight=target->nodes[i].weight[j]; netinfo->linfo[l].strength1=target->nodes[i].strength; netinfo->linfo[l].strength2=target->nodes[a].strength; } if (target->nodes[i].numadj!=0) { nnk=nnk/(double)(target->nodes[i].numadj); nnk_w=nnk_w/target->nodes[i].strength; } netinfo->ninfo[i].ui=ui; netinfo->ninfo[i].yi=yi; netinfo->ninfo[i].nnk=nnk; netinfo->ninfo[i].nnk_w=nnk_w; } // 4) clustering coefficient and local communication efficiency c=0.0; cw=0.0; e_loc=0.0; for(i=1;i<=target->nodeNum;i++) { if(target->nodes[i].numadj==1||target->nodes[i].numadj==0) { netinfo->ninfo[i].coef=0.0; netinfo->ninfo[i].e_local=0.0; netinfo->ninfo[i].coef_w=0.0; continue; } num=0; ei=0.0; ci_w=0.0; for(j=1;j<target->nodes[i].numadj;j++) { a=target->nodes[i].adj[j]; for(x=j+1;x<=target->nodes[i].numadj;x++) { b=target->nodes[i].adj[x]; for(y=1;y<=target->nodes[a].numadj;y++) { if(b==target->nodes[a].adj[y]) // a and b are also direct neighbours { num++; ei+=1.0; ci_w+=(target->nodes[i].weight[j]+target->nodes[i].weight[x]); }else{ ei+=(double)(1.0/2.0); } } } } ci=(double)((double)num/(double)(target->nodes[i].numadj*(target->nodes[i].numadj-1)/2)); ci_w=ci_w/(double)(target->nodes[i].strength*(target->nodes[i].numadj-1)); netinfo->ninfo[i].coef=ci; netinfo->ninfo[i].coef_w=ci_w; netinfo->ninfo[i].e_local=ei; c+=ci; cw+=ci_w; e_loc+=ei; } if(netinfo->activeNum!=0) { netinfo->av_coef=c/(double)netinfo->activeNum; netinfo->av_coefw=cw/(double)netinfo->activeNum; netinfo->e_loc=e_loc/(double)netinfo->activeNum; }else{ netinfo->av_coef=0; netinfo->av_coefw=0; netinfo->e_loc=0; } // 5) Load and Betweeness Centrality //getNL_LB(target,netinfo); return 0; }
//------------------------------------------------------------------------------ void NiceGraph::makeStrangersBanquetGraph(int numVertices, int groups, float density, float mu) { makeEmptyGraph(numVertices); // first initialize all the vertices makeUndirected(); // the SB is only undirected for now... if (groups > numVertices) // bounds checking on number of groups groups = numVertices; for (int c = 0; c < numVertices; c++) // now subdivide into groups { for (int g = 0; g < groups; g++) { if (c % groups == g) setVertexColor(c,g); } } // make declining edge scheme to speed things up int total_edges = numVertices * (numVertices - 1) / 2; vector<Edge> proposals (total_edges); int edgeIndex = 0; for (int froms = 0; froms < numVertices; froms++) { for (int tos = 0; tos < numVertices; tos++) { if ((froms != tos) && (froms < tos)) { proposals[edgeIndex].from = vertexList[froms]; proposals[edgeIndex].to = vertexList[tos]; edgeIndex++; } } } // propose connections and build graph int num_edges = (int) (density * (float) total_edges); int edge_counter = 0; while (edge_counter < num_edges) { // use declining proposal list to speed things up... int randIndex = rand() % proposals.size(); // choose two vertices to make the proposal int vertex1 = proposals[randIndex].from->vID; int vertex2 = proposals[randIndex].to->vID; if ((vertex1 != vertex2) && (!testConnected(vertex1,vertex2))) // if isn't itself, and aren't already connected { // now check to see if they are accepted if (vertexList[vertex1]->vColor == vertexList[vertex2]->vColor) { // if same color approve match addEdge(vertex1, vertex2); // add edge edge_counter++; if (!proposals.empty()) proposals.erase(proposals.begin()+randIndex); // remove from list } else // if different colors check against mu { float chance1 = rand() / (RAND_MAX+1.0); float chance2 = rand() / (RAND_MAX+1.0); if ((chance1 < mu) || (chance2 < mu)) continue; // if either one rejects the connection do nothing else { // approve the connection addEdge(vertex1, vertex2); // add edge edge_counter++; if (!proposals.empty()) proposals.erase(proposals.begin()+randIndex); // remove from list } } } } }