#include #include #include #include #include #include #include #include #include using namespace std; // The travelers!!! struct Agent { // origin node index int Origin; // Origin Time int OriginTime; //index of destination node int Destination; // position of the car (link id) int Position; int Index; //compliance to the information received at the junctions (basically how much the cars care about the state of the neighbour nodes when deciding their route double Compliance; }; // These are the junction that hold information abou struct Node { int Index; // The phase of the traffic light, meaning which ingoing link to the node receives green light int Phase; // list of neighbours used in the creation of the links' list vector Neighbors; // vector containing incoming links ids vector Ilinks; // vector containing outgoing links ids vector Olinks; // state of the node (0 or 1) encoding whether the node is signaling or not int State; // betweeness value of node double Beta; // Signaling threshold (as fraction of sum of capacities/buffer of incoming links) double Threshold; }; // The true streets, Buffer is the capacity, start and end are the indices of start and end nodes (surprisingly enough!) struct Link{ int Index; // Buffer= capacity of link int Buffer; // id of link's start node int start; // id of link's end node int end; // Vector containing the agents that compose the link's queue vector Queue; }; // number of nodes in the networks (for the moment is fixed, but one might well pass it from the command line typedef std::list listagents; /////////////////////////////////////////////////////////////////////////////////////////////////// int main(int argc, char *argv[]) { for(int rambo=1;rambo<20;rambo++){ int totindex=0; // rate at which cars are introduced in the network double rate=1; //(double) atof(argv[3]); // Total length of simulation int Tmax=80000; //atoi(argv[3]); // Number of cars introduced every time (basically roll the dice to see if you put them, if yes put Nc in ) int Nc=150; //atoi(argv[1]); int TotalDelivered=0; int prodotti=0; // buffer value used for links int buffer=30; // maximum number of cars flowing out of a link at each green light time int singleoutflow=15; // dim = variable used as side of lattice networks int dim=10; // power (for distances) to be used in route choosing double alpha = 5; int Rip = 373; //atoi(argv[4]); //// Data collection settings (data file names etc) char an_array[100]; // ASSORTED PIECES OF STRINGS AND STUFF USED TO COLLECT DATA OUTPUT string IND ="";///work/gpetri/TravelTimeAging/"; string ics="-"; string txt = ".txt"; sprintf(an_array, "%f", rate); char another_array[100]; sprintf(another_array,"%d", Nc); char yet_another[100]; sprintf(yet_another, "%d", Tmax); char rip[100]; sprintf(rip, "%d", Rip); string pippo2B = "Avalanches"; string pippo3 = "NetStructure"; string pippo4 = "totpop"; string pippo5A = "disappeared"; string ut = "UT"; ofstream UT ((IND+ut+ics+another_array+ics+an_array+ics+yet_another+ics+rip+txt).c_str()); string scarica2 = "Scarica2"; ofstream Scarica2 ((IND+scarica2+ics+another_array+ics+an_array+ics+yet_another+ics+rip+txt).c_str()); string scarica1 = "Scarica1"; ofstream Scarica1 ((IND+scarica1+ics+another_array+ics+an_array+ics+yet_another+ics+rip+txt).c_str()); string rt = "RT"; ofstream RT ((IND+rt+ics+another_array+ics+an_array+ics+yet_another+ics+rip+txt).c_str()); string pippo5B = "DD"; ofstream DD ((IND+pippo5B+ics+another_array+ics+an_array+ics+yet_another+ics+rip+txt).c_str()); string pippe = "Code"; string pippi = "TotPop"; ofstream Code ((IND+pippe+ics+another_array+ics+an_array+ics+yet_another+ics+rip+txt).c_str()); ofstream Pop ((IND+pippi+ics+another_array+ics+an_array+ics+yet_another+ics+rip+txt).c_str()); string pippee = "CodePop"; ofstream CodePop ((IND+pippee+ics+another_array+ics+an_array+ics+yet_another+ics+rip+txt).c_str()); string pippo6 = "Delivered"; string pippo7 = "TotDelivered"; ofstream Del ((IND+pippo6+ics+another_array+ics+an_array+ics+yet_another+ics+rip+txt).c_str()); ofstream TotDel ((IND+pippo7+ics+another_array+ics+an_array+ics+yet_another+ics+rip+txt).c_str()); string pippo8 = "QD"; ofstream QD ((IND+pippo8+ics+another_array+ics+an_array+ics+yet_another+ics+rip+txt).c_str()); string ra = "ratio"; ofstream ratio ((IND+ra+ics+another_array+ics+an_array+ics+yet_another+ics+rip+txt).c_str()); string pr = "Prodotti"; ofstream Prod ((IND+pr+ics+another_array+ics+an_array+ics+yet_another+ics+rip+txt).c_str()); string mc = "Moving"; ofstream MovingCars ((IND+mc+ics+another_array+ics+an_array+ics+yet_another+ics+rip+txt).c_str()); string td = "StuckCount"; string tt = "TravelTime"; ofstream TTr((IND+tt+ics+another_array+ics+an_array+ics+yet_another+ics+rip+txt).c_str()); ofstream SC((IND+td+ics+another_array+ics+an_array+ics+yet_another+ics+rip+txt).c_str()); ///////// GRAPH GENERATION SECTION // initializer of random number generator srand((unsigned)time(0)); // igraph declaration of new graph igraph_t graph; // declaration and initialization of vectors used for creating lattice graph igraph_vector_t dimvector; igraph_vector_init(&dimvector,2); VECTOR(dimvector)[0]=dim; VECTOR(dimvector)[1]=dim; // EXAMPLES OF GRAPH GENERATORS (i will insert a way of reading from an adjacency matrix file or edgelist file in a future iteration) igraph_lattice(&graph, &dimvector, 1, IGRAPH_UNDIRECTED, 1, 0); // igraph_erdos_renyi_game(&graph, IGRAPH_ERDOS_RENYI_GNP, 1000, 10/1000, IGRAPH_UNDIRECTED, IGRAPH_NO_LOOPS); // igraph_barabasi_game(&graph, 100, 3, NULL, 0, 0); // automatic count of number of nodes in network int N; N=(int)igraph_vcount(&graph); cout << " number of nodes " << N << endl; // Set Destinations and Origins for cars int numero = N; int O[numero]; int D[numero]; for(int ur=0;ur ListaLink; // declaration of iterator on graph's nodes igraph_vit_t mom; igraph_vit_create(&graph, igraph_vss_all(), &mom); int numeretto=0; while(!IGRAPH_VIT_END(mom)){ // assigment of index to nodes inside nodes' list vector ListaNodi[(int)IGRAPH_VIT_GET(mom)].Index=(int)IGRAPH_VIT_GET(mom); // this declares the iterator on the neighbours of the active node igraph_vs_t deh; igraph_vs_adj(&deh, (int) IGRAPH_VIT_GET(mom),IGRAPH_IN ); igraph_vit_t vicini; igraph_vit_create(&graph,deh,&vicini); // assignment of links adjacent to node under construction while(!IGRAPH_VIT_END(vicini)){ ListaNodi[(int)IGRAPH_VIT_GET(mom)].Neighbors.push_back((int)IGRAPH_VIT_GET(vicini)); Link newlinkO; newlinkO.Index=ListaLink.size(); newlinkO.Buffer=buffer; newlinkO.start=(int)IGRAPH_VIT_GET(mom); newlinkO.end=(int)IGRAPH_VIT_GET(vicini); ListaLink.push_back(newlinkO); ListaNodi[(int) IGRAPH_VIT_GET(mom)].Olinks.push_back(ListaLink.back().Index); IGRAPH_VIT_NEXT(vicini); } // garbage collection igraph_vit_destroy(&vicini); igraph_vs_destroy(&deh); // set phase of traffic lights ListaNodi[(int)IGRAPH_VIT_GET(mom)].Phase=rand()%ListaNodi[(int)IGRAPH_VIT_GET(mom)].Olinks.size(); // set betweeness of node ListaNodi[(int)IGRAPH_VIT_GET(mom)].Beta=VECTOR(bet)[(int)IGRAPH_VIT_GET(mom)]; // ListaNodi[(int)IGRAPH_VIT_GET(mom)].Beta=Bet[(int)IGRAPH_VIT_GET(mom)]; // set signaling threshold value for node (must find a better way to set this value) ListaNodi[(int)IGRAPH_VIT_GET(mom)].Threshold=1; IGRAPH_VIT_NEXT(mom); } // garbage collection igraph_vit_destroy(&mom); igraph_vector_destroy(&bet); // assignment of node's links to node in nodes' list for(int y=0;y=0) && (ecciPosition=linkid; int w=((rand()%numero)+1)%numero; int d = D[w]; while((int)MATRIX(res,d,O[posizione])==0){ w=((rand()%numero)+1)%numero; d = D[w]; } (ptrr)->Index=totindex+1; (ptrr)->Destination = d; (ptrr)->Origin=O[posizione]; (ptrr)->OriginTime=t; // this sets the compliance values as uniformly distributed into (0.5,1) (ptrr)->Compliance= 0.5 + 0.5*(rand()/(double)(RAND_MAX+1)); ListaLink[(ptrr)->Position].Queue.push_back(ptrr); totindex=totindex+1; // Le nuove macchine vengono messe su una delle strade in uscita dal nodo dove "vengon prodotte". // E vengono assorbite quando arrivano su una delle strade vicine al nodo dove voglio arrivare. prodotti++; } } Prod << " " << t << " " << prodotti << endl; } ///////// SEQUENTIAL UPDATE OF PHYSICAL LAYER // random choose a node to start serial update int Init = rand()%N; int activenode=Init; while(activenode!=(Init-1+N)%N){ // set initial variables for active node int phase = (int) ListaNodi[activenode].Phase; // update of phase value for next timestep ListaNodi[activenode].Phase = (ListaNodi[activenode].Phase+1+ListaNodi[activenode].Olinks.size())%ListaNodi[activenode].Olinks.size(); // variables useful as shortcuts (disposables basically) int activelink = ListaNodi[activenode].Ilinks[phase]; int stuck=0; int conto=0; while( (ListaLink[activelink].Queue.size()!=0) && (stuck==0) && (contoCompliance; // set dummy variable for car's destination's id int dest = (int) (ListaLink[activelink].Queue[0])->Destination; // vector in which I'll store the unnormalized probabilities of turning one way or the other vector TT; // Probability construction for single traveler navigation double z =0; for (int e=0;e Pcum; for(int u=0;uPcum[xz]) { xz++; } // link chosen for entrance attempt by car int linkattemp=ListaNodi[activenode].Olinks.at(xz); //if the target link is free, the car is allowed to enter and removed from the previous queue. We count one moving car. if(ListaLink[linkattemp].Queue.size()OriginTime) << endl; ratio << (int) MATRIX(res,(ListaLink[linkattemp].Queue.back())->Origin, (ListaLink[linkattemp].Queue.back())->Destination) << " " << (t- (ListaLink[linkattemp].Queue.back())->OriginTime)<< endl; Agent * death = ListaLink[linkattemp].Queue.back(); ListaLink[linkattemp].Queue.pop_back(); delete(death); Delivered++; } if ( ListaLink[linkattemp].start==dest ) { TTr << (t- (ListaLink[linkattemp].Queue.back())->OriginTime) << endl; ratio << (int) MATRIX(res,(ListaLink[linkattemp].Queue.back())->Origin, (ListaLink[linkattemp].Queue.back())->Destination) << " " << (t- (ListaLink[linkattemp].Queue.back())->OriginTime)<< endl; Agent * death = ListaLink[linkattemp].Queue.back(); ListaLink[linkattemp].Queue[(int)ListaLink[linkattemp].Queue.size()-1]=0; ListaLink[linkattemp].Queue.pop_back(); delete(death); Delivered++; } conto++; } else { //else if the selected link queue is full, the car gets stuck, blocking the cars behind and we proceed with the following node. stuck=1; stuckcount++; } } activenode++; activenode=activenode%N; } ///////////////////////////////////////////////// INFORMATION STEP int nocrit=0; int critical1=0; int critical2=0; // Search for primary critical nodes for(int nodo=0;nodo=ListaNodi[nodo].Threshold*bufftot ){ ListaNodi[nodo].State=1; nocrit=1; critical1++; critical2++; //cout << " primary critical found node " << nodo << endl; } // cout << "getting out of primary critical cycle" <=ListaNodi[i].Threshold*bufftot ){ ListaNodi[i].State=1; nocrit=1; critical2++; } } } } /////// DATA COLLECTION (full of shit down there, will correct it in future iteration) TotalDelivered+=Delivered; Del << " " << t << " " << Delivered << endl; TotDel << " " << t << " " << TotalDelivered << endl; MovingCars << " " << t << " " << Moving << endl; int pop=0; int QueueDistr [buffer+1]; for(int y=0;y