4
Copyright (C) 2005 Gabor Csardi <csardi@rmki.kfki.hu>
5
MTA RMKI, Konkoly-Thege Miklos st. 29-33, Budapest 1121, Hungary
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
33
* \section about_generators
35
* <para>Graph generators create graphs.</para>
37
* <para>Almost all functions which create graph objects are documented
38
* here. The exceptions are \ref igraph_subgraph() and alike, these
39
* create graphs based on another graph.</para>
45
* \function igraph_create
46
* \brief Creates a graph with the specified edges.
48
* \param graph An uninitialized graph object.
49
* \param edges The edges to add, the first two elements are the first
51
* \param n The number of vertices in the graph, if smaller or equal
52
* to the highest vertex id in the \p edges vector it
53
* will be increased automatically. So it is safe to give 0
55
* \param directed Boolean, whether to create a directed graph or
56
* not. If yes, then the first edge points from the first
57
* vertex id in \p edges to the second, etc.
59
* \c IGRAPH_EINVEVECTOR: invalid edges
60
* vector (odd number of vertices).
61
* \c IGRAPH_EINVVID: invalid (negative)
64
* Time complexity: O(|V|+|E|),
65
* |V| is the number of vertices,
66
* |E| the number of edges in the
69
int igraph_create(igraph_t *graph, const igraph_vector_t *edges, igraph_integer_t n,
70
igraph_bool_t directed) {
71
igraph_real_t max=igraph_vector_max(edges)+1;
73
if (igraph_vector_size(edges) % 2 != 0) {
74
IGRAPH_ERROR("Invalid (odd) edges vector", IGRAPH_EINVEVECTOR);
76
if (!igraph_vector_isininterval(edges, 0, max-1)) {
77
IGRAPH_ERROR("Invalid (negative) vertex id", IGRAPH_EINVVID);
80
IGRAPH_CHECK(igraph_empty(graph, n, directed));
81
IGRAPH_FINALLY(igraph_destroy, graph);
82
if (igraph_vector_size(edges)>0) {
83
igraph_integer_t vc=igraph_vcount(graph);
85
IGRAPH_CHECK(igraph_add_vertices(graph, max-vc, 0));
87
IGRAPH_CHECK(igraph_add_edges(graph, edges, 0));
90
IGRAPH_FINALLY_CLEAN(1);
94
int igraph_i_adjacency_directed(igraph_matrix_t *adjmatrix, igraph_vector_t *edges) {
96
long int no_of_nodes=igraph_matrix_nrow(adjmatrix);
99
for (i=0; i<no_of_nodes; i++) {
100
for (j=0; j<no_of_nodes; j++) {
101
long int M=MATRIX(*adjmatrix, i, j);
102
for (k=0; k<M; k++) {
103
IGRAPH_CHECK(igraph_vector_push_back(edges, i));
104
IGRAPH_CHECK(igraph_vector_push_back(edges, j));
112
int igraph_i_adjacency_max(igraph_matrix_t *adjmatrix, igraph_vector_t *edges) {
114
long int no_of_nodes=igraph_matrix_nrow(adjmatrix);
117
for (i=0; i<no_of_nodes; i++) {
118
for (j=i; j<no_of_nodes; j++) {
119
long int M1=MATRIX(*adjmatrix, i, j);
120
long int M2=MATRIX(*adjmatrix, j, i);
121
if (M1<M2) { M1=M2; }
122
for (k=0; k<M1; k++) {
123
IGRAPH_CHECK(igraph_vector_push_back(edges, i));
124
IGRAPH_CHECK(igraph_vector_push_back(edges, j));
132
int igraph_i_adjacency_upper(igraph_matrix_t *adjmatrix, igraph_vector_t *edges) {
134
long int no_of_nodes=igraph_matrix_nrow(adjmatrix);
137
for (i=0; i<no_of_nodes; i++) {
138
for (j=i; j<no_of_nodes; j++) {
139
long int M=MATRIX(*adjmatrix, i, j);
140
for (k=0; k<M; k++) {
141
IGRAPH_CHECK(igraph_vector_push_back(edges, i));
142
IGRAPH_CHECK(igraph_vector_push_back(edges, j));
149
int igraph_i_adjacency_lower(igraph_matrix_t *adjmatrix, igraph_vector_t *edges) {
151
long int no_of_nodes=igraph_matrix_nrow(adjmatrix);
154
for (i=0; i<no_of_nodes; i++) {
155
for (j=0; j<=i; j++) {
156
long int M=MATRIX(*adjmatrix, i, j);
157
for (k=0; k<M; k++) {
158
IGRAPH_CHECK(igraph_vector_push_back(edges, i));
159
IGRAPH_CHECK(igraph_vector_push_back(edges, j));
166
int igraph_i_adjacency_min(igraph_matrix_t *adjmatrix, igraph_vector_t *edges) {
168
long int no_of_nodes=igraph_matrix_nrow(adjmatrix);
171
for (i=0; i<no_of_nodes; i++) {
172
for (j=i; j<no_of_nodes; j++) {
173
long int M1=MATRIX(*adjmatrix, i, j);
174
long int M2=MATRIX(*adjmatrix, j, i);
175
if (M1>M2) { M1=M2; }
176
for (k=0; k<M1; k++) {
177
IGRAPH_CHECK(igraph_vector_push_back(edges, i));
178
IGRAPH_CHECK(igraph_vector_push_back(edges, j));
187
* \ingroup generators
188
* \function igraph_adjacency
189
* \brief Creates a graph object from an adjacency matrix.
191
* The order of the vertices in the matrix is preserved, i.e. the vertex
192
* corresponding to the first row/column will be vertex with id 0, the
193
* next row is for vertex 1, etc.
194
* \param graph Pointer to an uninitialized graph object.
195
* \param adjmatrix The adjacency matrix. How it is interpreted
196
* depends on the \p mode argument.
197
* \param mode Constant to specify how the given matrix is interpreted
198
* as an adjacency matrix. Possible values
200
* is the element in row i and column
201
* j in the adjacency matrix
204
* \cli IGRAPH_ADJ_DIRECTED
205
* the graph will be directed and
206
* an element gives the number of edges between two vertices.
207
* \cli IGRAPH_ADJ_UNDIRECTED
208
* this is the same as \c IGRAPH_ADJ_MAX,
210
* \cli IGRAPH_ADJ_MAX
211
* undirected graph will be created
212
* and the number of edges between vertex
215
* max(A(i,j), A(j,i)).
216
* \cli IGRAPH_ADJ_MIN
217
* undirected graph will be created
218
* with min(A(i,j), A(j,i))
219
* edges between vertex
222
* \cli IGRAPH_ADJ_PLUS
223
* undirected graph will be created
224
* with A(i,j)+A(j,i) edges
228
* \cli IGRAPH_ADJ_UPPER
229
* undirected graph will be created,
230
* only the upper right triangle (including the diagonal) is
231
* used for the number of edges.
232
* \cli IGRAPH_ADJ_LOWER
233
* undirected graph will be created,
234
* only the lower left triangle (including the diagonal) is
235
* used for creating the edges.
237
* \return Error code,
238
* \c IGRAPH_NONSQUARE: non-square matrix.
240
* Time complexity: O(|V||V|),
241
* |V| is the number of vertices in the graph.
244
int igraph_adjacency(igraph_t *graph, igraph_matrix_t *adjmatrix,
245
igraph_adjacency_t mode) {
247
igraph_vector_t edges=IGRAPH_VECTOR_NULL;
248
long int no_of_nodes;
251
if (igraph_matrix_nrow(adjmatrix) != igraph_matrix_ncol(adjmatrix)) {
252
IGRAPH_ERROR("Non-square matrix", IGRAPH_NONSQUARE);
255
IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);
257
/* Collect the edges */
258
no_of_nodes=igraph_matrix_nrow(adjmatrix);
260
case IGRAPH_ADJ_DIRECTED:
261
IGRAPH_CHECK(igraph_i_adjacency_directed(adjmatrix, &edges));
264
IGRAPH_CHECK(igraph_i_adjacency_max(adjmatrix, &edges));
266
case IGRAPH_ADJ_UPPER:
267
IGRAPH_CHECK(igraph_i_adjacency_upper(adjmatrix, &edges));
269
case IGRAPH_ADJ_LOWER:
270
IGRAPH_CHECK(igraph_i_adjacency_lower(adjmatrix, &edges));
273
IGRAPH_CHECK(igraph_i_adjacency_min(adjmatrix, &edges));
275
case IGRAPH_ADJ_PLUS:
276
IGRAPH_CHECK(igraph_i_adjacency_directed(adjmatrix, &edges));
280
IGRAPH_CHECK(igraph_create(graph, &edges, no_of_nodes,
281
(mode == IGRAPH_ADJ_DIRECTED)));
282
igraph_vector_destroy(&edges);
283
IGRAPH_FINALLY_CLEAN(1);
288
int igraph_i_weighted_adjacency_directed(igraph_matrix_t *adjmatrix,
289
igraph_vector_t *edges, igraph_vector_t *weights) {
291
long int no_of_nodes=igraph_matrix_nrow(adjmatrix);
294
for (i=0; i<no_of_nodes; i++) {
295
for (j=0; j<no_of_nodes; j++) {
296
igraph_real_t M=MATRIX(*adjmatrix, i, j);
297
if (M == 0.0) continue;
298
IGRAPH_CHECK(igraph_vector_push_back(edges, i));
299
IGRAPH_CHECK(igraph_vector_push_back(edges, j));
300
IGRAPH_CHECK(igraph_vector_push_back(weights, M));
307
int igraph_i_weighted_adjacency_plus(igraph_matrix_t *adjmatrix,
308
igraph_vector_t *edges, igraph_vector_t *weights) {
310
long int no_of_nodes=igraph_matrix_nrow(adjmatrix);
313
for (i=0; i<no_of_nodes; i++) {
314
for (j=i; j<no_of_nodes; j++) {
315
igraph_real_t M=MATRIX(*adjmatrix, i, j) + MATRIX(*adjmatrix, j, i);
316
if (M == 0.0) continue;
318
IGRAPH_CHECK(igraph_vector_push_back(edges, i));
319
IGRAPH_CHECK(igraph_vector_push_back(edges, j));
320
IGRAPH_CHECK(igraph_vector_push_back(weights, M));
327
int igraph_i_weighted_adjacency_max(igraph_matrix_t *adjmatrix,
328
igraph_vector_t *edges, igraph_vector_t *weights) {
330
long int no_of_nodes=igraph_matrix_nrow(adjmatrix);
333
for (i=0; i<no_of_nodes; i++) {
334
for (j=i; j<no_of_nodes; j++) {
335
igraph_real_t M1=MATRIX(*adjmatrix, i, j);
336
igraph_real_t M2=MATRIX(*adjmatrix, j, i);
337
if (M1<M2) { M1=M2; }
338
if (M1 == 0.0) continue;
339
IGRAPH_CHECK(igraph_vector_push_back(edges, i));
340
IGRAPH_CHECK(igraph_vector_push_back(edges, j));
341
IGRAPH_CHECK(igraph_vector_push_back(weights, M1));
347
int igraph_i_weighted_adjacency_upper(igraph_matrix_t *adjmatrix,
348
igraph_vector_t *edges, igraph_vector_t *weights) {
350
long int no_of_nodes=igraph_matrix_nrow(adjmatrix);
353
for (i=0; i<no_of_nodes; i++) {
354
for (j=i; j<no_of_nodes; j++) {
355
igraph_real_t M=MATRIX(*adjmatrix, i, j);
356
if (M == 0.0) continue;
357
IGRAPH_CHECK(igraph_vector_push_back(edges, i));
358
IGRAPH_CHECK(igraph_vector_push_back(edges, j));
359
IGRAPH_CHECK(igraph_vector_push_back(weights, M));
365
int igraph_i_weighted_adjacency_lower(igraph_matrix_t *adjmatrix,
366
igraph_vector_t *edges, igraph_vector_t *weights) {
368
long int no_of_nodes=igraph_matrix_nrow(adjmatrix);
371
for (i=0; i<no_of_nodes; i++) {
372
for (j=0; j<=i; j++) {
373
igraph_real_t M=MATRIX(*adjmatrix, i, j);
374
if (M == 0.0) continue;
375
IGRAPH_CHECK(igraph_vector_push_back(edges, i));
376
IGRAPH_CHECK(igraph_vector_push_back(edges, j));
377
IGRAPH_CHECK(igraph_vector_push_back(weights, M));
383
int igraph_i_weighted_adjacency_min(igraph_matrix_t *adjmatrix,
384
igraph_vector_t *edges, igraph_vector_t *weights) {
386
long int no_of_nodes=igraph_matrix_nrow(adjmatrix);
389
for (i=0; i<no_of_nodes; i++) {
390
for (j=i; j<no_of_nodes; j++) {
391
igraph_real_t M1=MATRIX(*adjmatrix, i, j);
392
igraph_real_t M2=MATRIX(*adjmatrix, j, i);
393
if (M1>M2) { M1=M2; }
394
if (M1 == 0.0) continue;
395
IGRAPH_CHECK(igraph_vector_push_back(edges, i));
396
IGRAPH_CHECK(igraph_vector_push_back(edges, j));
397
IGRAPH_CHECK(igraph_vector_push_back(weights, M1));
405
* \ingroup generators
406
* \function igraph_weighted_adjacency
407
* \brief Creates a graph object from a weighted adjacency matrix.
409
* The order of the vertices in the matrix is preserved, i.e. the vertex
410
* corresponding to the first row/column will be vertex with id 0, the
411
* next row is for vertex 1, etc.
412
* \param graph Pointer to an uninitialized graph object.
413
* \param adjmatrix The weighted adjacency matrix. How it is interpreted
414
* depends on the \p mode argument. The common feature is that
415
* edges with zero weights are considered nonexistent (however,
416
* negative weights are permitted).
417
* \param mode Constant to specify how the given matrix is interpreted
418
* as an adjacency matrix. Possible values
420
* is the element in row i and column
421
* j in the adjacency matrix
424
* \cli IGRAPH_ADJ_DIRECTED
425
* the graph will be directed and
426
* an element gives the weight of the edge between two vertices.
427
* \cli IGRAPH_ADJ_UNDIRECTED
428
* this is the same as \c IGRAPH_ADJ_MAX,
430
* \cli IGRAPH_ADJ_MAX
431
* undirected graph will be created
432
* and the weight of the edge between vertex
435
* max(A(i,j), A(j,i)).
436
* \cli IGRAPH_ADJ_MIN
437
* undirected graph will be created
438
* with edge weight min(A(i,j), A(j,i))
442
* \cli IGRAPH_ADJ_PLUS
443
* undirected graph will be created
444
* with edge weight A(i,j)+A(j,i)
448
* \cli IGRAPH_ADJ_UPPER
449
* undirected graph will be created,
450
* only the upper right triangle (including the diagonal) is
451
* used for the edge weights.
452
* \cli IGRAPH_ADJ_LOWER
453
* undirected graph will be created,
454
* only the lower left triangle (including the diagonal) is
455
* used for the edge weights.
457
* \param attr the name of the attribute that will store the edge weights.
458
* If \c NULL , it will use \c weight as the attribute name.
459
* \return Error code,
460
* \c IGRAPH_NONSQUARE: non-square matrix.
462
* Time complexity: O(|V||V|),
463
* |V| is the number of vertices in the graph.a
466
int igraph_weighted_adjacency(igraph_t *graph, igraph_matrix_t *adjmatrix,
467
igraph_adjacency_t mode, const char* attr) {
469
igraph_vector_t edges=IGRAPH_VECTOR_NULL;
470
igraph_vector_t weights=IGRAPH_VECTOR_NULL;
471
const char* default_attr = "weight";
472
igraph_vector_ptr_t attr_vec;
473
igraph_i_attribute_record_t attr_rec;
474
long int no_of_nodes;
477
if (igraph_matrix_nrow(adjmatrix) != igraph_matrix_ncol(adjmatrix)) {
478
IGRAPH_ERROR("Non-square matrix", IGRAPH_NONSQUARE);
481
IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);
482
IGRAPH_VECTOR_INIT_FINALLY(&weights, 0);
483
IGRAPH_VECTOR_PTR_INIT_FINALLY(&attr_vec, 1);
485
/* Collect the edges */
486
no_of_nodes=igraph_matrix_nrow(adjmatrix);
488
case IGRAPH_ADJ_DIRECTED:
489
IGRAPH_CHECK(igraph_i_weighted_adjacency_directed(adjmatrix, &edges, &weights));
492
IGRAPH_CHECK(igraph_i_weighted_adjacency_max(adjmatrix, &edges, &weights));
494
case IGRAPH_ADJ_UPPER:
495
IGRAPH_CHECK(igraph_i_weighted_adjacency_upper(adjmatrix, &edges, &weights));
497
case IGRAPH_ADJ_LOWER:
498
IGRAPH_CHECK(igraph_i_weighted_adjacency_lower(adjmatrix, &edges, &weights));
501
IGRAPH_CHECK(igraph_i_weighted_adjacency_min(adjmatrix, &edges, &weights));
503
case IGRAPH_ADJ_PLUS:
504
IGRAPH_CHECK(igraph_i_weighted_adjacency_plus(adjmatrix, &edges, &weights));
508
/* Prepare attribute record */
509
attr_rec.name = attr ? attr : default_attr;
510
attr_rec.type = IGRAPH_ATTRIBUTE_NUMERIC;
511
attr_rec.value = &weights;
512
VECTOR(attr_vec)[0] = &attr_rec;
515
IGRAPH_CHECK(igraph_empty(graph, no_of_nodes, (mode == IGRAPH_ADJ_DIRECTED)));
516
IGRAPH_FINALLY(igraph_destroy, graph);
517
if (igraph_vector_size(&edges)>0) {
518
IGRAPH_CHECK(igraph_add_edges(graph, &edges, &attr_vec));
520
IGRAPH_FINALLY_CLEAN(1);
523
igraph_vector_destroy(&edges);
524
igraph_vector_destroy(&weights);
525
igraph_vector_ptr_destroy(&attr_vec);
526
IGRAPH_FINALLY_CLEAN(3);
532
* \ingroup generators
533
* \function igraph_star
534
* \brief Creates a \em star graph, every vertex connects only to the center.
536
* \param graph Pointer to an uninitialized graph object, this will
538
* \param n Integer constant, the number of vertices in the graph.
539
* \param mode Constant, gives the type of the star graph to
540
* create. Possible values:
542
* \cli IGRAPH_STAR_OUT
543
* directed star graph, edges point
544
* \em from the center to the other vertices.
545
* \cli IGRAPH_STAR_IN
546
* directed star graph, edges point
547
* \em to the center from the other vertices.
548
* \cli IGRAPH_STAR_UNDIRECTED
549
* an undirected star graph is
552
* \param center Id of the vertex which will be the center of the
554
* \return Error code:
556
* \cli IGRAPH_EINVVID
557
* invalid number of vertices.
559
* invalid center vertex.
560
* \cli IGRAPH_EINVMODE
561
* invalid mode argument.
564
* Time complexity: O(|V|), the
565
* number of vertices in the graph.
567
* \sa \ref igraph_lattice(), \ref igraph_ring(), \ref igraph_tree()
568
* for creating other regular structures.
571
int igraph_star(igraph_t *graph, igraph_integer_t n, igraph_star_mode_t mode,
572
igraph_integer_t center) {
574
igraph_vector_t edges=IGRAPH_VECTOR_NULL;
578
IGRAPH_ERROR("Invalid number of vertices", IGRAPH_EINVVID);
580
if (center<0 || center >n-1) {
581
IGRAPH_ERROR("Invalid center vertex", IGRAPH_EINVAL);
583
if (mode != IGRAPH_STAR_OUT && mode != IGRAPH_STAR_IN &&
584
mode != IGRAPH_STAR_UNDIRECTED) {
585
IGRAPH_ERROR("invalid mode", IGRAPH_EINVMODE);
588
IGRAPH_VECTOR_INIT_FINALLY(&edges, (n-1)*2);
590
if (mode == IGRAPH_STAR_OUT) {
591
for (i=0; i<center; i++) {
592
VECTOR(edges)[2*i]=center;
593
VECTOR(edges)[2*i+1]=i;
595
for (i=center+1; i<n; i++) {
596
VECTOR(edges)[2*(i-1)]=center;
597
VECTOR(edges)[2*(i-1)+1]=i;
600
for (i=0; i<center; i++) {
601
VECTOR(edges)[2*i+1]=center;
602
VECTOR(edges)[2*i]=i;
604
for (i=center+1; i<n; i++) {
605
VECTOR(edges)[2*(i-1)+1]=center;
606
VECTOR(edges)[2*(i-1)]=i;
610
IGRAPH_CHECK(igraph_create(graph, &edges, 0,
611
(mode != IGRAPH_STAR_UNDIRECTED)));
612
igraph_vector_destroy(&edges);
613
IGRAPH_FINALLY_CLEAN(1);
619
* \ingroup generators
620
* \function igraph_lattice
621
* \brief Creates most kind of lattices.
623
* \param graph An uninitialized graph object.
624
* \param dimvector Vector giving the sizes of the lattice in each of
625
* its dimensions. Ie. the dimension of the lattice will be the
626
* same as the length of this vector.
627
* \param nei Integer value giving the distance (number of steps)
628
* within which two vertices will be connected. Not implemented
630
* \param directed Boolean, whether to create a directed graph. The
631
* direction of the edges is determined by the generation
632
* algorithm and is unlikely to suit you, so this isn't a very
634
* \param mutual Boolean, if the graph is directed this gives whether
635
* to create all connections as mutual.
636
* \param circular Boolean, defines whether the generated lattice is
638
* \return Error code:
639
* \c IGRAPH_EINVAL: invalid (negative)
642
* Time complexity: if \p nei is less than two then it is O(|V|+|E|) (as
643
* far as i remember), |V| and |E| are the number of vertices
644
* and edges in the generated graph. Otherwise it is O(|V|*d^o+|E|), d
645
* is the average degree of the graph, o is the \p nei argument.
647
int igraph_lattice(igraph_t *graph, const igraph_vector_t *dimvector, igraph_integer_t nei,
648
igraph_bool_t directed, igraph_bool_t mutual, igraph_bool_t circular) {
650
long int dims=igraph_vector_size(dimvector);
651
long int no_of_nodes=igraph_vector_prod(dimvector);
652
igraph_vector_t edges=IGRAPH_VECTOR_NULL;
653
long int *coords, *weights;
657
if (igraph_vector_any_smaller(dimvector, 0)) {
658
IGRAPH_ERROR("Invalid dimension vector", IGRAPH_EINVAL);
661
/* init coords & weights */
663
coords=igraph_Calloc(dims, long int);
665
IGRAPH_ERROR("lattice failed", IGRAPH_ENOMEM);
667
IGRAPH_FINALLY(free, coords); /* TODO: hack */
668
weights=igraph_Calloc(dims, long int);
670
IGRAPH_ERROR("lattice failed", IGRAPH_ENOMEM);
672
IGRAPH_FINALLY(free, weights);
674
for (i=1; i<dims; i++) {
675
weights[i]=weights[i-1]*VECTOR(*dimvector)[i-1];
678
IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);
679
IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_nodes*dims +
680
mutual*directed * no_of_nodes*dims));
682
for (i=0; i<no_of_nodes; i++) {
683
IGRAPH_ALLOW_INTERRUPTION();
684
for (j=0; j<dims; j++) {
685
if (circular || coords[j] != VECTOR(*dimvector)[j]-1) {
687
if (coords[j] != VECTOR(*dimvector)[j]-1) {
688
new_nei = i + weights[j] + 1;
690
new_nei = i - (VECTOR(*dimvector)[j]-1) * weights[j] + 1;
692
if (new_nei != i+1 && (VECTOR(*dimvector)[j] != 2 || coords[j] != 1)) {
693
igraph_vector_push_back(&edges, i); /* reserved */
694
igraph_vector_push_back(&edges, new_nei-1); /* reserved */
696
} /* if circular || coords[j] */
697
if (mutual && directed && (circular || coords[j] != 0)) {
700
new_nei=i-weights[j]+1;
702
new_nei=i+(VECTOR(*dimvector)[j]-1) * weights[j]+1;
704
if (VECTOR(*dimvector)[j] != 2 || coords[j] != 0) {
705
igraph_vector_push_back(&edges, i); /* reserved */
706
igraph_vector_push_back(&edges, new_nei-1); /* reserved */
708
} /* if circular || coords[0] */
711
/* increase coords */
715
while (carry==1 && pos != dims) {
716
if (coords[pos] != VECTOR(*dimvector)[pos]-1) {
725
} /* for i<no_of_nodes */
727
IGRAPH_CHECK(igraph_create(graph, &edges, 0, directed));
729
IGRAPH_CHECK(igraph_connect_neighborhood(graph, nei, IGRAPH_ALL));
734
igraph_Free(weights);
735
igraph_vector_destroy(&edges);
736
IGRAPH_FINALLY_CLEAN(3);
742
* \ingroup generators
743
* \function igraph_ring
744
* \brief Creates a \em ring graph, a one dimensional lattice.
746
* \param graph Pointer to an uninitialized graph object.
747
* \param n The number of vertices in the ring.
748
* \param directed Logical, whether to create a directed ring.
749
* \param mutual Logical, whether to create mutual edges in a directed
750
* ring. It is ignored for undirected graphs.
751
* \param circular Logical, if false, the ring will be open (this is
752
* not a real \em ring actually).
753
* \return Error code:
754
* \c IGRAPH_EINVAL: invalid number of vertices.
756
* Time complexity: O(|V|), the
757
* number of vertices in the graph.
759
* \sa \ref igraph_lattice() for generating more general lattices.
762
int igraph_ring(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed, igraph_bool_t mutual,
763
igraph_bool_t circular) {
765
igraph_vector_t v=IGRAPH_VECTOR_NULL;
768
IGRAPH_ERROR("negative number of vertices", IGRAPH_EINVAL);
771
IGRAPH_VECTOR_INIT_FINALLY(&v, 1);
774
IGRAPH_CHECK(igraph_lattice(graph, &v, 1, directed, mutual, circular));
775
igraph_vector_destroy(&v);
777
IGRAPH_FINALLY_CLEAN(1);
782
* \ingroup generators
783
* \function igraph_tree
784
* \brief Creates a tree in which almost all vertices have the same number of children.
786
* \param graph Pointer to an uninitialized graph object.
787
* \param n Integer, the number of vertices in the graph.
788
* \param children Integer, the number of children of a vertex in the
790
* \param type Constant, gives whether to create a directed tree, and
791
* if this is the case, also its orientation. Possible values:
793
* \cli IGRAPH_TREE_OUT
794
* directed tree, the edges point
795
* from the parents to their children,
796
* \cli IGRAPH_TREE_IN
797
* directed tree, the edges point from
798
* the children to their parents.
799
* \cli IGRAPH_TREE_UNDIRECTED
802
* \return Error code:
803
* \c IGRAPH_EINVAL: invalid number of vertices.
804
* \c IGRAPH_INVMODE: invalid mode argument.
806
* Time complexity: O(|V|+|E|), the
807
* number of vertices plus the number of edges in the graph.
809
* \sa \ref igraph_lattice(), \ref igraph_star() for creating other regular
813
int igraph_tree(igraph_t *graph, igraph_integer_t n, igraph_integer_t children,
814
igraph_tree_mode_t type) {
816
igraph_vector_t edges=IGRAPH_VECTOR_NULL;
821
if (n<0 || children<=0) {
822
IGRAPH_ERROR("Invalid number of vertices or children", IGRAPH_EINVAL);
824
if (type != IGRAPH_TREE_OUT && type != IGRAPH_TREE_IN &&
825
type != IGRAPH_TREE_UNDIRECTED) {
826
IGRAPH_ERROR("Invalid mode argument", IGRAPH_EINVMODE);
829
IGRAPH_VECTOR_INIT_FINALLY(&edges, 2*(n-1));
832
if (type == IGRAPH_TREE_OUT) {
833
while (idx<2*(n-1)) {
834
for (j=0; j<children && idx<2*(n-1); j++) {
835
VECTOR(edges)[idx++]=i;
836
VECTOR(edges)[idx++]=to++;
841
while (idx<2*(n-1)) {
842
for (j=0; j<children && idx<2*(n-1); j++) {
843
VECTOR(edges)[idx++]=to++;
844
VECTOR(edges)[idx++]=i;
850
IGRAPH_CHECK(igraph_create(graph, &edges, 0, type!=IGRAPH_TREE_UNDIRECTED));
852
igraph_vector_destroy(&edges);
853
IGRAPH_FINALLY_CLEAN(1);
858
* \ingroup generators
859
* \function igraph_full
860
* \brief Creates a full graph (directed or undirected, with or without loops).
863
* In a full graph every possible edge is present, every vertex is
864
* connected to every other vertex.
866
* \param graph Pointer to an uninitialized graph object.
867
* \param n Integer, the number of vertices in the graph.
868
* \param directed Logical, whether to create a directed graph.
869
* \param loops Logical, whether to include self-edges (loops).
870
* \return Error code:
871
* \c IGRAPH_EINVAL: invalid number of vertices.
873
* Time complexity: O(|V|+|E|),
874
* |V| is the number of vertices,
875
* |E| the number of edges in the
876
* graph. Of course this is the same as
880
* \sa \ref igraph_lattice(), \ref igraph_star(), \ref igraph_tree()
881
* for creating other regular structures.
884
int igraph_full(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed, igraph_bool_t loops) {
886
igraph_vector_t edges=IGRAPH_VECTOR_NULL;
890
IGRAPH_ERROR("invalid number of vertices", IGRAPH_EINVAL);
893
IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);
895
if (directed && loops) {
896
IGRAPH_CHECK(igraph_vector_reserve(&edges, n*n));
897
for (i=0; i<n; i++) {
898
for (j=0; j<n; j++) {
899
igraph_vector_push_back(&edges, i); /* reserved */
900
igraph_vector_push_back(&edges, j); /* reserved */
903
} else if (directed && !loops) {
904
IGRAPH_CHECK(igraph_vector_reserve(&edges, n*(n-1)));
905
for (i=0; i<n; i++) {
906
for (j=0; j<i; j++) {
907
igraph_vector_push_back(&edges, i); /* reserved */
908
igraph_vector_push_back(&edges, j); /* reserved */
910
for (j=i+1; j<n; j++) {
911
igraph_vector_push_back(&edges, i); /* reserved */
912
igraph_vector_push_back(&edges, j); /* reserved */
915
} else if (!directed && loops) {
916
IGRAPH_CHECK(igraph_vector_reserve(&edges, n*(n+1)/2));
917
for (i=0; i<n; i++) {
918
for (j=i; j<n; j++) {
919
igraph_vector_push_back(&edges, i); /* reserved */
920
igraph_vector_push_back(&edges, j); /* reserved */
924
IGRAPH_CHECK(igraph_vector_reserve(&edges, n*(n-1)/2));
925
for (i=0; i<n; i++) {
926
for (j=i+1; j<n; j++) {
927
igraph_vector_push_back(&edges, i); /* reserved */
928
igraph_vector_push_back(&edges, j); /* resreved */
933
IGRAPH_CHECK(igraph_create(graph, &edges, n, directed));
934
igraph_vector_destroy(&edges);
935
IGRAPH_FINALLY_CLEAN(1);
941
* \function igraph_full_citation
942
* Creates a full citation graph
944
* This is a directed graph, where every <code>i->j</code> edge is
945
* present if and only if <code>j<i</code>.
946
* If the \c directed argument is zero then an undirected graph is
947
* created, and it is just a full graph.
948
* \param graph Pointer to an uninitialized graph object, the result
950
* \param n The number of vertices.
951
* \param directed Whether to created a directed graph. If zero an
952
* undirected graph is created.
953
* \return Error code.
955
* Time complexity: O(|V|^2), as we have many edges.
958
int igraph_full_citation(igraph_t *graph, igraph_integer_t n,
959
igraph_bool_t directed) {
960
igraph_vector_t edges;
961
long int i, j, ptr=0;
963
IGRAPH_VECTOR_INIT_FINALLY(&edges, n*(n-1));
964
for (i=1; i<n; i++) {
965
for (j=0; j<i; j++) {
966
VECTOR(edges)[ptr++] = i;
967
VECTOR(edges)[ptr++] = j;
971
IGRAPH_CHECK(igraph_create(graph, &edges, n, directed));
972
igraph_vector_destroy(&edges);
973
IGRAPH_FINALLY_CLEAN(1);
978
* \function igraph_small
979
* \brief Shortand to create a short graph, giving the edges as agruments
982
* This function is handy when a relatively small graph needs to be created.
983
* Instead giving the edges in vector, they are given simply as
984
* arguments and a '-1' needs to be given after the last meaningful
987
* </para><para>Note that only graphs which have vertices less than
988
* the highest value of the 'int' type can be created this way. If you
989
* give larger values then the result is undefined.
991
* \param graph Pointer to an uninitialized graph object, the result
992
* will be stored here.
993
* \param n The number of vertices in the graph, an integer.
994
* \param directed Logical constant, gives whether the graph should be
996
* \param ... The additional arguments giving the edges of the
997
* graph. Don't forget to supply an additional '-1' after the last
998
* (meaningful) argument.
999
* \return Error code.
1001
* Time complexity: O(|V|+|E|), the number of vertices plus the number
1002
* of edges in the graph to create.
1005
int igraph_small(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed,
1007
igraph_vector_t edges;
1010
IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);
1012
va_start(ap, directed);
1014
int num = va_arg(ap, int);
1018
igraph_vector_push_back(&edges, num);
1021
IGRAPH_CHECK(igraph_create(graph, &edges, n, directed));
1023
igraph_vector_destroy(&edges);
1024
IGRAPH_FINALLY_CLEAN(1);
1029
* \function igraph_extended_chordal_ring
1030
* Create an extended chordal ring
1032
* An extended chordal ring is regular graph, each node has the same
1033
* degree. It can be obtained from a simple ring by adding some extra
1034
* edges specified by a matrix. Let p denote the number of columns in
1035
* the <parameter>W</parameter> matrix. The extra edges of vertex i
1036
* are added according to column (i mod p) in
1037
* <parameter>W</parameter>. The number of extra edges is the number
1038
* of rows in <parameter>W</parameter>: for each row j an edge
1039
* i->i+w[ij] is added if i+w[ij] is less than the number of total
1043
* See also Kotsis, G: Interconnection Topologies for Parallel Processing
1044
* Systems, PARS Mitteilungen 11, 1-6, 1993.
1046
* \param graph Pointer to an uninitialized graph object, the result
1047
* will be stored here. The result is always an undirected graph.
1048
* \param nodes Integer constant, the number of vertices in the
1049
* graph. It must be at least 3.
1050
* \param W The matrix specifying the extra edges. The number of
1051
* columns should divide the number of total vertices.
1052
* \return Error code.
1054
* \sa \ref igraph_ring().
1056
* Time complexity: O(|V|+|E|), the number of vertices plus the number
1060
int igraph_extended_chordal_ring(igraph_t *graph, igraph_integer_t nodes,
1061
const igraph_matrix_t *W) {
1063
igraph_vector_t edges;
1064
long int period=igraph_matrix_ncol(W);
1065
long int degree=igraph_matrix_nrow(W)+2;
1066
long int i, j, mpos=0, epos=0;
1069
IGRAPH_ERROR("An extended chordal ring has at least 3 nodes",
1073
if ((long int)nodes % period != 0) {
1074
IGRAPH_ERROR("The period (number of columns in W) should divide the "
1075
"number of nodes", IGRAPH_EINVAL);
1078
IGRAPH_VECTOR_INIT_FINALLY(&edges, nodes*degree);
1080
for (i=0; i<nodes-1; i++) {
1081
VECTOR(edges)[epos++] = i;
1082
VECTOR(edges)[epos++] = i+1;
1084
VECTOR(edges)[epos++] = 0;
1085
VECTOR(edges)[epos++] = nodes-1;
1088
for (i=0; i<nodes; i++) {
1089
for (j=0; j<degree-2; j++) {
1090
long int offset=MATRIX(*W, j, mpos);
1091
if (i+offset < nodes) {
1092
VECTOR(edges)[epos++] = i;
1093
VECTOR(edges)[epos++] = i+offset;
1096
mpos++; if (mpos==period) { mpos=0; }
1100
igraph_vector_resize(&edges, epos);
1101
IGRAPH_CHECK(igraph_create(graph, &edges, nodes, IGRAPH_UNDIRECTED));
1102
igraph_vector_destroy(&edges);
1103
IGRAPH_FINALLY_CLEAN(1);
1108
* \function igraph_connect_neighborhood
1109
* \brief Connects every vertex to its neighborhood
1111
* This function adds new edges to graph. For each vertex
1112
* vertices reachable by at most \p order steps and not yet connected
1113
* to the vertex a new edge is created.
1115
* </para><para> Note that the input graph is modified in place, no
1116
* new graph is created, call \ref igraph_copy() if you want to keep
1117
* the original graph as well.
1119
* </para><para> For undirected graphs reachability is always
1120
* symmetric, if vertex A can be reached from vertex B in at
1121
* most \p order steps, then the opposite is also true. Only one
1122
* undirected (A,B) edge will be added in this case.
1123
* \param graph The input graph, this is the output graph as well.
1124
* \param order Integer constant, it gives the distance within which
1125
* the vertices will be connected to the source vertex.
1126
* \param mode Constant, it specifies how the neighborhood search is
1127
* performed for directed graphs. If \c IGRAPH_OUT then vertices
1128
* reachable from the source vertex will be connected, \c IGRAPH_IN
1129
* is the opposite. If \c IGRAPH_ALL then the directed graph is
1130
* considered as an undirected one.
1131
* \return Error code.
1133
* \sa \ref igraph_lattice() uses this function to connect the
1134
* neighborhood of the vertices.
1136
* Time complexity: O(|V|*d^o), |V| is the number of vertices in the
1137
* graph, d is the average degree and o is the \p order argument.
1140
int igraph_connect_neighborhood(igraph_t *graph, igraph_integer_t order,
1141
igraph_neimode_t mode) {
1143
long int no_of_nodes=igraph_vcount(graph);
1145
igraph_vector_t edges;
1148
igraph_vector_t neis;
1151
IGRAPH_ERROR("Negative order, cannot connect neighborhood", IGRAPH_EINVAL);
1155
IGRAPH_WARNING("Order smaller than two, graph will be unchanged");
1158
if (!igraph_is_directed(graph)) {
1162
IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);
1163
added=igraph_Calloc(no_of_nodes, long int);
1165
IGRAPH_ERROR("Cannot connect neighborhood", IGRAPH_ENOMEM);
1167
IGRAPH_FINALLY(igraph_free, added);
1168
IGRAPH_DQUEUE_INIT_FINALLY(&q, 100);
1169
IGRAPH_VECTOR_INIT_FINALLY(&neis, 0);
1171
for (i=0; i<no_of_nodes; i++) {
1173
igraph_neighbors(graph, &neis, i, mode);
1174
in=igraph_vector_size(&neis);
1176
for (j=0; j<in; j++) {
1177
long int nei=VECTOR(neis)[j];
1179
igraph_dqueue_push(&q, nei);
1180
igraph_dqueue_push(&q, 1);
1184
while (!igraph_dqueue_empty(&q)) {
1185
long int actnode=igraph_dqueue_pop(&q);
1186
long int actdist=igraph_dqueue_pop(&q);
1188
igraph_neighbors(graph, &neis, actnode, mode);
1189
n=igraph_vector_size(&neis);
1191
if (actdist<order-1) {
1192
for (j=0; j<n; j++) {
1193
long int nei=VECTOR(neis)[j];
1194
if (added[nei] != i+1) {
1196
IGRAPH_CHECK(igraph_dqueue_push(&q, nei));
1197
IGRAPH_CHECK(igraph_dqueue_push(&q, actdist+1));
1198
if (mode != IGRAPH_ALL || i < nei) {
1199
if (mode == IGRAPH_IN) {
1200
IGRAPH_CHECK(igraph_vector_push_back(&edges, nei));
1201
IGRAPH_CHECK(igraph_vector_push_back(&edges, i));
1203
IGRAPH_CHECK(igraph_vector_push_back(&edges, i));
1204
IGRAPH_CHECK(igraph_vector_push_back(&edges, nei));
1210
for (j=0; j<n; j++) {
1211
long int nei=VECTOR(neis)[j];
1212
if (added[nei] != i+1) {
1214
if (mode != IGRAPH_ALL || i < nei) {
1215
if (mode == IGRAPH_IN) {
1216
IGRAPH_CHECK(igraph_vector_push_back(&edges, nei));
1217
IGRAPH_CHECK(igraph_vector_push_back(&edges, i));
1219
IGRAPH_CHECK(igraph_vector_push_back(&edges, i));
1220
IGRAPH_CHECK(igraph_vector_push_back(&edges, nei));
1227
} /* while q not empty */
1228
} /* for i < no_of_nodes */
1230
igraph_vector_destroy(&neis);
1231
igraph_dqueue_destroy(&q);
1233
IGRAPH_FINALLY_CLEAN(3);
1235
IGRAPH_CHECK(igraph_add_edges(graph, &edges, 0));
1237
igraph_vector_destroy(&edges);
1238
IGRAPH_FINALLY_CLEAN(1);
1244
* \function igraph_de_bruijn
1245
* \brief Generate a de Bruijn graph.
1247
* A de Bruijn graph represents relationships between strings. An alphabet
1248
* of \c m letters are used and strings of length \c n are considered.
1249
* A vertex corresponds to every possible string and there is a directed edge
1250
* from vertex \c v to vertex \c w if the string of \c v can be transformed into
1251
* the string of \c w by removing its first letter and appending a letter to it.
1254
* Please note that the graph will have \c m to the power \c n vertices and
1255
* even more edges, so probably you don't want to supply too big numbers for
1259
* De Bruijn graphs have some interesting properties, please see another source,
1260
* eg. Wikipedia for details.
1262
* \param graph Pointer to an uninitialized graph object, the result will be
1264
* \param m Integer, the number of letters in the alphabet.
1265
* \param n Integer, the length of the strings.
1266
* \return Error code.
1268
* \sa \ref igraph_kautz().
1270
* Time complexity: O(|V|+|E|), the number of vertices plus the number of edges.
1273
int igraph_de_bruijn(igraph_t *graph, igraph_integer_t m, igraph_integer_t n) {
1275
/* m - number of symbols */
1276
/* n - length of strings */
1278
long int no_of_nodes, no_of_edges;
1279
igraph_vector_t edges;
1284
IGRAPH_ERROR("`m' and `n' should be non-negative in a de Bruijn graph",
1289
return igraph_empty(graph, 1, IGRAPH_DIRECTED);
1292
return igraph_empty(graph, 0, IGRAPH_DIRECTED);
1295
no_of_nodes=pow(m, n);
1296
no_of_edges=no_of_nodes*m;
1298
IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);
1299
IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_edges*2));
1301
for (i=0; i<no_of_nodes; i++) {
1302
long int basis=(i*mm) % no_of_nodes;
1303
for (j=0; j<m; j++) {
1304
igraph_vector_push_back(&edges, i);
1305
igraph_vector_push_back(&edges, basis+j);
1309
IGRAPH_CHECK(igraph_create(graph, &edges, no_of_nodes, IGRAPH_DIRECTED));
1311
igraph_vector_destroy(&edges);
1312
IGRAPH_FINALLY_CLEAN(1);
1318
* \function igraph_kautz
1319
* \brief Generate a Kautz graph.
1321
* A Kautz graph is a labeled graph, vertices are labeled by strings
1322
* of length \c n+1 above an alphabet with \c m+1 letters, with
1323
* the restriction that every two consecutive letters in the string
1324
* must be different. There is a directed edge from a vertex \c v to
1325
* another vertex \c w if it is possible to transform the string of
1326
* \c v into the string of \c w by removing the first letter and
1327
* appending a letter to it.
1330
* Kautz graphs have some interesting properties, see eg. Wikipedia
1334
* Vincent Matossian wrote the first version of this function in R,
1336
* \param graph Pointer to an uninitialized graph object, the result
1337
* will be stored here.
1338
* \param m Integer, \c m+1 is the number of letters in the alphabet.
1339
* \param n Integer, \c n+1 is the length of the strings.
1340
* \return Error code.
1342
* \sa \ref igraph_de_bruijn().
1344
* Time complexity: O(|V|* [(m+1)/m]^n +|E|), in practice it is more
1345
* like O(|V|+|E|). |V| is the number of vertices, |E| is the number
1346
* of edges and \c m and \c n are the corresponding arguments.
1349
int igraph_kautz(igraph_t *graph, igraph_integer_t m, igraph_integer_t n) {
1351
/* m+1 - number of symbols */
1352
/* n+1 - length of strings */
1355
long int no_of_nodes, no_of_edges;
1356
long int allstrings;
1357
long int i, j, idx=0;
1358
igraph_vector_t edges;
1359
igraph_vector_long_t digits, table;
1360
igraph_vector_long_t index, index2;
1362
long int actvalue=0;
1365
IGRAPH_ERROR("`m' and `n' should be non-negative in a Kautz graph",
1370
return igraph_full(graph, m+1, IGRAPH_DIRECTED, IGRAPH_NO_LOOPS);
1373
return igraph_empty(graph, 0, IGRAPH_DIRECTED);
1376
no_of_nodes=(m+1)*pow(m, n);
1377
no_of_edges=no_of_nodes*m;
1378
allstrings=pow(m+1, n+1);
1380
IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);
1382
IGRAPH_CHECK(igraph_vector_long_init(&table, n+1));
1383
IGRAPH_FINALLY(igraph_vector_long_destroy, &table);
1385
for (i=n; i>=0; i--) {
1390
IGRAPH_CHECK(igraph_vector_long_init(&digits, n+1));
1391
IGRAPH_FINALLY(igraph_vector_long_destroy, &digits);
1392
IGRAPH_CHECK(igraph_vector_long_init(&index, pow(m+1, n+1)));
1393
IGRAPH_FINALLY(igraph_vector_long_destroy, &index);
1394
IGRAPH_CHECK(igraph_vector_long_init(&index2, no_of_nodes));
1395
IGRAPH_FINALLY(igraph_vector_long_destroy, &index2);
1397
/* Fill the index tables*/
1399
/* at the beginning of the loop, 0:actb contain the valid prefix */
1400
/* we might need to fill it to get a valid string */
1402
if (VECTOR(digits)[actb]==0) { z=1; }
1403
for (actb++; actb<=n; actb++) {
1404
VECTOR(digits)[actb]=z;
1405
actvalue += z*VECTOR(table)[actb];
1410
/* ok, we have a valid string now */
1411
VECTOR(index)[actvalue]=idx+1;
1412
VECTOR(index2)[idx]=actvalue;
1416
if (idx >= no_of_nodes) { break; }
1418
/* not yet, we need a valid prefix now */
1420
/* try to increase digits at position actb */
1421
long int next=VECTOR(digits)[actb]+1;
1422
if (actb != 0 && VECTOR(digits)[actb-1]==next) { next++; }
1424
/* ok, no problem */
1425
actvalue += (next-VECTOR(digits)[actb])*VECTOR(table)[actb];
1426
VECTOR(digits)[actb]=next;
1429
/* bad luck, try the previous digit */
1430
actvalue -= VECTOR(digits)[actb]*VECTOR(table)[actb];
1436
IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_edges*2));
1438
/* Now come the edges at last */
1439
for (i=0; i<no_of_nodes; i++) {
1440
long int fromvalue=VECTOR(index2)[i];
1441
long int lastdigit=fromvalue % (mm+1);
1442
long int basis=(fromvalue * (mm+1)) % allstrings;
1443
for (j=0; j<=m; j++) {
1444
long int tovalue, to;
1445
if (j==lastdigit) { continue; }
1447
to=VECTOR(index)[tovalue]-1;
1448
if (to<0) { continue; }
1449
igraph_vector_push_back(&edges, i);
1450
igraph_vector_push_back(&edges, to);
1454
igraph_vector_long_destroy(&index2);
1455
igraph_vector_long_destroy(&index);
1456
igraph_vector_long_destroy(&digits);
1457
igraph_vector_long_destroy(&table);
1458
IGRAPH_FINALLY_CLEAN(4);
1460
IGRAPH_CHECK(igraph_create(graph, &edges, no_of_nodes, IGRAPH_DIRECTED));
1461
igraph_vector_destroy(&edges);
1462
IGRAPH_FINALLY_CLEAN(1);
1468
* \function igraph_lcf_vector
1469
* \brief Create a graph from LCF notation
1471
* This function is essentially the same as \ref igraph_lcf(), only
1472
* the way for giving the arguments is different. See \ref
1473
* igraph_lcf() for details.
1474
* \param graph Pointer to an uninitialized graph object.
1475
* \param n Integer constant giving the number of vertices.
1476
* \param shifts A vector giving the shifts.
1477
* \param repeats An integer constant giving the number of repeats
1479
* \return Error code.
1481
* \sa \ref igraph_lcf()
1483
* Time complexity: O(|V|+|E|), linear in the number of vertices plus
1484
* the number of edges.
1487
int igraph_lcf_vector(igraph_t *graph, igraph_integer_t n,
1488
const igraph_vector_t *shifts,
1489
igraph_integer_t repeats) {
1491
igraph_vector_t edges;
1492
long int no_of_shifts=igraph_vector_size(shifts);
1493
long int ptr=0, i, sptr=0;
1494
long int no_of_nodes=n;
1495
long int no_of_edges=n+no_of_shifts*repeats/2;
1497
if (repeats<0) IGRAPH_ERROR("number of repeats must be positive", IGRAPH_EINVAL);
1498
IGRAPH_VECTOR_INIT_FINALLY(&edges, 2*no_of_edges);
1500
/* Create a ring first */
1501
for (i=0; i<no_of_nodes; i++) {
1502
VECTOR(edges)[ptr++]=i;
1503
VECTOR(edges)[ptr++]=i+1;
1505
VECTOR(edges)[ptr-1]=0;
1507
/* Then add the rest */
1508
while (ptr<2*no_of_edges) {
1509
long int sh=VECTOR(*shifts)[sptr % no_of_shifts];
1510
long int from=sptr % no_of_nodes;
1511
long int to=(no_of_nodes+sptr+sh) % no_of_nodes;
1513
VECTOR(edges)[ptr++]=from;
1514
VECTOR(edges)[ptr++]=to;
1519
IGRAPH_CHECK(igraph_create(graph, &edges, no_of_nodes, IGRAPH_UNDIRECTED));
1520
igraph_vector_destroy(&edges);
1521
IGRAPH_FINALLY_CLEAN(1);
1527
* \function igraph_lcf
1528
* \brief Create a graph from LCF notation
1531
* LCF is short for Lederberg-Coxeter-Frucht, it is a concise notation for
1532
* 3-regular Hamiltonian graphs. It consists of three parameters, the
1533
* number of vertices in the graph, a list of shifts giving additional
1534
* edges to a cycle backbone and another integer giving how many times
1535
* the shifts should be performed. See
1536
* http://mathworld.wolfram.com/LCFNotation.html for details.
1538
* \param graph Pointer to an uninitialized graph object.
1539
* \param n Integer, the number of vertices in the graph.
1540
* \param ... The shifts and the number of repeats for the shifts,
1541
* plus an additional 0 to mark the end of the arguments.
1542
* \return Error code.
1544
* \sa See \ref igraph_lcf_vector() for a similar function using a
1545
* vector_t instead of the variable length argument list.
1547
* Time complexity: O(|V|+|E|), the number of vertices plus the number
1551
int igraph_lcf(igraph_t *graph, igraph_integer_t n, ...) {
1552
igraph_vector_t shifts;
1553
igraph_integer_t repeats;
1556
IGRAPH_VECTOR_INIT_FINALLY(&shifts, 0);
1560
int num=va_arg(ap, int);
1564
IGRAPH_CHECK(igraph_vector_push_back(&shifts, num));
1566
if (igraph_vector_size(&shifts)==0) {
1569
repeats=igraph_vector_pop_back(&shifts);
1572
IGRAPH_CHECK(igraph_lcf_vector(graph, n, &shifts, repeats));
1573
igraph_vector_destroy(&shifts);
1574
IGRAPH_FINALLY_CLEAN(1);
1579
igraph_real_t igraph_i_famous_bull[] = {
1584
igraph_real_t igraph_i_famous_chvatal[] = {
1586
5, 6, 6, 7, 7, 8, 8, 9, 5, 9, 4, 5, 4, 8, 2, 8, 2, 6, 0, 6, 0, 9, 3, 9, 3, 7,
1587
1, 7, 1, 5, 1, 10, 4, 10, 4, 11, 2, 11, 0, 10, 0, 11, 3, 11, 3, 10, 1, 2
1590
igraph_real_t igraph_i_famous_coxeter[] = {
1592
0, 1, 0, 2, 0, 7, 1, 4, 1, 13, 2, 3, 2, 8, 3, 6, 3, 9, 4, 5, 4, 12, 5, 6, 5,
1593
11, 6, 10, 7, 19, 7, 24, 8, 20, 8, 23, 9, 14, 9, 22, 10, 15, 10, 21, 11, 16,
1594
11, 27, 12, 17, 12, 26, 13, 18, 13, 25, 14, 17, 14, 18, 15, 18, 15, 19, 16, 19,
1595
16, 20, 17, 20, 21, 23, 21, 26, 22, 24, 22, 27, 23, 25, 24, 26, 25, 27
1598
igraph_real_t igraph_i_famous_cubical[] = {
1600
0, 1, 1, 2, 2, 3, 0, 3, 4, 5, 5, 6, 6, 7, 4, 7, 0, 4, 1, 5, 2, 6, 3, 7
1603
igraph_real_t igraph_i_famous_diamond[] = {
1608
igraph_real_t igraph_i_famous_dodecahedron[] = {
1610
0, 1, 0, 4, 0, 5, 1, 2, 1, 6, 2, 3, 2, 7, 3, 4, 3, 8, 4, 9, 5, 10, 5, 11, 6,
1611
10, 6, 14, 7, 13, 7, 14, 8, 12, 8, 13, 9, 11, 9, 12, 10, 15, 11, 16, 12, 17,
1612
13, 18, 14, 19, 15, 16, 15, 19, 16, 17, 17, 18, 18, 19
1615
igraph_real_t igraph_i_famous_folkman[] = {
1617
0, 5, 0, 8, 0, 10, 0, 13, 1, 7, 1, 9, 1, 12, 1, 14, 2, 6, 2, 8, 2, 11, 2, 13,
1618
3, 5, 3, 7, 3, 10, 3, 12, 4, 6, 4, 9, 4, 11, 4, 14, 5, 15, 5, 19, 6, 15, 6, 16,
1619
7, 16, 7, 17, 8, 17, 8, 18, 9, 18, 9, 19, 10, 15, 10, 19, 11, 15, 11, 16, 12,
1620
16, 12, 17, 13, 17, 13, 18, 14, 18, 14, 19
1623
igraph_real_t igraph_i_famous_franklin[] = {
1625
0, 1, 0, 2, 0, 6, 1, 3, 1, 7, 2, 4, 2, 10, 3, 5, 3, 11, 4, 5, 4, 6, 5, 7, 6, 8,
1626
7, 9, 8, 9, 8, 11, 9, 10, 10, 11
1629
igraph_real_t igraph_i_famous_frucht[] = {
1631
0, 1, 0, 2, 0, 11, 1, 3, 1, 6, 2, 5, 2, 10, 3, 4, 3, 6, 4, 8, 4, 11, 5, 9, 5,
1632
10, 6, 7, 7, 8, 7, 9, 8, 9, 10, 11
1635
igraph_real_t igraph_i_famous_grotzsch[] = {
1637
0, 1, 0, 2, 0, 7, 0, 10, 1, 3, 1, 6, 1, 9, 2, 4, 2, 6, 2, 8, 3, 4, 3, 8, 3, 10,
1638
4, 7, 4, 9, 5, 6, 5, 7, 5, 8, 5, 9, 5, 10
1641
igraph_real_t igraph_i_famous_heawood[] = {
1643
0, 1, 0, 5, 0, 13, 1, 2, 1, 10, 2, 3, 2, 7, 3, 4, 3, 12, 4, 5, 4, 9, 5, 6, 6,
1644
7, 6, 11, 7, 8, 8, 9, 8, 13, 9, 10, 10, 11, 11, 12, 12, 13
1647
igraph_real_t igraph_i_famous_herschel[] = {
1649
0, 2, 0, 3, 0, 4, 0, 5, 1, 2, 1, 3, 1, 6, 1, 7, 2, 10, 3, 9, 4, 8, 4, 9, 5, 8,
1650
5, 10, 6, 8, 6, 9, 7, 8, 7, 10
1653
igraph_real_t igraph_i_famous_house[] = {
1655
0,1,0,2,1,3,2,3,2,4,3,4
1658
igraph_real_t igraph_i_famous_housex[] = {
1660
0,1,0,2,0,3,1,2,1,3,2,3,2,4,3,4
1663
igraph_real_t igraph_i_famous_icosahedron[] = {
1665
0, 1, 0, 2, 0, 3, 0, 4, 0, 8, 1, 2, 1, 6, 1, 7, 1, 8, 2, 4, 2, 5, 2, 6, 3, 4,
1666
3, 8, 3, 9, 3, 11, 4, 5, 4, 11, 5, 6, 5, 10, 5, 11, 6, 7, 6, 10, 7, 8, 7, 9, 7,
1667
10, 8, 9, 9, 10, 9, 11, 10, 11
1670
igraph_real_t igraph_i_famous_krackhardt_kite[] = {
1672
0,1,0,2,0,3,0,5, 1,3,1,4,1,6, 2,3,2,5, 3,4,3,5,3,6, 4,6, 5,6,5,7, 6,7, 7,8, 8,9
1675
igraph_real_t igraph_i_famous_levi[] = {
1677
0, 1, 0, 7, 0, 29, 1, 2, 1, 24, 2, 3, 2, 11, 3, 4, 3, 16, 4, 5, 4, 21, 5, 6, 5,
1678
26, 6, 7, 6, 13, 7, 8, 8, 9, 8, 17, 9, 10, 9, 22, 10, 11, 10, 27, 11, 12, 12,
1679
13, 12, 19, 13, 14, 14, 15, 14, 23, 15, 16, 15, 28, 16, 17, 17, 18, 18, 19, 18,
1680
25, 19, 20, 20, 21, 20, 29, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
1684
igraph_real_t igraph_i_famous_mcgee[] = {
1686
0, 1, 0, 7, 0, 23, 1, 2, 1, 18, 2, 3, 2, 14, 3, 4, 3, 10, 4, 5, 4, 21, 5, 6, 5,
1687
17, 6, 7, 6, 13, 7, 8, 8, 9, 8, 20, 9, 10, 9, 16, 10, 11, 11, 12, 11, 23, 12,
1688
13, 12, 19, 13, 14, 14, 15, 15, 16, 15, 22, 16, 17, 17, 18, 18, 19, 19, 20, 20,
1692
igraph_real_t igraph_i_famous_meredith[] = {
1694
0, 4, 0, 5, 0, 6, 1, 4, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6, 3, 4, 3, 5, 3, 6, 7, 11,
1695
7, 12, 7, 13, 8, 11, 8, 12, 8, 13, 9, 11, 9, 12, 9, 13, 10, 11, 10, 12, 10, 13,
1696
14, 18, 14, 19, 14, 20, 15, 18, 15, 19, 15, 20, 16, 18, 16, 19, 16, 20, 17, 18,
1697
17, 19, 17, 20, 21, 25, 21, 26, 21, 27, 22, 25, 22, 26, 22, 27, 23, 25, 23, 26,
1698
23, 27, 24, 25, 24, 26, 24, 27, 28, 32, 28, 33, 28, 34, 29, 32, 29, 33, 29, 34,
1699
30, 32, 30, 33, 30, 34, 31, 32, 31, 33, 31, 34, 35, 39, 35, 40, 35, 41, 36, 39,
1700
36, 40, 36, 41, 37, 39, 37, 40, 37, 41, 38, 39, 38, 40, 38, 41, 42, 46, 42, 47,
1701
42, 48, 43, 46, 43, 47, 43, 48, 44, 46, 44, 47, 44, 48, 45, 46, 45, 47, 45, 48,
1702
49, 53, 49, 54, 49, 55, 50, 53, 50, 54, 50, 55, 51, 53, 51, 54, 51, 55, 52, 53,
1703
52, 54, 52, 55, 56, 60, 56, 61, 56, 62, 57, 60, 57, 61, 57, 62, 58, 60, 58, 61,
1704
58, 62, 59, 60, 59, 61, 59, 62, 63, 67, 63, 68, 63, 69, 64, 67, 64, 68, 64, 69,
1705
65, 67, 65, 68, 65, 69, 66, 67, 66, 68, 66, 69, 2, 50, 1, 51, 9, 57, 8, 58, 16,
1706
64, 15, 65, 23, 36, 22, 37, 30, 43, 29, 44, 3, 21, 7, 24, 14, 31, 0, 17, 10,
1707
28, 38, 42, 35, 66, 59, 63, 52, 56, 45, 49
1710
igraph_real_t igraph_i_famous_noperfectmatching[] = {
1712
0, 1, 0, 2, 0, 3, 1, 2, 1, 3, 2, 3, 2, 4, 3, 4, 4, 5, 5, 6, 5, 7, 6, 12, 6, 13,
1713
7, 8, 7, 9, 8, 9, 8, 10, 8, 11, 9, 10, 9, 11, 10, 11, 12, 13, 12, 14, 12, 15,
1714
13, 14, 13, 15, 14, 15
1717
igraph_real_t igraph_i_famous_nonline[] = {
1719
0, 1, 0, 2, 0, 3, 4, 6, 4, 7, 5, 6, 5, 7, 6, 7, 7, 8, 9, 11, 9, 12, 9, 13, 10,
1720
11, 10, 12, 10, 13, 11, 12, 11, 13, 12, 13, 14, 15, 15, 16, 15, 17, 16, 17, 16,
1721
18, 17, 18, 18, 19, 20, 21, 20, 22, 20, 23, 21, 22, 21, 23, 21, 24, 22, 23, 22,
1722
24, 24, 25, 26, 27, 26, 28, 26, 29, 27, 28, 27, 29, 27, 30, 27, 31, 28, 29, 28,
1723
30, 28, 31, 30, 31, 32, 34, 32, 35, 32, 36, 33, 34, 33, 35, 33, 37, 34, 35, 36,
1724
37, 38, 39, 38, 40, 38, 43, 39, 40, 39, 41, 39, 42, 39, 43, 40, 41, 41, 42, 42,
1725
43, 44, 45, 44, 46, 45, 46, 45, 47, 46, 47, 46, 48, 47, 48, 47, 49, 48, 49
1728
igraph_real_t igraph_i_famous_octahedron[] = {
1730
0, 1, 0, 2, 1, 2, 3, 4, 3, 5, 4, 5, 0, 3, 0, 5, 1, 3, 1, 4, 2, 4, 2, 5
1733
igraph_real_t igraph_i_famous_petersen[] = {
1735
0,1,0,4,0,5, 1,2,1,6, 2,3,2,7, 3,4,3,8, 4,9, 5,7,5,8, 6,8,6,9, 7,9
1738
igraph_real_t igraph_i_famous_robertson[] = {
1740
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12,
1741
12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 0, 18, 0, 4, 4, 9, 9, 13, 13,
1742
17, 2, 17, 2, 6, 6, 10, 10, 15, 0, 15, 1, 8, 8, 16, 5, 16, 5, 12, 1, 12, 7, 18,
1743
7, 14, 3, 14, 3, 11, 11, 18
1746
igraph_real_t igraph_i_famous_smallestcyclicgroup[] = {
1748
0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 1, 2, 1, 3, 1, 7, 1, 8, 2, 5, 2, 6, 2, 7, 3, 8,
1752
igraph_real_t igraph_i_famous_tetrahedron[] = {
1754
0, 3, 1, 3, 2, 3, 0, 1, 1, 2, 0, 2
1757
igraph_real_t igraph_i_famous_thomassen[] = {
1759
0, 2, 0, 3, 1, 3, 1, 4, 2, 4, 5, 7, 5, 8, 6, 8, 6, 9, 7, 9, 10, 12, 10, 13, 11,
1760
13, 11, 14, 12, 14, 15, 17, 15, 18, 16, 18, 16, 19, 17, 19, 9, 19, 4, 14, 24,
1761
25, 25, 26, 20, 26, 20, 21, 21, 22, 22, 23, 23, 27, 27, 28, 28, 29, 29, 30, 30,
1762
31, 31, 32, 32, 33, 24, 33, 5, 24, 6, 25, 7, 26, 8, 20, 0, 20, 1, 21, 2, 22, 3,
1763
23, 10, 27, 11, 28, 12, 29, 13, 30, 15, 30, 16, 31, 17, 32, 18, 33
1766
igraph_real_t igraph_i_famous_tutte[] = {
1768
0, 10, 0, 11, 0, 12, 1, 2, 1, 7, 1, 19, 2, 3, 2, 41, 3, 4, 3, 27, 4, 5, 4, 33,
1769
5, 6, 5, 45, 6, 9, 6, 29, 7, 8, 7, 21, 8, 9, 8, 22, 9, 24, 10, 13, 10, 14, 11,
1770
26, 11, 28, 12, 30, 12, 31, 13, 15, 13, 21, 14, 15, 14, 18, 15, 16, 16, 17, 16,
1771
20, 17, 18, 17, 23, 18, 24, 19, 25, 19, 40, 20, 21, 20, 22, 22, 23, 23, 24, 25,
1772
26, 25, 38, 26, 34, 27, 28, 27, 39, 28, 34, 29, 30, 29, 44, 30, 35, 31, 32, 31,
1773
35, 32, 33, 32, 42, 33, 43, 34, 36, 35, 37, 36, 38, 36, 39, 37, 42, 37, 44, 38,
1774
40, 39, 41, 40, 41, 42, 43, 43, 45, 44, 45
1777
igraph_real_t igraph_i_famous_uniquely3colorable[] = {
1779
0, 1, 0, 3, 0, 6, 0, 8, 1, 4, 1, 7, 1, 9, 2, 3, 2, 6, 2, 7, 2, 9, 2, 11, 3, 4,
1780
3, 10, 4, 5, 4, 11, 5, 6, 5, 7, 5, 8, 5, 10, 8, 11, 9, 10
1783
igraph_real_t igraph_i_famous_walther[] = {
1785
0, 1, 1, 2, 1, 8, 2, 3, 2, 13, 3, 4, 3, 16, 4, 5, 5, 6, 5, 19, 6, 7, 6, 20, 7,
1786
21, 8, 9, 8, 13, 9, 10, 9, 22, 10, 11, 10, 20, 11, 12, 13, 14, 14, 15, 14, 23,
1787
15, 16, 15, 17, 17, 18, 18, 19, 18, 24, 20, 24, 22, 23, 23, 24
1790
int igraph_i_famous(igraph_t *graph, igraph_real_t *data) {
1791
long int no_of_nodes=data[0];
1792
long int no_of_edges=data[1];
1793
igraph_bool_t directed=data[2];
1794
igraph_vector_t edges;
1796
igraph_vector_view(&edges, data+3, 2*no_of_edges);
1797
IGRAPH_CHECK(igraph_create(graph, &edges, no_of_nodes, directed));
1802
* \function igraph_famous
1803
* \brief Create a famous graph by simply providing its name
1806
* The name of the graph can be simply supplied as a string.
1807
* Note that this function creates graphs which don't take any parameters,
1808
* there are separate functions for graphs with parameters, eg. \ref
1809
* igraph_full() for creating a full graph.
1812
* The following graphs are supported:
1815
* The bull graph, 5 vertices, 5 edges, resembles to the
1816
* head of a bull if drawn properly.
1818
* This is the smallest triangle-free graph that is
1819
* both 4-chromatic and 4-regular. According to the Grunbaum
1820
* conjecture there exists an m-regular, m-chromatic graph
1821
* with n vertices for every m>1 and n>2. The Chvatal graph
1822
* is an example for m=4 and n=12. It has 24 edges.
1824
* A non-Hamiltonian cubic symmetric graph with 28
1825
* vertices and 42 edges.
1827
* The Platonic graph of the cube. A convex regular
1828
* polyhedron with 8 vertices and 12 edges.
1830
* A graph with 4 vertices and 5 edges, resembles to a
1831
* schematic diamond if drawn properly.
1832
* \cli Dodecahedral, Dodecahedron
1833
* Another Platonic solid
1834
* with 20 vertices and 30 edges.
1836
* The semisymmetric graph with minimum number of
1837
* vertices, 20 and 40 edges. A semisymmetric graph is
1838
* regular, edge transitive and not vertex transitive.
1840
* This is a graph whose embedding to the Klein
1841
* bottle can be colored with six colors, it is a
1842
* counterexample to the neccessity of the Heawood
1843
* conjecture on a Klein bottle. It has 12 vertices and 18
1846
* The Frucht Graph is the smallest cubical graph
1847
* whose automorphism group consists only of the identity
1848
* element. It has 12 vertices and 18 edges.
1850
* The Grƶtzsch graph is a triangle-free graph with
1851
* 11 vertices, 20 edges, and chromatic number 4. It is named after
1852
* German mathematician Herbert Grƶtzsch, and its existence
1853
* demonstrates that the assumption of planarity is necessary in
1854
* Grƶtzsch's theorem that every triangle-free planar
1855
* graph is 3-colorable.
1857
* The Heawood graph is an undirected graph with 14
1858
* vertices and 21 edges. The graph is cubic, and all cycles in the
1859
* graph have six or more edges. Every smaller cubic graph has shorter
1860
* cycles, so this graph is the 6-cage, the smallest cubic graph of
1863
* The Herschel graph is the smallest
1864
* nonhamiltonian polyhedral graph. It is the
1865
* unique such graph on 11 nodes, and has 18 edges.
1867
* The house graph is a 5-vertex, 6-edge graph, the
1868
* schematic draw of a house if drawn properly, basicly a
1869
* triangle of the top of a square.
1871
* The same as the house graph with an X in the square. 5
1872
* vertices and 8 edges.
1873
* \cli Icosahedral, Icosahedron
1874
* A Platonic solid with 12
1875
* vertices and 30 edges.
1876
* \cli Krackhardt_Kite
1877
* A social network with 10 vertices and 18 edges.
1878
* Krackhardt, D. Assessing the Political Landscape:
1879
* Structure, Cognition, and Power in Organizations.
1880
* Admin. Sci. Quart. 35, 342-369, 1990.
1882
* The graph is a 4-arc transitive cubic graph, it has
1883
* 30 vertices and 45 edges.
1885
* The McGee graph is the unique 3-regular 7-cage
1886
* graph, it has 24 vertices and 36 edges.
1888
* The Meredith graph is a quartic graph on 70
1889
* nodes and 140 edges that is a counterexample to the conjecture that
1890
* every 4-regular 4-connected graph is Hamiltonian.
1891
* \cli Noperfectmatching
1892
* A connected graph with 16 vertices and
1893
* 27 edges containing no perfect matching. A matching in a graph
1894
* is a set of pairwise non-adjacent edges; that is, no two edges
1895
* share a common vertex. A perfect matching is a matching
1896
* which covers all vertices of the graph.
1898
* A graph whose connected components are the 9
1899
* graphs whose presence as a vertex-induced subgraph in a
1900
* graph makes a nonline graph. It has 50 vertices and 72 edges.
1901
* \cli Octahedral, Octahedron
1902
* Platonic solid with 6
1903
* vertices and 12 edges.
1905
* A 3-regular graph with 10 vertices and 15 edges. It is
1906
* the smallest hypohamiltonian graph, ie. it is
1907
* non-hamiltonian but removing any single vertex from it makes it
1910
* The unique (4,5)-cage graph, ie. a 4-regular
1911
* graph of girth 5. It has 19 vertices and 38 edges.
1912
* \cli Smallestcyclicgroup
1913
* A smallest nontrivial graph
1914
* whose automorphism group is cyclic. It has 9 vertices and
1916
* \cli Tetrahedral, Tetrahedron
1917
* Platonic solid with 4
1918
* vertices and 6 edges.
1920
* The smallest hypotraceable graph,
1921
* on 34 vertices and 52 edges. A hypotracable graph does
1922
* not contain a Hamiltonian path but after removing any
1923
* single vertex from it the remainder always contains a
1924
* Hamiltonian path. A graph containing a Hamiltonian path
1925
* is called tracable.
1927
* Tait's Hamiltonian graph conjecture states that
1928
* every 3-connected 3-regular planar graph is Hamiltonian.
1929
* This graph is a counterexample. It has 46 vertices and 69
1931
* \cli Uniquely3colorable
1932
* Returns a 12-vertex, triangle-free
1933
* graph with chromatic number 3 that is uniquely
1936
* An identity graph with 25 vertices and 31
1937
* edges. An identity graph has a single graph automorphism,
1941
* \param graph Pointer to an unitialized graph object.
1942
* \param name Character constant, the name of the graph to be
1943
* created, it is case insensitive.
1944
* \return Error code, IGRAPH_EINVAL if there is no graph with the
1947
* \sa Other functions for creating graph structures:
1948
* \ref igraph_ring(), \ref igraph_tree(), \ref igraph_lattice(), \ref
1951
* Time complexity: O(|V|+|E|), the number of vertices plus the number
1952
* of edges in the graph.
1955
int igraph_famous(igraph_t *graph, const char *name) {
1957
if (!strcasecmp(name, "bull")) {
1958
return igraph_i_famous(graph, igraph_i_famous_bull);
1959
} else if (!strcasecmp(name, "chvatal")) {
1960
return igraph_i_famous(graph, igraph_i_famous_chvatal);
1961
} else if (!strcasecmp(name, "coxeter")) {
1962
return igraph_i_famous(graph, igraph_i_famous_coxeter);
1963
} else if (!strcasecmp(name, "cubical")) {
1964
return igraph_i_famous(graph, igraph_i_famous_cubical);
1965
} else if (!strcasecmp(name, "diamond")) {
1966
return igraph_i_famous(graph, igraph_i_famous_diamond);
1967
} else if (!strcasecmp(name, "dodecahedral") ||
1968
!strcasecmp(name, "dodecahedron")) {
1969
return igraph_i_famous(graph, igraph_i_famous_dodecahedron);
1970
} else if (!strcasecmp(name, "folkman")) {
1971
return igraph_i_famous(graph, igraph_i_famous_folkman);
1972
} else if (!strcasecmp(name, "franklin")) {
1973
return igraph_i_famous(graph, igraph_i_famous_franklin);
1974
} else if (!strcasecmp(name, "frucht")) {
1975
return igraph_i_famous(graph, igraph_i_famous_frucht);
1976
} else if (!strcasecmp(name, "grotzsch")) {
1977
return igraph_i_famous(graph, igraph_i_famous_grotzsch);
1978
} else if (!strcasecmp(name, "heawood")) {
1979
return igraph_i_famous(graph, igraph_i_famous_heawood);
1980
} else if (!strcasecmp(name, "herschel")) {
1981
return igraph_i_famous(graph, igraph_i_famous_herschel);
1982
} else if (!strcasecmp(name, "house")) {
1983
return igraph_i_famous(graph, igraph_i_famous_house);
1984
} else if (!strcasecmp(name, "housex")) {
1985
return igraph_i_famous(graph, igraph_i_famous_housex);
1986
} else if (!strcasecmp(name, "icosahedral") ||
1987
!strcasecmp(name, "icosahedron")) {
1988
return igraph_i_famous(graph, igraph_i_famous_icosahedron);
1989
} else if (!strcasecmp(name, "krackhardt_kite")) {
1990
return igraph_i_famous(graph, igraph_i_famous_krackhardt_kite);
1991
} else if (!strcasecmp(name, "levi")) {
1992
return igraph_i_famous(graph, igraph_i_famous_levi);
1993
} else if (!strcasecmp(name, "mcgee")) {
1994
return igraph_i_famous(graph, igraph_i_famous_mcgee);
1995
} else if (!strcasecmp(name, "meredith")) {
1996
return igraph_i_famous(graph, igraph_i_famous_meredith);
1997
} else if (!strcasecmp(name, "noperfectmatching")) {
1998
return igraph_i_famous(graph, igraph_i_famous_noperfectmatching);
1999
} else if (!strcasecmp(name, "nonline")) {
2000
return igraph_i_famous(graph, igraph_i_famous_nonline);
2001
} else if (!strcasecmp(name, "octahedral") ||
2002
!strcasecmp(name, "octahedron")) {
2003
return igraph_i_famous(graph, igraph_i_famous_octahedron);
2004
} else if (!strcasecmp(name, "petersen")) {
2005
return igraph_i_famous(graph, igraph_i_famous_petersen);
2006
} else if (!strcasecmp(name, "robertson")) {
2007
return igraph_i_famous(graph, igraph_i_famous_robertson);
2008
} else if (!strcasecmp(name, "smallestcyclicgroup")) {
2009
return igraph_i_famous(graph, igraph_i_famous_smallestcyclicgroup);
2010
} else if (!strcasecmp(name, "tetrahedral") ||
2011
!strcasecmp(name, "tetrahedron")) {
2012
return igraph_i_famous(graph, igraph_i_famous_tetrahedron);
2013
} else if (!strcasecmp(name, "thomassen")) {
2014
return igraph_i_famous(graph, igraph_i_famous_thomassen);
2015
} else if (!strcasecmp(name, "tutte")) {
2016
return igraph_i_famous(graph, igraph_i_famous_tutte);
2017
} else if (!strcasecmp(name, "uniquely3colorable")) {
2018
return igraph_i_famous(graph, igraph_i_famous_uniquely3colorable);
2019
} else if (!strcasecmp(name, "walther")) {
2020
return igraph_i_famous(graph, igraph_i_famous_walther);
2022
IGRAPH_ERROR("Unknown graph, see documentation", IGRAPH_EINVAL);
2029
* \function igraph_adjlist
2030
* Create a graph from an adjacency list
2032
* An adjacency list is list of vectors, containing the neighbors
2033
* of all vertices. For operations that involve many changes of the
2034
* graph structure, it is recommended that you convert the graph into
2035
* and adjacency list via \ref igraph_adjlist_init(), perform the
2036
* modifications (these are cheap for an adjacency list) and then
2037
* recreate the igraph graph via this function.
2039
* \param graph Pointer to an uninitialized graph object.
2040
* \param adjlist The adjacency list.
2041
* \param directed Logical, whether or not to create a directed graph.
2042
* \param duplicate Logical, for undirected graphs this specified
2043
* whether each edge is included twice, in the vectors of
2044
* both adjacenct vertices. If this is false (0), then it is
2045
* assumed that every edge is included only once. This argument
2046
* is ignored for directed graphs.
2047
* \return Error code.
2049
* \sa \ref igraph_adjlist_init() for the opposite operation.
2051
* Time complexity: O(|V|+|E|).
2055
int igraph_adjlist(igraph_t *graph, const igraph_adjlist_t *adjlist,
2056
igraph_bool_t directed, igraph_bool_t duplicate) {
2058
long int no_of_nodes=igraph_adjlist_size(adjlist);
2059
long int no_of_edges=0;
2062
igraph_vector_t edges;
2065
duplicate = duplicate && !directed; /* only duplicate if undirected */
2067
for (i=0; i<no_of_nodes; i++) {
2068
no_of_edges += igraph_vector_size(igraph_adjlist_get(adjlist, i));
2075
IGRAPH_VECTOR_INIT_FINALLY(&edges, 2*no_of_edges);
2077
for (i=0; i<no_of_nodes; i++) {
2078
igraph_vector_t *neis=igraph_adjlist_get(adjlist, i);
2079
long int j, n=igraph_vector_size(neis);
2081
for (j=0; j<n; j++) {
2082
long int nei=VECTOR(*neis)[j];
2086
if (! duplicate || nei > i) {
2087
if (edgeptr+2 > 2*no_of_edges) {
2088
IGRAPH_ERROR("Invalid adjacency list, most probably not correctly"
2089
" duplicated edges for an undirected graph", IGRAPH_EINVAL);
2091
VECTOR(edges)[edgeptr++] = i;
2092
VECTOR(edges)[edgeptr++] = nei;
2097
if (duplicate) { loops=loops/2; }
2098
if (edgeptr+2*loops > 2*no_of_edges) {
2099
IGRAPH_ERROR("Invalid adjacency list, most probably not correctly"
2100
" duplicated edges for an undirected graph", IGRAPH_EINVAL);
2102
for (j=0; j<loops; j++) {
2103
VECTOR(edges)[edgeptr++] = i;
2104
VECTOR(edges)[edgeptr++] = i;
2108
IGRAPH_CHECK(igraph_create(graph, &edges, no_of_nodes, directed));
2109
igraph_vector_destroy(&edges);
2110
IGRAPH_FINALLY_CLEAN(1);