Merge lp:~samuel-thiriot-accounts/igraph/add_game_islands into lp:~igraph/igraph/0.6-main-old

Proposed by SamThiriot
Status: Merged
Merged at revision: 2512
Proposed branch: lp:~samuel-thiriot-accounts/igraph/add_game_islands
Merge into: lp:~igraph/igraph/0.6-main-old
Diff against target: 227 lines (+190/-0)
4 files modified
include/igraph_games.h (+8/-0)
interfaces/R/igraph/R/games.R (+14/-0)
interfaces/R/src/rinterface.c.in (+20/-0)
src/games.c (+148/-0)
To merge this branch: bzr merge lp:~samuel-thiriot-accounts/igraph/add_game_islands
Reviewer Review Type Date Requested Status
Gábor Csárdi Approve
Review via email: mp+62567@code.launchpad.net

Description of the change

As discussed in the igraph-help list, I propose here to add another game which creates networks made of interconnected islands (small ER graphs).

This network generator is especially usefull for benchmarking, as it enables to tune easily the average path length and clustering rate in the graph.

I'm a newbie in bzr, so I hope I made things in the right way.

Added the generator into the C files (games.c, igraph_games.h ), and the relevant interfaces into the R interface folder.

Please let me now if something is wrong !

Regards,

Sam.

To post a comment you must log in.
Revision history for this message
Tamás Nepusz (ntamas) wrote :

Hi Sam,

This one seemed to work, thanks. One of us will review this soon. You'll probably get notified by Launchpad.

Tamas

Revision history for this message
SamThiriot (samuel-thiriot-accounts) wrote :

Hi Tamas,

thanks for your help !

Sam.

Revision history for this message
Gábor Csárdi (gabor.csardi) wrote :

Thanks for the code! Next time please consider also

1) writing some test cases, and
2) writing the R documentation if you add an R interface.

These are not strictly required for the inclusion of your patch, but they make our lives a lot easier.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/igraph_games.h'
2--- include/igraph_games.h 2011-05-11 21:44:47 +0000
3+++ include/igraph_games.h 2011-05-26 21:28:30 +0000
4@@ -162,6 +162,14 @@
5 igraph_real_t fw_prob, igraph_real_t bw_factor,
6 igraph_integer_t ambs, igraph_bool_t directed);
7
8+
9+int igraph_simple_interconnected_islands_game(
10+ igraph_t *graph,
11+ igraph_integer_t islands_n,
12+ igraph_integer_t islands_size,
13+ igraph_real_t islands_pin,
14+ igraph_integer_t n_inter);
15+
16 __END_DECLS
17
18 #endif
19
20=== modified file 'interfaces/R/igraph/R/games.R'
21--- interfaces/R/igraph/R/games.R 2011-05-11 21:44:47 +0000
22+++ interfaces/R/igraph/R/games.R 2011-05-26 21:28:30 +0000
23@@ -335,3 +335,17 @@
24 res
25 }
26
27+
28+simple.interconnected.islands.game <- function(islands.n, islands.size, islands.pin, n.inter) {
29+
30+
31+ on.exit( .Call("R_igraph_finalizer", PACKAGE="igraph") )
32+ .Call( "R_igraph_simple_interconnected_islands_game",
33+ as.numeric(islands.n),
34+ as.numeric(islands.size),
35+ as.numeric(islands.pin),
36+ as.numeric(n.inter),
37+ PACKAGE="igraph")
38+}
39+
40+
41
42=== modified file 'interfaces/R/src/rinterface.c.in'
43--- interfaces/R/src/rinterface.c.in 2011-05-16 16:20:11 +0000
44+++ interfaces/R/src/rinterface.c.in 2011-05-26 21:28:30 +0000
45@@ -8461,6 +8461,26 @@
46 return result;
47 }
48
49+
50+
51+SEXP R_igraph_simple_interconnected_islands_game(SEXP islands_n, SEXP islands_size, SEXP islands_pin, SEXP n_inter) {
52+
53+ igraph_t g;
54+ igraph_integer_t a=REAL(islands_n)[0];
55+ igraph_integer_t b=REAL(islands_size)[0];
56+ igraph_real_t c=REAL(islands_pin)[0];
57+ igraph_integer_t d=REAL(n_inter)[0];
58+ SEXP result;
59+
60+ igraph_simple_interconnected_islands_game(&g, a, b, c, d);
61+ PROTECT(result=R_igraph_to_SEXP(&g));
62+ igraph_destroy(&g);
63+
64+ UNPROTECT(1);
65+ return result;
66+}
67+
68+
69 /***********************************************/
70 /* THE REST IS GENERATED BY inger.py */
71 /***********************************************/
72
73=== modified file 'src/games.c'
74--- src/games.c 2011-05-15 17:07:38 +0000
75+++ src/games.c 2011-05-26 21:28:30 +0000
76@@ -2975,3 +2975,151 @@
77 IGRAPH_FINALLY_CLEAN(1);
78 return 0;
79 }
80+
81+
82+
83+/**
84+ * \ingroup generators
85+ * \function igraph_simple_interconnected_islands_game
86+ * \brief Generates a random graph made of several interconnected islands, each island being a random graph.
87+ *
88+ * \param graph Pointer to an uninitialized graph object.
89+ * \param islands_n The number of islands in the graph.
90+ * \param islands_size The size of islands in the graph.
91+ * \param islands_pin The probability to create each possible edge into each island .
92+ * \param n_inter The number of edges to create between two islands .
93+
94+ * \return Error code:
95+ * \c IGRAPH_EINVAL: invalid parameter
96+ * \c IGRAPH_ENOMEM: there is not enought
97+ * memory for the operation.
98+ *
99+ * Time complexity: O(|V|+|E|), the
100+ * number of vertices plus the number of edges in the graph.
101+ *
102+ */
103+int igraph_simple_interconnected_islands_game(
104+ igraph_t *graph,
105+ igraph_integer_t islands_n,
106+ igraph_integer_t islands_size,
107+ igraph_real_t islands_pin,
108+ igraph_integer_t n_inter) {
109+
110+
111+ igraph_vector_t edges=IGRAPH_VECTOR_NULL;
112+ igraph_vector_t s=IGRAPH_VECTOR_NULL;
113+ int retval=0;
114+
115+ if (islands_n<0) {
116+ IGRAPH_ERROR("Invalid number of islands", IGRAPH_EINVAL);
117+ }
118+ if (islands_size<0) {
119+ IGRAPH_ERROR("Invalid size for islands", IGRAPH_EINVAL);
120+ }
121+ if (islands_pin<0 || islands_pin>1) {
122+ IGRAPH_ERROR("Invalid probability for islands", IGRAPH_EINVAL);
123+ }
124+ if ( (n_inter<0) || (n_inter>islands_size) ) {
125+ IGRAPH_ERROR("Invalid number of inter-islands links", IGRAPH_EINVAL);
126+ }
127+
128+ // how much memory ?
129+ int nbNodes = islands_n*islands_size;
130+ double maxpossibleedgesPerIsland = ((double)islands_size*((double)islands_size-(double)1))/(double)2;
131+ double maxedgesPerIsland = islands_pin*maxpossibleedgesPerIsland;
132+ int nbEdgesInterIslands = n_inter*(islands_n*(islands_n-1))/2;
133+ double maxedges = maxedgesPerIsland*islands_n + nbEdgesInterIslands;
134+
135+ // debug&tests : printf("total nodes %d, maxedgesperisland %f, maxedgesinterislands %d, maxedges %f\n", nbNodes, maxedgesPerIsland, nbEdgesInterIslands, maxedges);
136+
137+ // reserve enough place for all the edges, thanks !
138+ IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);
139+ IGRAPH_CHECK(igraph_vector_reserve(&edges, maxedges));
140+
141+ RNG_BEGIN();
142+
143+ // first create all the islands
144+
145+ int startIsland = 0;
146+ int endIsland = 0;
147+ int i,j, is;
148+ for (is=1; is<=islands_n; is++) { // for each island
149+
150+ long int slen;
151+
152+ // index for start and end of nodes in this island
153+ startIsland = islands_size*(is-1);
154+ endIsland = startIsland+islands_size -1;
155+
156+
157+ // debug&tests : printf("start %d,end %d\n", startIsland, endIsland);
158+
159+ // create the random numbers to be used (into s)
160+ IGRAPH_VECTOR_INIT_FINALLY(&s, 0);
161+ IGRAPH_CHECK(igraph_vector_reserve(&s, maxedgesPerIsland));
162+
163+
164+
165+ double rand;
166+ double last=RNG_GEOM(islands_pin);
167+ // debug&tests : printf("last=%f \n", last);
168+ while (last < maxpossibleedgesPerIsland) { // maxedgesPerIsland
169+ IGRAPH_CHECK(igraph_vector_push_back(&s, last));
170+ rand = RNG_GEOM(islands_pin);
171+ last += rand; //RNG_GEOM(islands_pin);
172+ //printf("rand=%f , last=%f \n", rand, last);
173+ last += 1;
174+ }
175+
176+
177+
178+ // change this to edges !
179+ for (i=0; i<igraph_vector_size(&s); i++) {
180+
181+ long int to=floor((sqrt(8*VECTOR(s)[i]+1)+1)/2);
182+ long int from=VECTOR(s)[i]-(((igraph_real_t)to)*(to-1))/2;
183+ to += startIsland;
184+ from += startIsland;
185+ // debug&tests : printf("from %d to %d\n", from, to);
186+ igraph_vector_push_back(&edges, from);
187+ igraph_vector_push_back(&edges, to);
188+ }
189+
190+ // clear the memory used for random number for this island
191+ igraph_vector_destroy(&s);
192+ IGRAPH_FINALLY_CLEAN(1);
193+
194+
195+ // create the links with other islands
196+ for (i=is+1; i<=islands_n; i++) { // for each other island (not the previous ones)
197+
198+ // debug&tests : printf("link islands %d and %d\n", is, i);
199+ for (j=0; j<n_inter; j++) { // for each link between islands
200+
201+ long int from = RNG_UNIF(startIsland, endIsland);
202+ long int to = RNG_UNIF((i-1)*islands_size, i*islands_size);
203+ //printf("from %d to %d\n", from, to);
204+ igraph_vector_push_back(&edges, from);
205+ igraph_vector_push_back(&edges, to);
206+ }
207+
208+ }
209+ }
210+
211+
212+
213+ RNG_END();
214+
215+
216+ // actually fill the graph object
217+ IGRAPH_CHECK(retval=igraph_create(graph, &edges, nbNodes, 0));
218+
219+ // an clear remaining things
220+ igraph_vector_destroy(&edges);
221+ IGRAPH_FINALLY_CLEAN(1);
222+
223+
224+ return retval;
225+
226+}
227+

Subscribers

People subscribed via source and target branches