Add graph references
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2013-2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef IGRAPH_BENCH_H
|
||||
#define IGRAPH_BENCH_H
|
||||
|
||||
#include <sys/resource.h> /* getrusage */
|
||||
#include <sys/time.h> /* gettimeofday */
|
||||
#include <unistd.h> /* sleep */
|
||||
|
||||
static inline void igraph_get_cpu_time(double *data) {
|
||||
|
||||
struct rusage self;
|
||||
struct timeval real;
|
||||
gettimeofday(&real, NULL);
|
||||
getrusage(RUSAGE_SELF, &self);
|
||||
data[0] = (double) real.tv_sec + 1e-6 * real.tv_usec; /* real */
|
||||
data[1] = (double) self.ru_utime.tv_sec + 1e-6 * self.ru_utime.tv_usec; /* user */
|
||||
data[2] = (double) self.ru_stime.tv_sec + 1e-6 * self.ru_stime.tv_usec; /* system */
|
||||
}
|
||||
|
||||
#define BENCH_INIT() \
|
||||
do { \
|
||||
printf("\n|> Benchmark file: %s\n", IGRAPH_FILE_BASENAME); \
|
||||
sleep(1); \
|
||||
} while (0)
|
||||
|
||||
#define REPEAT(CODE, N) \
|
||||
do { \
|
||||
igraph_int_t rep_i; \
|
||||
for (rep_i=0; rep_i < N; ++rep_i) { CODE; } \
|
||||
} while (0)
|
||||
|
||||
#define BENCH(NAME, ...) do { \
|
||||
double start[3], stop[3]; \
|
||||
double r, u, s; \
|
||||
igraph_get_cpu_time(start); \
|
||||
{ __VA_ARGS__; } \
|
||||
igraph_get_cpu_time(stop); \
|
||||
r = 1e-3 * round(1e3 * (stop[0] - start[0])); \
|
||||
u = 1e-3 * round(1e3 * (stop[1] - start[1])); \
|
||||
s = 1e-3 * round(1e3 * (stop[2] - start[2])); \
|
||||
printf("| %-80s %5.3gs %5.3gs %5.3gs\n", NAME, r, u, s); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
IGraph library.
|
||||
Copyright (C) 2025 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
#include "igraph_spatial.h"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
void bench_lune(igraph_int_t test_nr, igraph_int_t point_count, igraph_int_t dimensions, igraph_real_t beta) {
|
||||
igraph_matrix_t points;
|
||||
igraph_t g;
|
||||
char msg[200];
|
||||
|
||||
igraph_matrix_init(&points, point_count, dimensions);
|
||||
|
||||
for (igraph_int_t point = 0; point < point_count; point++) {
|
||||
for (igraph_int_t dim = 0; dim < dimensions; dim++) {
|
||||
MATRIX(points, point, dim) = RNG_UNIF01();
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%3"IGRAPH_PRId" Lune based beta skeleton in %dD, beta=%.3f, n=%6" IGRAPH_PRId,
|
||||
test_nr, (int) dimensions, beta, point_count);
|
||||
|
||||
BENCH(msg, igraph_lune_beta_skeleton(&g, &points, beta));
|
||||
|
||||
igraph_destroy(&g);
|
||||
igraph_matrix_destroy(&points);
|
||||
|
||||
}
|
||||
|
||||
void bench_circle(igraph_int_t test_nr, igraph_int_t point_count, igraph_int_t dimensions, igraph_real_t beta) {
|
||||
igraph_matrix_t points;
|
||||
igraph_t g;
|
||||
char msg[200];
|
||||
|
||||
igraph_matrix_init(&points, point_count, dimensions);
|
||||
|
||||
for (igraph_int_t point = 0; point < point_count; point++) {
|
||||
for (igraph_int_t dim = 0; dim < dimensions; dim++) {
|
||||
MATRIX(points, point, dim) = RNG_UNIF01();
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%3"IGRAPH_PRId" Circle based beta skeleton in %dD, beta=%3f, n=%6" IGRAPH_PRId,
|
||||
test_nr, (int) dimensions, beta, point_count);
|
||||
|
||||
BENCH(msg, igraph_circle_beta_skeleton(&g, &points, beta));
|
||||
|
||||
igraph_destroy(&g);
|
||||
igraph_matrix_destroy(&points);
|
||||
|
||||
}
|
||||
|
||||
void bench_gabriel(igraph_int_t test_nr, igraph_int_t point_count, igraph_int_t dimensions, igraph_real_t beta_cutoff) {
|
||||
igraph_matrix_t points;
|
||||
igraph_vector_t edge_weights;
|
||||
igraph_t g;
|
||||
char msg[200];
|
||||
|
||||
igraph_matrix_init(&points, point_count, dimensions);
|
||||
igraph_vector_init(&edge_weights, 0);
|
||||
|
||||
for (igraph_int_t point = 0; point < point_count; point++) {
|
||||
for (igraph_int_t dim = 0; dim < dimensions; dim++) {
|
||||
MATRIX(points, point, dim) = RNG_UNIF01();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%3"IGRAPH_PRId" Beta weighted gabriel graph in %dD, cutoff=%3f, n=%6" IGRAPH_PRId,
|
||||
test_nr, (int) dimensions, beta_cutoff, point_count);
|
||||
|
||||
BENCH(msg, igraph_beta_weighted_gabriel_graph(&g, &edge_weights, &points, beta_cutoff));
|
||||
|
||||
igraph_vector_destroy(&edge_weights);
|
||||
igraph_destroy(&g);
|
||||
igraph_matrix_destroy(&points);
|
||||
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_int_t test_nr = 0;
|
||||
bench_lune(++test_nr, 100, 2, 2);
|
||||
bench_lune(++test_nr, 1000, 2, 2);
|
||||
bench_lune(++test_nr, 10000, 2, 2);
|
||||
bench_lune(++test_nr, 100000, 2, 2);
|
||||
bench_lune(++test_nr, 100, 3, 2);
|
||||
bench_lune(++test_nr, 1000, 3, 2);
|
||||
bench_lune(++test_nr, 10000, 3, 2);
|
||||
bench_lune(++test_nr, 100000, 3, 2);
|
||||
bench_lune(++test_nr, 1000, 4, 2);
|
||||
|
||||
bench_lune(++test_nr, 10000, 2, 1);
|
||||
bench_lune(++test_nr, 10000, 2, 2);
|
||||
bench_lune(++test_nr, 10000, 2, 4);
|
||||
bench_lune(++test_nr, 10000, 2, 8);
|
||||
bench_lune(++test_nr, 10000, 2, 16);
|
||||
bench_lune(++test_nr, 10000, 2, 32);
|
||||
bench_lune(++test_nr, 10000, 2, 64);
|
||||
bench_lune(++test_nr, 10000, 2, 128);
|
||||
bench_lune(++test_nr, 10000, 2, 256);
|
||||
bench_lune(++test_nr, 10000, 2, 512);
|
||||
bench_lune(++test_nr, 10000, 2, 1024);
|
||||
bench_lune(++test_nr, 1000, 2, 0.9);
|
||||
bench_lune(++test_nr, 1000, 2, 0.5);
|
||||
bench_lune(++test_nr, 1000, 2, 0.1);
|
||||
|
||||
|
||||
bench_circle(++test_nr, 100, 2, 2);
|
||||
bench_circle(++test_nr, 1000, 2, 2);
|
||||
bench_circle(++test_nr, 10000, 2, 2);
|
||||
bench_circle(++test_nr, 100000, 2, 2);
|
||||
|
||||
bench_circle(++test_nr, 10000, 2, 2);
|
||||
bench_circle(++test_nr, 10000, 2, 3);
|
||||
bench_circle(++test_nr, 10000, 2, 5);
|
||||
bench_circle(++test_nr, 10000, 2, 15);
|
||||
bench_circle(++test_nr, 10000, 2, 50);
|
||||
|
||||
bench_gabriel(++test_nr, 100, 2, 2);
|
||||
bench_gabriel(++test_nr, 1000, 2, 2);
|
||||
bench_gabriel(++test_nr, 10000, 2, 2);
|
||||
bench_gabriel(++test_nr, 100000, 2, 2);
|
||||
|
||||
bench_gabriel(++test_nr, 100, 3, 2);
|
||||
bench_gabriel(++test_nr, 1000, 3, 2);
|
||||
bench_gabriel(++test_nr, 10000, 3, 2);
|
||||
bench_gabriel(++test_nr, 100000, 3, 2);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
igraph_vector_int_t colors;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_vector_int_init(&colors, 0);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 50000, 1000000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
BENCH(" 1 COLORED_NEIGHBORS, random graph with 50,000 vertices and 2,000,000 edges",
|
||||
igraph_vertex_coloring_greedy(&g, &colors, IGRAPH_COLORING_GREEDY_COLORED_NEIGHBORS)
|
||||
);
|
||||
BENCH(" 2 DSATUR, random graph with 50,000 vertices and 2,000,000 edges",
|
||||
igraph_vertex_coloring_greedy(&g, &colors, IGRAPH_COLORING_GREEDY_DSATUR)
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
|
||||
printf("\n");
|
||||
|
||||
igraph_barabasi_game(&g, 100000, 1, 15, NULL, 0, 0, 0, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
BENCH(" 1 COLORED_NEIGHBORS, pref. attach. graph n=100,000 m=15",
|
||||
igraph_vertex_coloring_greedy(&g, &colors, IGRAPH_COLORING_GREEDY_COLORED_NEIGHBORS)
|
||||
);
|
||||
BENCH(" 2 DSATUR, pref. attach. graph n=100,000 m=15",
|
||||
igraph_vertex_coloring_greedy(&g, &colors, IGRAPH_COLORING_GREEDY_DSATUR)
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_vector_int_destroy(&colors);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
void run_bench(const igraph_t *graph, const igraph_vector_t *weights,
|
||||
const char *name, int rep) {
|
||||
igraph_vector_int_t membership;
|
||||
igraph_vector_t vertex_weight;
|
||||
igraph_int_t vcount = igraph_vcount(graph);
|
||||
igraph_int_t ecount = igraph_ecount(graph);
|
||||
char msg[256], msg2[128];
|
||||
|
||||
igraph_vector_int_init(&membership, vcount);
|
||||
igraph_vector_init(&vertex_weight, vcount);
|
||||
|
||||
igraph_strength(graph, &vertex_weight, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS, weights);
|
||||
|
||||
snprintf(msg2, sizeof(msg2) / sizeof(msg2[0]),
|
||||
"%s, vcount=%" IGRAPH_PRId ", ecount=%" IGRAPH_PRId ", %s, %dx",
|
||||
name, vcount, ecount, weights == NULL ? "unweighted" : "weighted",
|
||||
rep);
|
||||
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]), "1 Louvain, %s", msg2);
|
||||
BENCH(msg, REPEAT(igraph_community_multilevel(graph, weights, 1.0, &membership, NULL, NULL), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]), "2 Leiden , %s", msg2);
|
||||
BENCH(msg, REPEAT(igraph_community_leiden(graph, weights, &vertex_weight, NULL, 1.0 / igraph_vector_sum(weights), 0.01, false, 1, &membership, NULL, NULL), rep));
|
||||
|
||||
printf("\n");
|
||||
|
||||
igraph_vector_destroy(&vertex_weight);
|
||||
igraph_vector_int_destroy(&membership);
|
||||
}
|
||||
|
||||
void rand_weights(const igraph_t *graph, igraph_vector_t *weights) {
|
||||
igraph_int_t ecount = igraph_ecount(graph);
|
||||
igraph_vector_resize(weights, ecount);
|
||||
for (igraph_int_t i=0; i < ecount; i++) {
|
||||
VECTOR(*weights)[i] = RNG_UNIF01();
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_t weights;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_vector_init(&weights, 0);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 100, 500, false, false, false);
|
||||
rand_weights(&graph, &weights);
|
||||
run_bench(&graph, &weights, "G(n,m)", 1000);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 1000, 5000, false, false, false);
|
||||
rand_weights(&graph, &weights);
|
||||
run_bench(&graph, &weights, "G(n,m)", 100);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 1000, 50000, false, false, false);
|
||||
rand_weights(&graph, &weights);
|
||||
run_bench(&graph, &weights, "G(n,m)", 10);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 10000, 50000, false, false, false);
|
||||
rand_weights(&graph, &weights);
|
||||
run_bench(&graph, &weights, "G(n,m)", 10);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 100000, 500000, false, false, false);
|
||||
rand_weights(&graph, &weights);
|
||||
run_bench(&graph, &weights, "G(n,m)", 1);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_forest_fire_game(&graph, 1000, 0.2, 1, 2, false);
|
||||
rand_weights(&graph, &weights);
|
||||
run_bench(&graph, &weights, "forest fire", 100);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_barabasi_game(&graph, 1000, 1, 5, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&graph, &weights);
|
||||
run_bench(&graph, &weights, "PA", 100);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_vector_destroy(&weights);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
/* Benchmarks related to biconnected components. */
|
||||
|
||||
void run_bench(igraph_int_t vcount, igraph_real_t meandeg, igraph_int_t rep) {
|
||||
igraph_t g;
|
||||
igraph_bool_t b;
|
||||
igraph_vector_int_t ivec;
|
||||
char msg[128];
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, vcount, round(meandeg * vcount / 2), IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_int_init(&ivec, igraph_vcount(&g));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 1 Weakly connected? vcount=%" IGRAPH_PRId ", meandeg=%g, %" IGRAPH_PRId "x",
|
||||
vcount, meandeg, 10*rep);
|
||||
|
||||
igraph_invalidate_cache(&g);
|
||||
BENCH(msg, REPEAT(igraph_is_connected(&g, &b, IGRAPH_WEAK), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 2 Weak components. vcount=%" IGRAPH_PRId ", meandeg=%g, %" IGRAPH_PRId "x",
|
||||
vcount, meandeg, rep);
|
||||
|
||||
igraph_invalidate_cache(&g);
|
||||
BENCH(msg, REPEAT(igraph_connected_components(&g, &ivec, NULL, NULL, IGRAPH_WEAK), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 3 Strongly connected? vcount=%" IGRAPH_PRId ", meandeg=%g, %" IGRAPH_PRId "x",
|
||||
vcount, meandeg, 10*rep);
|
||||
|
||||
igraph_invalidate_cache(&g);
|
||||
BENCH(msg, REPEAT(igraph_is_connected(&g, &b, IGRAPH_STRONG), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 4 Strong components. vcount=%" IGRAPH_PRId ", meandeg=%g, %" IGRAPH_PRId "x",
|
||||
vcount, meandeg, rep);
|
||||
|
||||
igraph_invalidate_cache(&g);
|
||||
BENCH(msg, REPEAT(igraph_connected_components(&g, &ivec, NULL, NULL, IGRAPH_STRONG), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 5 Biconnected? vcount=%" IGRAPH_PRId ", meandeg=%g, %" IGRAPH_PRId "x",
|
||||
vcount, meandeg, rep);
|
||||
|
||||
igraph_invalidate_cache(&g);
|
||||
BENCH(msg, REPEAT(igraph_is_biconnected(&g, &b), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 6 Bridges. vcount=%" IGRAPH_PRId ", meandeg=%g, %" IGRAPH_PRId "x",
|
||||
vcount, meandeg, rep);
|
||||
|
||||
igraph_invalidate_cache(&g);
|
||||
BENCH(msg, REPEAT(igraph_bridges(&g, &ivec), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 7 Articulation pts. vcount=%" IGRAPH_PRId ", meandeg=%g, %" IGRAPH_PRId "x",
|
||||
vcount, meandeg, rep);
|
||||
|
||||
igraph_invalidate_cache(&g);
|
||||
BENCH(msg, REPEAT(igraph_articulation_points(&g, &ivec), rep));
|
||||
|
||||
igraph_vector_int_destroy(&ivec);
|
||||
igraph_destroy(&g);
|
||||
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
// Note that whether these random graphs end up being connected
|
||||
// with high probability depends not only on their mean degree,
|
||||
// but also their vertex count.
|
||||
|
||||
run_bench(10000, 0.5, 100); // no giant component
|
||||
run_bench(10000, 3, 100); // not weakly connected
|
||||
run_bench(10000, 10, 100); // not strongly connected
|
||||
run_bench(10000, 20, 100); // strongly connnected
|
||||
|
||||
run_bench(100000, 0.5, 100); // no giant component
|
||||
run_bench(100000, 3, 100); // not weakly connected
|
||||
run_bench(100000, 10, 100); // not strongly connected
|
||||
run_bench(100000, 20, 100); // strongly connnected
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
void gnp(igraph_int_t n, igraph_real_t p, igraph_bool_t directed, igraph_edge_type_sw_t allowed_edge_types) {
|
||||
igraph_t g;
|
||||
igraph_erdos_renyi_game_gnp(&g, n, p, directed, allowed_edge_types, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_destroy(&g);
|
||||
}
|
||||
|
||||
void gnm(igraph_int_t n, igraph_real_t meandeg, igraph_bool_t directed, igraph_edge_type_sw_t allowed_edge_types) {
|
||||
igraph_t g;
|
||||
igraph_erdos_renyi_game_gnm(&g, n, round(directed ? n * meandeg : 0.5 * n * meandeg), directed, allowed_edge_types, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_destroy(&g);
|
||||
}
|
||||
|
||||
void chung_lu(const igraph_vector_t *outdeg, const igraph_vector_t *indeg, igraph_bool_t loops) {
|
||||
igraph_t g;
|
||||
igraph_chung_lu_game(&g, outdeg, indeg, loops, IGRAPH_CHUNG_LU_ORIGINAL);
|
||||
igraph_destroy(&g);
|
||||
}
|
||||
|
||||
void run_bench(igraph_int_t vcount, igraph_real_t meandeg, igraph_int_t rep) {
|
||||
igraph_t g;
|
||||
igraph_real_t p = meandeg / vcount;
|
||||
igraph_vector_t outdeg, indeg;
|
||||
char msg[128], msg2[80];
|
||||
|
||||
snprintf(msg2, sizeof(msg2) / sizeof(msg2[0]),
|
||||
"vcount=%" IGRAPH_PRId ", meandeg=%g, %" IGRAPH_PRId "x",
|
||||
vcount, meandeg, rep);
|
||||
|
||||
igraph_vector_init(&outdeg, 0);
|
||||
igraph_vector_init(&indeg, 0);
|
||||
|
||||
igraph_erdos_renyi_game_gnp(&g, vcount, p, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_strength(&g, &outdeg, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS, NULL);
|
||||
igraph_destroy(&g);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 1 G(n,p) undirected, no loops / no multi, %s", msg2);
|
||||
BENCH(msg, REPEAT(gnp(vcount, p, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 2 G(n,m) undirected, no loops / no multi, %s", msg2);
|
||||
BENCH(msg, REPEAT(gnm(vcount, meandeg, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 3 Chung-Lu undirected, no loops, %s", msg2);
|
||||
BENCH(msg, REPEAT(chung_lu(&outdeg, NULL, IGRAPH_NO_LOOPS), rep));
|
||||
|
||||
printf("\n");
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 4 G(n,p) undirected, loops / no multi, %s", msg2);
|
||||
BENCH(msg, REPEAT(gnp(vcount, p, IGRAPH_UNDIRECTED, IGRAPH_LOOPS_SW), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 5 G(n,m) undirected, loops / no multi, %s", msg2);
|
||||
BENCH(msg, REPEAT(gnm(vcount, meandeg, IGRAPH_UNDIRECTED, IGRAPH_LOOPS_SW), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 6 Chung-Lu undirected, loops, %s", msg2);
|
||||
BENCH(msg, REPEAT(chung_lu(&outdeg, NULL, IGRAPH_LOOPS), rep));
|
||||
|
||||
printf("\n");
|
||||
|
||||
igraph_erdos_renyi_game_gnp(&g, vcount, p, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_strength(&g, &outdeg, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS, NULL);
|
||||
igraph_strength(&g, &indeg, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS, NULL);
|
||||
igraph_destroy(&g);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 7 G(n,p) directed, no loops / no multi, %s", msg2);
|
||||
BENCH(msg, REPEAT(gnp(vcount, p, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 8 G(n,m) directed, no loops / no multi, %s", msg2);
|
||||
BENCH(msg, REPEAT(gnm(vcount, meandeg, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 9 Chung-Lu directed, no loops, %s", msg2);
|
||||
BENCH(msg, REPEAT(chung_lu(&outdeg, &indeg, IGRAPH_NO_LOOPS), rep));
|
||||
|
||||
printf("\n");
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"10 G(n,p) directed, loops / no multi, %s", msg2);
|
||||
BENCH(msg, REPEAT(gnp(vcount, p, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"11 G(n,m) directed, loops / no multi, %s", msg2);
|
||||
BENCH(msg, REPEAT(gnm(vcount, meandeg, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"12 Chung-Lu directed, loops, %s", msg2);
|
||||
BENCH(msg, REPEAT(chung_lu(&outdeg, &indeg, IGRAPH_LOOPS), rep));
|
||||
|
||||
printf("\n\n");
|
||||
|
||||
igraph_vector_destroy(&indeg);
|
||||
igraph_vector_destroy(&outdeg);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
run_bench(100, 3, 10000);
|
||||
run_bench(10000, 3, 100);
|
||||
run_bench(1000000, 3, 1);
|
||||
|
||||
run_bench(10000, 1, 1000);
|
||||
run_bench(10000, 100, 10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
#define BENCH_UNDIR(N, REP) \
|
||||
do { \
|
||||
igraph_barabasi_game(&graph, N, 1, 3, NULL, true, 0, IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE, NULL); \
|
||||
igraph_degree(&graph, °, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS); \
|
||||
igraph_destroy(&graph); \
|
||||
\
|
||||
BENCH("Undirected simple, PA, n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(°, NULL, IGRAPH_SIMPLE_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Undirected loops, PA, n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(°, NULL, IGRAPH_LOOPS_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Undirected multi, PA, n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(°, NULL, IGRAPH_MULTI_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Undirected multi, loops, PA, n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(°, NULL, IGRAPH_MULTI_SW | IGRAPH_LOOPS_SW, &graphical), 100); \
|
||||
); \
|
||||
\
|
||||
igraph_erdos_renyi_game_gnp(&graph, N, 12.0/N, IGRAPH_UNDIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED); \
|
||||
igraph_degree(&graph, °, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS); \
|
||||
igraph_destroy(&graph); \
|
||||
\
|
||||
BENCH("Undirected simple, G(n,p), n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(°, NULL, IGRAPH_SIMPLE_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Undirected loops, G(n,p), n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(°, NULL, IGRAPH_LOOPS_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Undirected multi, G(n,p), n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(°, NULL, IGRAPH_MULTI_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Undirected multi, loops, G(n,p), n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(°, NULL, IGRAPH_MULTI_SW | IGRAPH_LOOPS_SW, &graphical), 100); \
|
||||
); \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
|
||||
#define BENCH_DIR(N, REP) \
|
||||
do { \
|
||||
igraph_barabasi_game(&graph, N, 1, 3, NULL, true, 0, IGRAPH_DIRECTED, IGRAPH_BARABASI_PSUMTREE, NULL); \
|
||||
igraph_degree(&graph, &outdeg, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS); \
|
||||
igraph_degree(&graph, &indeg, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS); \
|
||||
igraph_destroy(&graph); \
|
||||
\
|
||||
BENCH("Directed simple, PA, n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(&outdeg, &indeg, IGRAPH_SIMPLE_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Directed loops, PA, n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(&outdeg, &indeg, IGRAPH_LOOPS_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Directed multi, PA, n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(&outdeg, &indeg, IGRAPH_MULTI_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Directed multi, loops, PA, n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(&outdeg, &indeg, IGRAPH_MULTI_SW | IGRAPH_LOOPS_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
igraph_erdos_renyi_game_gnp(&graph, N, 12.0/N, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED); \
|
||||
igraph_degree(&graph, &outdeg, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS); \
|
||||
igraph_degree(&graph, &indeg, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS); \
|
||||
igraph_destroy(&graph); \
|
||||
\
|
||||
BENCH("Directed simple, G(n,p), n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(&outdeg, &indeg, IGRAPH_SIMPLE_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Directed loops, G(n,p), n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(&outdeg, &indeg, IGRAPH_LOOPS_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Directed multi, G(n,p), n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(&outdeg, &indeg, IGRAPH_MULTI_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Directed multi, loops, G(n,p), n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(&outdeg, &indeg, IGRAPH_MULTI_SW | IGRAPH_LOOPS_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_int_t deg, outdeg, indeg;
|
||||
igraph_bool_t graphical;
|
||||
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
|
||||
igraph_vector_int_init(°, 0);
|
||||
igraph_vector_int_init(&outdeg, 0);
|
||||
igraph_vector_int_init(&indeg, 0);
|
||||
|
||||
BENCH_UNDIR(50, 2000000);
|
||||
BENCH_DIR(50, 2000000);
|
||||
printf("\n");
|
||||
BENCH_UNDIR(1000, 100000);
|
||||
BENCH_DIR(1000, 100000);
|
||||
printf("\n");
|
||||
BENCH_UNDIR(1000000, 100);
|
||||
BENCH_DIR(1000000, 100);
|
||||
|
||||
igraph_vector_int_destroy(°);
|
||||
igraph_vector_int_destroy(&outdeg);
|
||||
igraph_vector_int_destroy(&indeg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
/*
|
||||
* Benchmark creating graphs from dense adjacency matrices.
|
||||
*
|
||||
* When there are a small number of non-zero elements (low mean degree),
|
||||
* iterating through the matrix dominates the timing. When there are
|
||||
* many non-zero elements, creating the graphfrom its edge list dominates.
|
||||
*/
|
||||
|
||||
void adjacency(const igraph_matrix_t *adjmatrix, igraph_adjacency_t mode, igraph_loops_t loops) {
|
||||
igraph_t g;
|
||||
igraph_adjacency(&g, adjmatrix, mode, loops);
|
||||
igraph_destroy(&g);
|
||||
}
|
||||
|
||||
void weighted_adjacency(const igraph_matrix_t *adjmatrix, igraph_adjacency_t mode, igraph_vector_t *weights, igraph_loops_t loops) {
|
||||
igraph_t g;
|
||||
igraph_weighted_adjacency(&g, adjmatrix, mode, weights, loops);
|
||||
igraph_destroy(&g);
|
||||
}
|
||||
|
||||
void run_bench(igraph_int_t vcount, igraph_int_t meandeg, igraph_int_t rep) {
|
||||
igraph_t g;
|
||||
igraph_matrix_t mat;
|
||||
igraph_vector_t weights;
|
||||
char msg[128];
|
||||
igraph_adjacency_t types[] = {
|
||||
IGRAPH_ADJ_DIRECTED,
|
||||
IGRAPH_ADJ_MAX,
|
||||
IGRAPH_ADJ_PLUS,
|
||||
IGRAPH_ADJ_UPPER /* similar to DIRECTED when unweighted, similar to MAX when weighted */
|
||||
};
|
||||
const char *names[] = { "DIRECTED", "MAX", "PLUS", "UPPER" };
|
||||
|
||||
igraph_matrix_init(&mat, 0, 0);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, vcount, meandeg * vcount / 2, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW | IGRAPH_MULTI_SW,
|
||||
false);
|
||||
igraph_get_adjacency(&g, &mat, IGRAPH_GET_ADJACENCY_BOTH, NULL, IGRAPH_LOOPS_ONCE);
|
||||
|
||||
igraph_vector_init(&weights, igraph_ecount(&g));
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
for (size_t i=0; i < sizeof(types) / sizeof(types[0]); i++) {
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%2d vcount=%" IGRAPH_PRId ", meandeg=%3" IGRAPH_PRId ", %8s, unweighted, %" IGRAPH_PRId "x",
|
||||
(int) i+1, vcount, meandeg, names[i], rep);
|
||||
|
||||
BENCH(msg, REPEAT(adjacency(&mat, types[i], IGRAPH_LOOPS_ONCE), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%2d vcount=%" IGRAPH_PRId ", meandeg=%3" IGRAPH_PRId ", %8s, weighted, %" IGRAPH_PRId "x",
|
||||
(int) i+1, vcount, meandeg, names[i], rep);
|
||||
|
||||
BENCH(msg, REPEAT(weighted_adjacency(&mat, types[i], &weights, IGRAPH_LOOPS_ONCE), rep));
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
igraph_vector_destroy(&weights);
|
||||
igraph_matrix_destroy(&mat);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
run_bench(100, 5, 10000);
|
||||
run_bench(100, 50, 10000);
|
||||
run_bench(1000, 5, 100);
|
||||
run_bench(1000, 50, 100);
|
||||
run_bench(1000, 500, 100);
|
||||
run_bench(10000, 5, 1);
|
||||
run_bench(10000, 50, 1);
|
||||
run_bench(10000, 500, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_real_t avglen;
|
||||
igraph_matrix_t mat;
|
||||
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
|
||||
igraph_matrix_init(&mat, 0, 0);
|
||||
|
||||
igraph_kautz(&graph, 4, 5);
|
||||
igraph_matrix_resize(&mat, igraph_vcount(&graph), igraph_vcount(&graph)); /* preallocate matrix */
|
||||
|
||||
BENCH(" 1 Kautz(4, 5) average_path_length directed",
|
||||
igraph_average_path_length(&graph, NULL, &avglen, NULL, IGRAPH_DIRECTED, 1);
|
||||
);
|
||||
BENCH(" 2 Kautz(4, 5) distances directed",
|
||||
igraph_distances(&graph, NULL, &mat, igraph_vss_all(), igraph_vss_all(), IGRAPH_OUT);
|
||||
);
|
||||
BENCH(" 3 Kautz(4, 5) average_path_length undirected",
|
||||
igraph_average_path_length(&graph, NULL, &avglen, NULL, IGRAPH_UNDIRECTED, 1);
|
||||
);
|
||||
BENCH(" 4 Kautz(4, 5) distances undirected",
|
||||
igraph_distances(&graph, NULL, &mat, igraph_vss_all(), igraph_vss_all(), IGRAPH_ALL);
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
{
|
||||
igraph_vector_int_t dims;
|
||||
igraph_vector_bool_t periodic;
|
||||
igraph_vector_int_init_int(&dims, 3, 15, 15, 15);
|
||||
igraph_vector_bool_init_int(&periodic, 3, 1, 1, 1);
|
||||
igraph_square_lattice(&graph, &dims, 1, IGRAPH_UNDIRECTED, 0, &periodic);
|
||||
igraph_vector_int_destroy(&dims);
|
||||
igraph_vector_bool_destroy(&periodic);
|
||||
igraph_rewire(&graph, 100, IGRAPH_SIMPLE_SW, NULL);
|
||||
igraph_matrix_resize(&mat, igraph_vcount(&graph), igraph_vcount(&graph)); /* preallocate matrix */
|
||||
}
|
||||
|
||||
BENCH(" 5 Rewired 15x15x15 lattice average_path_length",
|
||||
igraph_average_path_length(&graph, NULL, &avglen, NULL, IGRAPH_UNDIRECTED, 1);
|
||||
);
|
||||
BENCH(" 6 Rewired 15x15x15 lattice distances undirected",
|
||||
igraph_distances(&graph, NULL, &mat, igraph_vss_all(), igraph_vss_all(), IGRAPH_ALL);
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 10000, 12000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_matrix_resize(&mat, igraph_vcount(&graph), igraph_vcount(&graph)); /* preallocate matrix */
|
||||
|
||||
BENCH(" 7 Erdos-Renyi n=10000 m=12000 average_path_length directed",
|
||||
igraph_average_path_length(&graph, NULL, &avglen, NULL, IGRAPH_DIRECTED, 1);
|
||||
);
|
||||
BENCH(" 8 Erdos-Renyi n=10000 m=12000 distances directed",
|
||||
igraph_distances(&graph, NULL, &mat, igraph_vss_all(), igraph_vss_all(), IGRAPH_OUT);
|
||||
);
|
||||
|
||||
/* The undirected computation will be much slower on this graph, as the largest weakly connected
|
||||
* component is much larger. */
|
||||
BENCH(" 9 Erdos-Renyi n=10000 m=12000 average_path_length undirected",
|
||||
igraph_average_path_length(&graph, NULL, &avglen, NULL, IGRAPH_UNDIRECTED, 1);
|
||||
);
|
||||
BENCH("10 Erdos-Renyi n=10000 m=12000 distances undirected",
|
||||
igraph_distances(&graph, NULL, &mat, igraph_vss_all(), igraph_vss_all(), IGRAPH_ALL);
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
igraph_matrix_destroy(&mat);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_t betweenness;
|
||||
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
|
||||
igraph_vector_init(&betweenness, 0);
|
||||
|
||||
/* Kautz and De Bruijn graphs are connected, therefore there should not be a dramatic difference
|
||||
* in the performance of the directed and undirected calculations. */
|
||||
|
||||
igraph_kautz(&graph, 4, 5);
|
||||
BENCH(" 1 Betweenness, Kautz(4,5), directed",
|
||||
igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false));
|
||||
BENCH(" 2 Betweenness, Kautz(4,5), undirected",
|
||||
igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false));
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_de_bruijn(&graph, 6, 5);
|
||||
BENCH(" 3 Betweenness, DeBruijn(6,5), directed",
|
||||
igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false));
|
||||
igraph_destroy(&graph);
|
||||
|
||||
{
|
||||
igraph_vector_int_t dims;
|
||||
|
||||
igraph_vector_int_init_int_end(&dims, -1, 8, 8, 8, 8, -1);
|
||||
igraph_square_lattice(&graph, &dims, 1, IGRAPH_UNDIRECTED, /* mutual */ 0, /* periodic */ 0);
|
||||
BENCH(" 4 Betweenness, Grid(8,8,8,8), undirected",
|
||||
igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false));
|
||||
igraph_destroy(&graph);
|
||||
igraph_vector_int_destroy(&dims);
|
||||
|
||||
igraph_vector_int_init_int_end(&dims, -1, 10, 10, 10, 10, -1);
|
||||
igraph_square_lattice(&graph, &dims, 1, IGRAPH_UNDIRECTED, /* mutual */ 0, /* periodic */ 0);
|
||||
BENCH(" 5 Betweenness, Grid(10,10,10,10), cutoff 5",
|
||||
igraph_betweenness_cutoff(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false, 5));
|
||||
BENCH(" 6 Betweenness, Grid(10,10,10,10), cutoff 8",
|
||||
igraph_betweenness_cutoff(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false, 8));
|
||||
igraph_destroy(&graph);
|
||||
igraph_vector_int_destroy(&dims);
|
||||
}
|
||||
|
||||
igraph_barabasi_game(&graph, 8000, 1, 1, NULL, 1, 0, IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
BENCH(" 7 Betweenness, Barabasi n=8000 m=1, undirected",
|
||||
igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false));
|
||||
BENCH(" 8 Betweenness, Barabasi n=8000 m=1, undirected, cutoff 6",
|
||||
igraph_betweenness_cutoff(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false, 6));
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_barabasi_game(&graph, 30000, 1, 5, NULL, 1, 0, IGRAPH_DIRECTED, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
BENCH(" 9 Betweenness, Barabasi n=30000 m=5, directed",
|
||||
igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false));
|
||||
BENCH("10 Betweenness, Barabasi n=30000 m=5, directed, cutoff 5",
|
||||
igraph_betweenness_cutoff(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false, 5));
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_vector_destroy(&betweenness);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
void rand_weight_vec(igraph_vector_t *vec, const igraph_t *graph) {
|
||||
const igraph_int_t n = igraph_ecount(graph);
|
||||
igraph_vector_resize(vec, n);
|
||||
for (igraph_int_t i=0; i < n; ++i) {
|
||||
VECTOR(*vec)[i] = RNG_UNIF(1, 10);
|
||||
}
|
||||
}
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_t betweenness, weight;
|
||||
|
||||
/* These betweenness benchmarks are identical to the weighted closeness ones. */
|
||||
|
||||
/* This benchmark compares directed/undirected and weighted/unweighted calculations
|
||||
* on the same graphs. */
|
||||
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
|
||||
igraph_vector_init(&betweenness, 0);
|
||||
igraph_vector_init(&weight, 0);
|
||||
|
||||
igraph_kautz(&graph, 4, 3);
|
||||
|
||||
/* Kautz and De Bruijn graphs are connected, therefore there should not be a dramatic difference
|
||||
* in the performance of the directed and undirected calculations. */
|
||||
|
||||
#define NAME "Kautz(4,3)"
|
||||
#define REP 100
|
||||
|
||||
BENCH(" 1 Betweenness, unweighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false), REP)
|
||||
);
|
||||
BENCH(" 2 Betweenness, unweighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false), REP)
|
||||
);
|
||||
|
||||
rand_weight_vec(&weight, &graph);
|
||||
|
||||
BENCH(" 3 Betweenness, weighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, &weight, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false), REP)
|
||||
);
|
||||
BENCH(" 4 Betweenness, weighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, &weight, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false), REP)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
#undef NAME
|
||||
#undef REP
|
||||
|
||||
#define NAME "DeBruijn(5,5)"
|
||||
#define REP 1
|
||||
|
||||
igraph_de_bruijn(&graph, 5, 5);
|
||||
|
||||
BENCH(" 5 Betweenness, unweighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false), REP)
|
||||
);
|
||||
BENCH(" 6 Betweenness, unweighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false), REP)
|
||||
);
|
||||
|
||||
rand_weight_vec(&weight, &graph);
|
||||
|
||||
BENCH(" 7 Betweenness, weighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, &weight, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false), REP)
|
||||
);
|
||||
BENCH(" 8 Betweenness, weighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, &weight, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false), REP)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
#undef NAME
|
||||
#undef REP
|
||||
|
||||
/* Choose the parameters of the Erdős-Rényi model so that the graph will have a large strongly connected
|
||||
* giant component. With 3000 vertices and 10000 edges, it is likely to contain over 90% of vertices.
|
||||
* If the graph does not have a giant component, then the directed betweenness calculation will be very
|
||||
* fast, and not directly comparable to the undirected one. */
|
||||
|
||||
#define NAME "GNM(3000,10000)"
|
||||
#define REP 1
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 3000, 10000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
|
||||
BENCH(" 9 Betweenness, unweighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false), REP)
|
||||
);
|
||||
BENCH("10 Betweenness, unweighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false), REP)
|
||||
);
|
||||
|
||||
rand_weight_vec(&weight, &graph);
|
||||
|
||||
BENCH("11 Betweenness, weighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, &weight, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false), REP)
|
||||
);
|
||||
BENCH("12 Betweenness, weighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, &weight, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false), REP)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
#undef NAME
|
||||
#undef REP
|
||||
|
||||
/* Benchmark a much denser Erdős-Rényi graph as well. */
|
||||
|
||||
#define NAME "GNM(3000,30000)"
|
||||
#define REP 1
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 3000, 30000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
|
||||
BENCH("13 Betweenness, unweighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false), REP)
|
||||
);
|
||||
BENCH("14 Betweenness, unweighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false), REP)
|
||||
);
|
||||
|
||||
rand_weight_vec(&weight, &graph);
|
||||
|
||||
BENCH("15 Betweenness, weighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, &weight, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false), REP)
|
||||
);
|
||||
BENCH("16 Betweenness, weighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, &weight, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false), REP)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_vector_destroy(&weight);
|
||||
igraph_vector_destroy(&betweenness);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
igraph_vector_int_list_t res;
|
||||
igraph_int_t res_int;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_vector_int_list_init(&res, 0);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 100, 3000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
BENCH(" 1 Cliques in random graph with 100 vertices and 3000 edges",
|
||||
igraph_cliques(&g, &res, /* min_size= */ 0, /* max_size= */ 0, -1);
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_vector_int_list_clear(&res);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 200, 10000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
BENCH(" 2 Cliques in random graph with 200 vertices and 10000 edges, up to size 5",
|
||||
igraph_cliques(&g, &res, /* min_size= */ 0, /* max_size= */ 5, -1);
|
||||
);
|
||||
igraph_vector_int_list_clear(&res);
|
||||
BENCH(" 3 Clique number of the same graph with 200 vertices and 10000 edges",
|
||||
igraph_clique_number(&g, &res_int);
|
||||
);
|
||||
igraph_vector_int_list_clear(&res);
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_vector_int_list_destroy(&res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
void rand_weight_vec(igraph_vector_t *vec, const igraph_t *graph) {
|
||||
const igraph_int_t n = igraph_ecount(graph);
|
||||
igraph_vector_resize(vec, n);
|
||||
for (igraph_int_t i=0; i < n; ++i) {
|
||||
VECTOR(*vec)[i] = RNG_UNIF(1, 10);
|
||||
}
|
||||
}
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_t closeness, weight;
|
||||
|
||||
/* These closeness benchmarks are identical to the weighted betweenness ones. */
|
||||
|
||||
/* This benchmark compares directed/undirected and weighted/unweighted calculations
|
||||
* on the same graphs. */
|
||||
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
|
||||
igraph_vector_init(&closeness, 0);
|
||||
igraph_vector_init(&weight, 0);
|
||||
|
||||
igraph_kautz(&graph, 4, 3);
|
||||
|
||||
/* Kautz and De Bruijn graphs are connected, therefore there should not be a dramatic difference
|
||||
* in the performance of the directed and undirected calculations. */
|
||||
|
||||
#define NAME "Kautz(4,3)"
|
||||
#define REP 100
|
||||
|
||||
BENCH(" 1 Closeness, unweighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_OUT, NULL, 1), REP)
|
||||
);
|
||||
BENCH(" 2 Closeness, unweighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_ALL, NULL, 1), REP)
|
||||
);
|
||||
|
||||
rand_weight_vec(&weight, &graph);
|
||||
|
||||
BENCH(" 3 Closeness, weighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_OUT, &weight, 1), REP)
|
||||
);
|
||||
BENCH(" 4 Closeness, weighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_ALL, &weight, 1), REP)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
#undef NAME
|
||||
#undef REP
|
||||
|
||||
#define NAME "DeBruijn(5,5)"
|
||||
#define REP 1
|
||||
|
||||
igraph_de_bruijn(&graph, 5, 5);
|
||||
|
||||
BENCH(" 5 Closeness, unweighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_OUT, NULL, 1), REP)
|
||||
);
|
||||
BENCH(" 6 Closeness, unweighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_ALL, NULL, 1), REP)
|
||||
);
|
||||
|
||||
rand_weight_vec(&weight, &graph);
|
||||
|
||||
BENCH(" 7 Closeness, weighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_OUT, &weight, 1), REP)
|
||||
);
|
||||
BENCH(" 8 Closeness, weighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_ALL, &weight, 1), REP)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
#undef NAME
|
||||
#undef REP
|
||||
|
||||
/* Choose the parameters of the Erdős-Rényi model so that the graph will have a large strongly connected
|
||||
* giant component. With 3000 vertices and 10000 edges, it is likely to contain over 90% of vertices.
|
||||
* If the graph does not have a giant component, then the directed betweenness calculation will be very
|
||||
* fast, and not directly comparable to the undirected one. */
|
||||
|
||||
#define NAME "GNM(3000,10000)"
|
||||
#define REP 1
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 3000, 10000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
|
||||
BENCH(" 9 Closeness, unweighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_OUT, NULL, 1), REP)
|
||||
);
|
||||
BENCH("10 Closeness, unweighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_ALL, NULL, 1), REP)
|
||||
);
|
||||
|
||||
rand_weight_vec(&weight, &graph);
|
||||
|
||||
BENCH("11 Closeness, weighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_OUT, &weight, 1), REP)
|
||||
);
|
||||
BENCH("12 Closeness, weighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_ALL, &weight, 1), REP)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
#undef NAME
|
||||
#undef REP
|
||||
|
||||
/* Benchmark a much denser Erdős-Rényi graph as well. */
|
||||
|
||||
#define NAME "GNM(3000,30000)"
|
||||
#define REP 1
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 3000, 30000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
|
||||
BENCH("13 Closeness, unweighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_OUT, NULL, 1), REP)
|
||||
);
|
||||
BENCH("14 Closeness, unweighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_ALL, NULL, 1), REP)
|
||||
);
|
||||
|
||||
rand_weight_vec(&weight, &graph);
|
||||
|
||||
BENCH("15 Closeness, weighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_OUT, &weight, 1), REP)
|
||||
);
|
||||
BENCH("16 Closeness, weighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_ALL, &weight, 1), REP)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_vector_destroy(&weight);
|
||||
igraph_vector_destroy(&closeness);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
igraph_graph_list_t res;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_graph_list_init(&res, 0);
|
||||
|
||||
igraph_empty(&g, 1000, IGRAPH_UNDIRECTED);
|
||||
BENCH(" 1 Decompose graph with 1000 isolated vertices",
|
||||
igraph_decompose(&g, &res, IGRAPH_WEAK, -1, -1);
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_graph_list_clear(&res);
|
||||
|
||||
igraph_empty(&g, 10000, IGRAPH_UNDIRECTED);
|
||||
BENCH(" 2 Decompose graph with 10000 isolated vertices",
|
||||
igraph_decompose(&g, &res, IGRAPH_WEAK, -1, -1);
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_graph_list_clear(&res);
|
||||
|
||||
igraph_empty(&g, 100000, IGRAPH_UNDIRECTED);
|
||||
BENCH(" 3 Decompose graph with 100000 isolated vertices",
|
||||
igraph_decompose(&g, &res, IGRAPH_WEAK, -1, -1);
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_graph_list_clear(&res);
|
||||
|
||||
igraph_graph_list_destroy(&res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
/* Calls igraph_degree_1() separately for each vertex. */
|
||||
void deg1(const igraph_t *g, igraph_vector_int_t *res, igraph_neimode_t mode, igraph_loops_t loops) {
|
||||
igraph_int_t n = igraph_vcount(g);
|
||||
igraph_vector_int_resize(res, n);
|
||||
for (igraph_int_t i=0; i < n; i++) {
|
||||
igraph_degree_1(g, &VECTOR(*res)[i], i, mode, loops);
|
||||
}
|
||||
}
|
||||
|
||||
/* Calls igraph_degree() separately for each vertex, pre-allocates work vector. */
|
||||
void degv(const igraph_t *g, igraph_vector_int_t *res, igraph_neimode_t mode, igraph_loops_t loops) {
|
||||
igraph_int_t n = igraph_vcount(g);
|
||||
igraph_vector_int_t work;
|
||||
|
||||
igraph_vector_int_resize(res, n);
|
||||
igraph_vector_int_init(&work, 1);
|
||||
for (igraph_int_t i=0; i < n; i++) {
|
||||
igraph_degree(g, &work, igraph_vss_1(i), mode, loops);
|
||||
}
|
||||
igraph_vector_int_destroy(&work);
|
||||
}
|
||||
|
||||
/* Calls igraph_degree() separately for each vertex, allocates a new work vector each time. */
|
||||
void degv2(const igraph_t *g, igraph_vector_int_t *res, igraph_neimode_t mode, igraph_loops_t loops) {
|
||||
igraph_int_t n = igraph_vcount(g);
|
||||
|
||||
for (igraph_int_t i=0; i < n; i++) {
|
||||
igraph_vector_int_t work;
|
||||
igraph_vector_int_init(&work, 1);
|
||||
igraph_degree(g, &work, igraph_vss_1(i), mode, loops);
|
||||
igraph_vector_int_destroy(&work);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
igraph_vector_int_t degs;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_barabasi_game(&g, 100000, 1, 10, NULL, true, 0, IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE_MULTIPLE, NULL);
|
||||
igraph_vector_int_init(°s, igraph_vcount(&g));
|
||||
|
||||
#define REP 1000
|
||||
|
||||
printf("Count loops twice, O(1) per degree, fast methods only.\n");
|
||||
|
||||
BENCH(" 1 igraph_degree(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_degree(&g, °s, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 2 deg1(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(deg1(&g, °s, IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
|
||||
#undef REP
|
||||
|
||||
#define REP 100
|
||||
|
||||
printf("\nCount loops twice, O(1) per degree.\n");
|
||||
|
||||
BENCH(" 1 igraph_degree(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_degree(&g, °s, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 2 deg1(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(deg1(&g, °s, IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 3 degv(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(degv(&g, °s, IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 4 degv2(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(degv2(&g, °s, IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
|
||||
#undef REP
|
||||
|
||||
#define REP 100
|
||||
|
||||
printf("\nCount loops twice, O(1) per degree.\n");
|
||||
|
||||
BENCH(" 1 igraph_degree(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_degree(&g, °s, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 2 deg1(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(deg1(&g, °s, IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 3 degv(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(degv(&g, °s, IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 4 degv2(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(degv2(&g, °s, IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
|
||||
#undef REP
|
||||
|
||||
#define REP 100
|
||||
|
||||
printf("\nDo not count loops, O(d) per degree.\n");
|
||||
|
||||
BENCH(" 1 igraph_degree(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_degree(&g, °s, igraph_vss_all(), IGRAPH_ALL, IGRAPH_NO_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 2 deg1(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(deg1(&g, °s, IGRAPH_ALL, IGRAPH_NO_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 3 degv(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(degv(&g, °s, IGRAPH_ALL, IGRAPH_NO_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 4 degv2(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(degv2(&g, °s, IGRAPH_ALL, IGRAPH_NO_LOOPS), REP);
|
||||
);
|
||||
|
||||
igraph_vector_int_destroy(°s);
|
||||
igraph_destroy(&g);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t g, template;
|
||||
igraph_vector_int_t degrees, outdeg, indeg;
|
||||
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
|
||||
/* This benchmark indirectly tests the performance of igraph_set_t at the
|
||||
* moment because igraph_degree_sequence_game() (especially the
|
||||
* IGRAPH_DEGSEQ_CONFIGURATION_SIMPLE mode) heavily relies on sets.
|
||||
* This might change in future versions so the name of the benchmark
|
||||
* reflects the name of the function that is tested directly */
|
||||
|
||||
igraph_vector_int_init(°rees, 1000);
|
||||
igraph_vector_int_fill(°rees, 7);
|
||||
BENCH(" 1 Degseq of undirected k-regular, N=1000, k=7, CONFIGURATION_SIMPLE",
|
||||
igraph_degree_sequence_game(&g, °rees, /* indeg = */ NULL, IGRAPH_DEGSEQ_CONFIGURATION_SIMPLE)
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_vector_int_destroy(°rees);
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
igraph_vector_int_init(°rees, 0);
|
||||
igraph_barabasi_game(&template, 1000, /* power = */ 1, /* m = */ 1,
|
||||
/* outseq = */ NULL, /* outpref = */ true, /* A = */ 0,
|
||||
IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE, /* start_from = */ NULL
|
||||
);
|
||||
igraph_degree(&template, °rees, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS);
|
||||
BENCH(" 2 Degseq of undirected BA, N=1000, m=1, CONFIGURATION_SIMPLE",
|
||||
igraph_degree_sequence_game(&g, °rees, /* indeg = */ NULL, IGRAPH_DEGSEQ_CONFIGURATION_SIMPLE)
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_destroy(&template);
|
||||
igraph_vector_int_destroy(°rees);
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
igraph_vector_int_init(°rees, 0);
|
||||
igraph_erdos_renyi_game_gnm(&template, 200, 600, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_degree(&template, °rees, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS);
|
||||
BENCH(" 3 Degseq of undirected G(n,m), N=150, m=450, CONFIGURATION_SIMPLE",
|
||||
igraph_degree_sequence_game(&g, °rees, /* indeg = */ NULL, IGRAPH_DEGSEQ_CONFIGURATION_SIMPLE)
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_destroy(&template);
|
||||
igraph_vector_int_destroy(°rees);
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
igraph_vector_int_init(°rees, 0);
|
||||
igraph_grg_game(&template, 10000, 0.013, /* torus = */ false, /* x = */ NULL, /* y = */ NULL);
|
||||
igraph_degree(&template, °rees, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS);
|
||||
BENCH(" 4 Degseq of GRG, N=10000, r=0.013, CONFIGURATION_SIMPLE",
|
||||
igraph_degree_sequence_game(&g, °rees, /* indeg = */ NULL, IGRAPH_DEGSEQ_CONFIGURATION_SIMPLE)
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_destroy(&template);
|
||||
igraph_vector_int_destroy(°rees);
|
||||
|
||||
igraph_vector_int_init(°rees, 1000);
|
||||
igraph_vector_int_fill(°rees, 5);
|
||||
BENCH(" 5 Degseq of directed k-regular, N=1000, k=5, CONFIGURATION_SIMPLE",
|
||||
igraph_degree_sequence_game(&g, °rees, °rees, IGRAPH_DEGSEQ_CONFIGURATION_SIMPLE)
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_vector_int_destroy(°rees);
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
igraph_vector_int_init(&outdeg, 0);
|
||||
igraph_vector_int_init(&indeg, 0);
|
||||
igraph_barabasi_game(&template, 5000, /* power = */ 1, /* m = */ 2,
|
||||
/* outseq = */ NULL, /* outpref = */ true, /* A = */ 0,
|
||||
IGRAPH_DIRECTED, IGRAPH_BARABASI_PSUMTREE, /* start_from = */ NULL
|
||||
);
|
||||
igraph_degree(&template, &outdeg, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS);
|
||||
igraph_degree(&template, &indeg, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS);
|
||||
BENCH(" 6 Degseq of directed BA, N=500, m=2, CONFIGURATION_SIMPLE",
|
||||
igraph_degree_sequence_game(&g, &outdeg, &indeg, IGRAPH_DEGSEQ_CONFIGURATION_SIMPLE)
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_destroy(&template);
|
||||
igraph_vector_int_destroy(&indeg);
|
||||
igraph_vector_int_destroy(&outdeg);
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
igraph_vector_int_init(&outdeg, 0);
|
||||
igraph_vector_int_init(&indeg, 0);
|
||||
igraph_erdos_renyi_game_gnm(&template, 15000, 45000, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_degree(&template, &outdeg, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS);
|
||||
igraph_degree(&template, &indeg, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS);
|
||||
BENCH(" 7 Degseq of directed G(n,m), N=15000, m=45000, CONFIGURATION_SIMPLE",
|
||||
igraph_degree_sequence_game(&g, &outdeg, &indeg, IGRAPH_DEGSEQ_CONFIGURATION_SIMPLE)
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_destroy(&template);
|
||||
igraph_vector_int_destroy(&indeg);
|
||||
igraph_vector_int_destroy(&outdeg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2025 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
void bench_delaunay(const char *message, igraph_int_t point_count, igraph_int_t dimensions) {
|
||||
igraph_matrix_t points;
|
||||
igraph_t g;
|
||||
char msg[200];
|
||||
|
||||
igraph_matrix_init(&points, point_count, dimensions);
|
||||
|
||||
for (igraph_int_t point = 0; point < point_count; point++) {
|
||||
for (igraph_int_t dim = 0; dim < dimensions; dim++) {
|
||||
MATRIX(points, point, dim) = RNG_UNIF01();
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%s Delaunay triangulation in %dD, n=%6" IGRAPH_PRId,
|
||||
message, (int) dimensions, point_count);
|
||||
|
||||
BENCH(msg, igraph_delaunay_graph(&g, &points));
|
||||
|
||||
igraph_destroy(&g);
|
||||
igraph_matrix_destroy(&points);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 20250814);
|
||||
|
||||
bench_delaunay(" 1", 1000000, 1);
|
||||
bench_delaunay(" 2", 100000, 2);
|
||||
bench_delaunay(" 3", 10000, 2);
|
||||
bench_delaunay(" 4", 1000, 2);
|
||||
bench_delaunay(" 5", 100, 2);
|
||||
bench_delaunay(" 6", 10000, 3);
|
||||
bench_delaunay(" 7", 1000, 3);
|
||||
bench_delaunay(" 8", 100, 3);
|
||||
bench_delaunay(" 9", 2000, 4);
|
||||
bench_delaunay("10", 500, 5);
|
||||
bench_delaunay("11", 200, 6);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2025 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
void bench_gnp(igraph_int_t n, igraph_real_t p, igraph_bool_t directed, igraph_real_t negloop, int rep) {
|
||||
igraph_t g;
|
||||
igraph_matrix_t res;
|
||||
igraph_vector_t weights;
|
||||
char msg[200];
|
||||
|
||||
igraph_matrix_init(&res, 0, 0);
|
||||
igraph_vector_init(&weights, 0);
|
||||
|
||||
/* IGRAPH_NO_LOOPS, as loops are not allowed with negative weights. */
|
||||
igraph_erdos_renyi_game_gnp(&g, n, p, directed, IGRAPH_MULTI_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_matrix_resize(&res, igraph_vcount(&g), igraph_vcount(&g));
|
||||
igraph_vector_resize(&weights, igraph_ecount(&g));
|
||||
|
||||
for (igraph_int_t i=0; i < igraph_ecount(&g); i++) {
|
||||
VECTOR(weights)[i] = RNG_EXP(1);
|
||||
}
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 1 n=%d, p=%g, %s, Unweighted, %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances(&g, NULL, &res, igraph_vss_all(), igraph_vss_all(), IGRAPH_OUT), rep);
|
||||
);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 2 n=%d, p=%g, %s, Dijkstra, %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances_dijkstra(&g, &res, igraph_vss_all(), igraph_vss_all(), &weights, IGRAPH_OUT), rep)
|
||||
);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 3 n=%d, p=%g, %s, Unweighted Floyd-Warshall, %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances_floyd_warshall(&g, &res, igraph_vss_all(), igraph_vss_all(), NULL, IGRAPH_OUT, IGRAPH_FLOYD_WARSHALL_ORIGINAL), rep)
|
||||
);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 4 n=%d, p=%g, %s, Unweighted Floyd-Warshall-tree-speedup, %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances_floyd_warshall(&g, &res, igraph_vss_all(), igraph_vss_all(), NULL, IGRAPH_OUT, IGRAPH_FLOYD_WARSHALL_TREE), rep)
|
||||
);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 5 n=%d, p=%g, %s, Floyd-Warshall, %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances_floyd_warshall(&g, &res, igraph_vss_all(), igraph_vss_all(), &weights, IGRAPH_OUT, IGRAPH_FLOYD_WARSHALL_ORIGINAL), rep)
|
||||
);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 6 n=%d, p=%g, %s, Floyd-Warshall-tree-speedup, %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances_floyd_warshall(&g, &res, igraph_vss_all(), igraph_vss_all(), &weights, IGRAPH_OUT, IGRAPH_FLOYD_WARSHALL_TREE), rep)
|
||||
);
|
||||
|
||||
/* Negative weights, only for directed graphs. */
|
||||
|
||||
if (! directed) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Add a small number of negative weights, rely on luck, as well as tuning 'negloop',
|
||||
* to avoid negative loops. */
|
||||
for (igraph_int_t i=0; i < trunc(negloop * igraph_ecount(&g)); i++) {
|
||||
/* For reproducibility, do not write two RNG_...() calls within the same statement,
|
||||
* as the C language does not guarantee any evaluation order between them. */
|
||||
igraph_real_t w = RNG_UNIF(-negloop, 0);
|
||||
VECTOR(weights)[RNG_INTEGER(0, igraph_ecount(&g)-1)] = w;
|
||||
}
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 7 n=%d, p=%g, %s, Bellman-Ford (negative), %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances_bellman_ford(&g, &res, igraph_vss_all(), igraph_vss_all(), &weights, IGRAPH_OUT), rep)
|
||||
);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 8 n=%d, p=%g, %s, Johnson (negative), %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances_johnson(&g, &res, igraph_vss_all(), igraph_vss_all(), &weights, IGRAPH_OUT), rep)
|
||||
);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 9 n=%d, p=%g, %s, Floyd-Warshall (negative), %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances_floyd_warshall(&g, &res, igraph_vss_all(), igraph_vss_all(), &weights, IGRAPH_OUT, IGRAPH_FLOYD_WARSHALL_ORIGINAL), rep)
|
||||
);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"10 n=%d, p=%g, %s, Floyd-Warshall-tree-speedup (negative), %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances_floyd_warshall(&g, &res, igraph_vss_all(), igraph_vss_all(), &weights, IGRAPH_OUT, IGRAPH_FLOYD_WARSHALL_TREE), rep)
|
||||
);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
/*
|
||||
bench_gnp(100, 0.5, IGRAPH_DIRECTED, 0.01, 200); printf("\n");
|
||||
bench_gnp(100, 0.5, IGRAPH_UNDIRECTED, 0.01, 200); printf("\n");
|
||||
|
||||
bench_gnp(30, 0.5, IGRAPH_DIRECTED, 0.01, 2000); printf("\n");
|
||||
bench_gnp(30, 0.5, IGRAPH_UNDIRECTED, 0.01, 2000); printf("\n");
|
||||
|
||||
bench_gnp(100, 0.1, IGRAPH_DIRECTED, 0.01, 1000); printf("\n");
|
||||
bench_gnp(100, 0.1, IGRAPH_UNDIRECTED, 0.01, 1000); printf("\n");
|
||||
|
||||
bench_gnp(500, 0.1, IGRAPH_DIRECTED, 0.005, 10); printf("\n");
|
||||
bench_gnp(500, 0.1, IGRAPH_UNDIRECTED, 0.005, 10); printf("\n");
|
||||
|
||||
bench_gnp(1500, 0.02, IGRAPH_DIRECTED, 0.01, 1); printf("\n");
|
||||
bench_gnp(1500, 0.02, IGRAPH_UNDIRECTED, 0.01, 1); printf("\n");
|
||||
*/
|
||||
|
||||
bench_gnp(1000, 0.1, IGRAPH_DIRECTED, 0.002, 1); printf("\n");
|
||||
|
||||
bench_gnp(300, 0.1, IGRAPH_DIRECTED, 0.005, 50); printf("\n");
|
||||
|
||||
bench_gnp(100, 0.1, IGRAPH_DIRECTED, 0.01, 500); printf("\n");
|
||||
|
||||
bench_gnp(50, 0.1, IGRAPH_DIRECTED, 0.01, 10000); printf("\n");
|
||||
|
||||
bench_gnp(30, 0.1, IGRAPH_DIRECTED, 0.01, 20000); printf("\n");
|
||||
|
||||
bench_gnp(20, 0.2, IGRAPH_DIRECTED, 0.01, 40000); printf("\n");
|
||||
|
||||
bench_gnp(10, 0.2, IGRAPH_DIRECTED, 0.01, 100000); printf("\n");
|
||||
|
||||
bench_gnp(1500, 0.01, IGRAPH_DIRECTED, 0.01, 1); printf("\n");
|
||||
|
||||
bench_gnp(100, 0.5, IGRAPH_DIRECTED, 0.01, 1000); printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
#define BENCH_BLOCK() \
|
||||
BENCH(" 1 vc=" TOSTR(VCOUNT) ", ec=" TOSTR(ECOUNT) ", k=3, all, " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_ecc(&g, &ecc, igraph_ess_all(IGRAPH_EDGEORDER_ID), 3, false, true), REP); \
|
||||
); \
|
||||
BENCH(" 2 vc=" TOSTR(VCOUNT) ", ec=" TOSTR(ECOUNT) ", k=3, subset: all, " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_ecc(&g, &ecc, igraph_ess_range(0, igraph_ecount(&g)), 3, false, true), REP); \
|
||||
); \
|
||||
\
|
||||
igraph_random_sample(&eids, 0, igraph_ecount(&g)-1, SS); \
|
||||
\
|
||||
BENCH(" 3 vc=" TOSTR(VCOUNT) ", ec=" TOSTR(ECOUNT) ", k=3, subset: " TOSTR(SS) ", " TOSTR(SREP) "x", \
|
||||
REPEAT(igraph_ecc(&g, &ecc, igraph_ess_vector(&eids), 3, false, true), SREP); \
|
||||
); \
|
||||
\
|
||||
BENCH(" 4 vc=" TOSTR(VCOUNT) ", ec=" TOSTR(ECOUNT) ", k=4, all, " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_ecc(&g, &ecc, igraph_ess_all(IGRAPH_EDGEORDER_ID), 4, false, true), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH(" 4 vc=" TOSTR(VCOUNT) ", ec=" TOSTR(ECOUNT) ", k=4, subset: all, " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_ecc(&g, &ecc, igraph_ess_range(0, igraph_ecount(&g)), 4, false, true), REP); \
|
||||
); \
|
||||
BENCH(" 5 vc=" TOSTR(VCOUNT) ", ec=" TOSTR(ECOUNT) ", k=4, subset: " TOSTR(SS) ", " TOSTR(SREP) "x", \
|
||||
REPEAT(igraph_ecc(&g, &ecc, igraph_ess_vector(&eids), 4, false, true), SREP); \
|
||||
);
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
igraph_vector_t ecc;
|
||||
igraph_vector_int_t eids;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_vector_init(&ecc, 0);
|
||||
igraph_vector_int_init(&eids, 0);
|
||||
|
||||
printf("Erdos-Renyi GNM:\n\n");
|
||||
|
||||
#define VCOUNT 100
|
||||
#define ECOUNT 5000
|
||||
#define REP 100
|
||||
#define SS 100
|
||||
#define SREP 1000
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, VCOUNT, ECOUNT, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_resize(&ecc, igraph_ecount(&g));
|
||||
|
||||
BENCH_BLOCK()
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef ECOUNT
|
||||
#undef REP
|
||||
#undef SS
|
||||
#undef SREP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 1000
|
||||
#define ECOUNT 5000
|
||||
#define REP 100
|
||||
#define SS 100
|
||||
#define SREP 1000
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, VCOUNT, ECOUNT, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_resize(&ecc, igraph_ecount(&g));
|
||||
|
||||
BENCH_BLOCK()
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef ECOUNT
|
||||
#undef REP
|
||||
#undef SS
|
||||
#undef SREP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 10000
|
||||
#define ECOUNT 10000
|
||||
#define REP 100
|
||||
#define SS 100
|
||||
#define SREP 1000
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, VCOUNT, ECOUNT, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_resize(&ecc, igraph_ecount(&g));
|
||||
|
||||
BENCH_BLOCK()
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef ECOUNT
|
||||
#undef REP
|
||||
#undef SS
|
||||
#undef SREP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 10000
|
||||
#define ECOUNT 50000
|
||||
#define REP 100
|
||||
#define SS 100
|
||||
#define SREP 1000
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, VCOUNT, ECOUNT, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_resize(&ecc, igraph_ecount(&g));
|
||||
|
||||
BENCH_BLOCK()
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef ECOUNT
|
||||
#undef REP
|
||||
#undef SS
|
||||
#undef SREP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 10000
|
||||
#define ECOUNT 50000
|
||||
#define REP 100
|
||||
#define SS 100
|
||||
#define SREP 1000
|
||||
|
||||
printf("Barabasi:\n\n");
|
||||
|
||||
igraph_barabasi_game(&g,
|
||||
VCOUNT, 1, ECOUNT / VCOUNT, NULL, true, 0,
|
||||
IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE_MULTIPLE, NULL);
|
||||
igraph_vector_resize(&ecc, igraph_ecount(&g));
|
||||
|
||||
BENCH_BLOCK()
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef ECOUNT
|
||||
#undef REP
|
||||
#undef SS
|
||||
#undef SREP
|
||||
|
||||
igraph_vector_int_destroy(&eids);
|
||||
igraph_vector_destroy(&ecc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2025 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
// Function to generate random vertex indices for subgraph extraction
|
||||
void generate_random_vertices(igraph_vector_int_t *vertices,
|
||||
igraph_int_t graph_size,
|
||||
igraph_int_t subset_size) {
|
||||
igraph_vector_int_init(vertices, 0);
|
||||
igraph_vector_int_resize(vertices, subset_size);
|
||||
|
||||
// Create a vector to track used vertices
|
||||
igraph_vector_int_t used_vertices;
|
||||
igraph_vector_int_init(&used_vertices, graph_size);
|
||||
for (igraph_int_t i = 0; i < graph_size; i++) {
|
||||
VECTOR(used_vertices)[i] = i;
|
||||
}
|
||||
|
||||
// Randomly select subset_size unique vertices
|
||||
for (igraph_int_t i = 0; i < subset_size; i++) {
|
||||
igraph_int_t index = RNG_INTEGER(0, graph_size - i - 1);
|
||||
VECTOR(*vertices)[i] = VECTOR(used_vertices)[index];
|
||||
|
||||
// Remove the selected vertex from used_vertices
|
||||
VECTOR(used_vertices)[index] = VECTOR(used_vertices)[graph_size - i - 1];
|
||||
}
|
||||
|
||||
// Sort the vertices to simulate real-world scenarios
|
||||
igraph_vector_int_sort(vertices);
|
||||
|
||||
igraph_vector_int_destroy(&used_vertices);
|
||||
}
|
||||
|
||||
// Benchmark function
|
||||
void bench_induced_subgraph(igraph_t *graph, igraph_vector_int_t *vertices,
|
||||
igraph_subgraph_implementation_t impl) {
|
||||
igraph_t subgraph;
|
||||
igraph_vs_t vs;
|
||||
|
||||
igraph_vs_vector(&vs, vertices);
|
||||
igraph_induced_subgraph(graph, &subgraph, vs, impl);
|
||||
igraph_vs_destroy(&vs);
|
||||
igraph_destroy(&subgraph);
|
||||
}
|
||||
|
||||
void run_bench(int i, int n, int m, int subset_percentage) {
|
||||
igraph_t graph;
|
||||
igraph_vector_int_t vertices;
|
||||
|
||||
// Calculate subset size based on percentage
|
||||
igraph_int_t subset_size = (n * subset_percentage) / 100;
|
||||
|
||||
// Prepare random graph and vertices
|
||||
igraph_erdos_renyi_game_gnm(&graph, n, m, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
generate_random_vertices(&vertices, n, subset_size);
|
||||
|
||||
char msg[255];
|
||||
int rep = 300000000 / (n * subset_percentage);
|
||||
|
||||
// Benchmark method 1 (COPY_AND_DELETE)
|
||||
snprintf(msg, sizeof(msg),
|
||||
"Method 1 (COPY_AND_DELETE): n=%5d, subset=%3d%%, %dx", n,
|
||||
subset_percentage, rep);
|
||||
BENCH(msg, REPEAT(bench_induced_subgraph(&graph, &vertices,
|
||||
IGRAPH_SUBGRAPH_COPY_AND_DELETE),
|
||||
rep));
|
||||
|
||||
// Benchmark method 2 (CREATE_FROM_SCRATCH)
|
||||
snprintf(msg, sizeof(msg),
|
||||
"Method 2 (CREATE_FROM_SCRATCH): n=%5d, subset=%3d%%, %dx", n,
|
||||
subset_percentage, rep);
|
||||
BENCH(msg, REPEAT(bench_induced_subgraph(&graph, &vertices,
|
||||
IGRAPH_SUBGRAPH_CREATE_FROM_SCRATCH),
|
||||
rep));
|
||||
|
||||
// Cleanup
|
||||
igraph_vector_int_destroy(&vertices);
|
||||
igraph_destroy(&graph);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int i = 0;
|
||||
|
||||
// Initialize random number generator
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
BENCH_INIT();
|
||||
|
||||
// Macro to run benchmarks for different graph sizes and subset percentages
|
||||
#define BENCHSET(n, m) \
|
||||
run_bench(++i, n, m, 20); /* 20% subset */ \
|
||||
run_bench(++i, n, m, 25); /* 25% subset */ \
|
||||
run_bench(++i, n, m, 30); /* 30% subset */ \
|
||||
run_bench(++i, n, m, 35); /* 35% subset */ \
|
||||
run_bench(++i, n, m, 40); /* 40% subset */ \
|
||||
run_bench(++i, n, m, 45); /* 45% subset */ \
|
||||
run_bench(++i, n, m, 50); /* 50% subset */ \
|
||||
run_bench(++i, n, m, 55); /* 55% subset */ \
|
||||
printf("\n");
|
||||
|
||||
// Benchmark different graph sizes
|
||||
BENCHSET(100, 500);
|
||||
BENCHSET(1000, 5000);
|
||||
BENCHSET(10000, 50000);
|
||||
BENCHSET(100000, 500000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
#define BARABASI_GRAPH_VERTEX_COUNT 100000
|
||||
|
||||
void unit_test_subgraph_edges(
|
||||
const igraph_t *graph, igraph_vector_int_t *vertices,
|
||||
igraph_int_t induced_subgraph_vertice_count, igraph_int_t benchmark_count,
|
||||
const char* bench_message
|
||||
) {
|
||||
igraph_vector_int_t edges;
|
||||
igraph_vector_int_init(&edges, 0);
|
||||
|
||||
IGRAPH_UNUSED(vertices);
|
||||
|
||||
BENCH(bench_message,
|
||||
REPEAT(
|
||||
igraph_induced_subgraph_edges(graph, igraph_vss_range(0, induced_subgraph_vertice_count), &edges),
|
||||
benchmark_count
|
||||
)
|
||||
);
|
||||
|
||||
igraph_vector_int_destroy(&edges);
|
||||
}
|
||||
|
||||
void bench_induced_subgraph_edges(void) {
|
||||
igraph_t g;
|
||||
igraph_vector_int_t vertices;
|
||||
|
||||
igraph_vector_int_init_range(&vertices, 0, BARABASI_GRAPH_VERTEX_COUNT);
|
||||
igraph_vector_int_shuffle(&vertices);
|
||||
|
||||
igraph_barabasi_game(&g, BARABASI_GRAPH_VERTEX_COUNT, 1, 100, NULL, true, 0,
|
||||
IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE_MULTIPLE, NULL);
|
||||
|
||||
printf("induced_subgraph_edges() for BA graph\n");
|
||||
|
||||
#define REP 10
|
||||
|
||||
#define INDUCED_SUBGRAPH_VERTEX_COUNT 100
|
||||
unit_test_subgraph_edges(&g, &vertices, INDUCED_SUBGRAPH_VERTEX_COUNT, REP,
|
||||
"n=" TOSTR(BARABASI_GRAPH_VERTEX_COUNT) ", "
|
||||
"m=100, "
|
||||
"e=" TOSTR(INDUCED_SUBGRAPH_VERTEX_COUNT) ", "
|
||||
TOSTR(REP) " x"
|
||||
);
|
||||
#undef INDUCED_SUBGRAPH_VERTEX_COUNT
|
||||
|
||||
#define INDUCED_SUBGRAPH_VERTEX_COUNT 1000
|
||||
unit_test_subgraph_edges(&g, &vertices, INDUCED_SUBGRAPH_VERTEX_COUNT, REP,
|
||||
"n=" TOSTR(BARABASI_GRAPH_VERTEX_COUNT) ", "
|
||||
"m=100, "
|
||||
"e=" TOSTR(INDUCED_SUBGRAPH_VERTEX_COUNT) ", "
|
||||
TOSTR(REP) " x"
|
||||
);
|
||||
#undef INDUCED_SUBGRAPH_VERTEX_COUNT
|
||||
|
||||
#define INDUCED_SUBGRAPH_VERTEX_COUNT 10000
|
||||
unit_test_subgraph_edges(&g, &vertices, INDUCED_SUBGRAPH_VERTEX_COUNT, REP,
|
||||
"n=" TOSTR(BARABASI_GRAPH_VERTEX_COUNT) ", "
|
||||
"m=100, "
|
||||
"e=" TOSTR(INDUCED_SUBGRAPH_VERTEX_COUNT) ", "
|
||||
TOSTR(REP) " x"
|
||||
);
|
||||
#undef INDUCED_SUBGRAPH_VERTEX_COUNT
|
||||
|
||||
#undef REP
|
||||
|
||||
igraph_destroy(&g);
|
||||
igraph_vector_int_destroy(&vertices);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
bench_induced_subgraph_edges();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_t distances;
|
||||
igraph_matrix_t layout;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_matrix_init(&layout, 0, 0);
|
||||
|
||||
|
||||
igraph_small(&graph, 12, IGRAPH_UNDIRECTED,
|
||||
0,1, 0,2, 0,3, 1,2, 1,3, 2,3,
|
||||
3,4, 4,5, 5,6,
|
||||
6,7, 7,8, 6,8, 7,9, 6,9, 8,9, 7,10, 8,10, 9,10, 10,11, 9,11, 8,11, 7,11,
|
||||
-1);
|
||||
igraph_vector_init_real(&distances,
|
||||
igraph_ecount(&graph),
|
||||
0.1, 0.09, 0.12, 0.09, 0.1, 0.1,
|
||||
0.9, 0.9, 0.9,
|
||||
0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.08, 0.05, 0.1, 0.08, 0.12, 0.09, 0.11
|
||||
);
|
||||
|
||||
#define EPOCHS 5000
|
||||
#define REP 40
|
||||
|
||||
BENCH("Small graph, epochs: " TOSTR(EPOCHS) ", repetitions: " TOSTR(REP), REPEAT(igraph_layout_umap(&graph, &layout, 0, &distances, 0.01, EPOCHS, 0), REP);
|
||||
);
|
||||
|
||||
#undef EPOCHS
|
||||
#undef REP
|
||||
#define EPOCHS 500
|
||||
#define REP 400
|
||||
|
||||
BENCH("Small graph, epochs: " TOSTR(EPOCHS) ", repetitions: " TOSTR(REP), REPEAT(igraph_layout_umap(&graph, &layout, 0, &distances, 0.01, EPOCHS, 0) , REP);
|
||||
);
|
||||
|
||||
#undef EPOCHS
|
||||
#undef REP
|
||||
#define EPOCHS 60
|
||||
#define REP 1
|
||||
#define VCOUNT 10000
|
||||
#define DENS 0.001
|
||||
|
||||
igraph_destroy(&graph);
|
||||
igraph_erdos_renyi_game_gnp(&graph, VCOUNT, DENS, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_resize(&distances, igraph_ecount(&graph));
|
||||
for (igraph_int_t i=0; i < igraph_ecount(&graph); i++) {
|
||||
VECTOR(distances)[i] = RNG_UNIF(0.05, 0.15);
|
||||
}
|
||||
|
||||
BENCH("Larger graph, epochs: " TOSTR(EPOCHS) ", repetitions: " TOSTR(REP), REPEAT(igraph_layout_umap(&graph, &layout, 0, &distances, 0.01, EPOCHS, 0) , REP);
|
||||
);
|
||||
|
||||
|
||||
igraph_matrix_destroy(&layout);
|
||||
igraph_destroy(&graph);
|
||||
igraph_vector_destroy(&distances);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
void bench(int m, int n, int rep) {
|
||||
igraph_matrix_t mat;
|
||||
|
||||
igraph_matrix_init(&mat, m, n);
|
||||
for (igraph_int_t j=0; j < n; j++) {
|
||||
for (igraph_int_t i=0; i < m; i++) {
|
||||
MATRIX(mat, i, j) = RNG_UNIF(-1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
char name[200];
|
||||
sprintf(name, "Transpose %5d x %5d, %dx", m, n, rep);
|
||||
BENCH( name, REPEAT(igraph_matrix_transpose(&mat), rep) );
|
||||
|
||||
igraph_matrix_destroy(&mat);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
BENCH_INIT();
|
||||
|
||||
bench(30, 30, 100000);
|
||||
bench(100, 100, 10000);
|
||||
bench(1000, 1000, 100);
|
||||
bench(1024, 1024, 100); /* naive implementation has bad cache behaviour with power of 2 sizes */
|
||||
bench(1023, 1025, 100); /* non-symmetric */
|
||||
bench(3000, 3000, 10);
|
||||
/* skinny non-symmetric: */
|
||||
bench(100, 10000, 100);
|
||||
bench(10000, 100, 100);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2013-2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_t g;
|
||||
igraph_int_t toremovev[] = {
|
||||
2609, 2098, 14517, 7540, 19560, 8855,
|
||||
5939, 14947, 441, 16976, 19642, 4188,
|
||||
15447, 11837, 2333, 7309, 18539, 14099,
|
||||
14264, 9240
|
||||
};
|
||||
const igraph_vector_int_t toremove =
|
||||
igraph_vector_int_view(toremovev, sizeof(toremovev) / sizeof(toremovev[0]));;
|
||||
igraph_vector_int_list_t res;
|
||||
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_full(&g, 200, IGRAPH_UNDIRECTED, IGRAPH_NO_LOOPS);
|
||||
igraph_delete_edges(&g, igraph_ess_vector(&toremove));
|
||||
|
||||
igraph_vector_int_list_init(&res, 0);
|
||||
|
||||
BENCH(" 1 Maximal cliques of almost complete graph",
|
||||
igraph_maximal_cliques(&g, &res,
|
||||
/* min_size= */ IGRAPH_UNLIMITED, /* max_size= */ IGRAPH_UNLIMITED,
|
||||
/* max_results= */ IGRAPH_UNLIMITED);
|
||||
);
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_vector_int_list_destroy(&res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2025 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
void bench_pointcloud(const char *message, igraph_metric_t metric, igraph_int_t point_count, igraph_int_t dimensions, igraph_int_t neighbors, igraph_real_t cutoff) {
|
||||
igraph_matrix_t points;
|
||||
igraph_t g;
|
||||
char msg[200];
|
||||
const char *metricname;
|
||||
|
||||
igraph_matrix_init(&points, point_count, dimensions);
|
||||
|
||||
for (igraph_int_t point = 0; point < point_count; point++) {
|
||||
for (igraph_int_t dim = 0; dim < dimensions; dim++) {
|
||||
MATRIX(points, point, dim) = RNG_UNIF01();
|
||||
}
|
||||
}
|
||||
|
||||
switch (metric) {
|
||||
case IGRAPH_METRIC_L2: metricname = "L2"; break;
|
||||
case IGRAPH_METRIC_L1: metricname = "L1"; break;
|
||||
}
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%s RKNN with %s, %dD, n=%6" IGRAPH_PRId ", k=%2d, r=%g",
|
||||
message, metricname, (int) dimensions, point_count, (int) neighbors, cutoff);
|
||||
|
||||
BENCH(msg, igraph_nearest_neighbor_graph(&g, &points, metric, neighbors, cutoff, false));
|
||||
|
||||
igraph_destroy(&g);
|
||||
igraph_matrix_destroy(&points);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 20250728);
|
||||
|
||||
bench_pointcloud(" 1", IGRAPH_METRIC_L2, 100000, 1, 10, 0.1);
|
||||
bench_pointcloud(" 2", IGRAPH_METRIC_L2, 100000, 2, 10, 0.1);
|
||||
bench_pointcloud(" 3", IGRAPH_METRIC_L2, 100000, 3, 10, 0.1);
|
||||
bench_pointcloud(" 4", IGRAPH_METRIC_L2, 100000, 4, 10, 0.1);
|
||||
|
||||
bench_pointcloud(" 5", IGRAPH_METRIC_L2, 10000, 1, -1, 0.001);
|
||||
bench_pointcloud(" 6", IGRAPH_METRIC_L2, 10000, 2, -1, 0.01);
|
||||
bench_pointcloud(" 7", IGRAPH_METRIC_L2, 10000, 3, -1, 0.01);
|
||||
bench_pointcloud(" 8", IGRAPH_METRIC_L2, 10000, 4, -1, 0.1);
|
||||
|
||||
bench_pointcloud(" 9", IGRAPH_METRIC_L2, 1000, 1, -1, -1);
|
||||
bench_pointcloud("10", IGRAPH_METRIC_L2, 1000, 2, -1, -1);
|
||||
bench_pointcloud("11", IGRAPH_METRIC_L2, 1000, 3, -1, -1);
|
||||
bench_pointcloud("12", IGRAPH_METRIC_L2, 1000, 4, -1, -1);
|
||||
|
||||
bench_pointcloud("13", IGRAPH_METRIC_L2, 100000, 1, 10, -1);
|
||||
bench_pointcloud("14", IGRAPH_METRIC_L2, 100000, 2, 10, -1);
|
||||
bench_pointcloud("15", IGRAPH_METRIC_L2, 100000, 3, 10, -1);
|
||||
bench_pointcloud("16", IGRAPH_METRIC_L2, 100000, 4, 10, -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,473 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2021-2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
typedef struct igraph_lazy_adjlist2_t {
|
||||
const igraph_t *graph;
|
||||
igraph_int_t length;
|
||||
igraph_int_t data_length;
|
||||
igraph_vector_int_t *adjs;
|
||||
igraph_int_t *data;
|
||||
igraph_int_t next_data;
|
||||
igraph_neimode_t mode;
|
||||
igraph_loops_t loops;
|
||||
igraph_bool_t multiple;
|
||||
} igraph_lazy_adjlist2_t;
|
||||
|
||||
igraph_error_t igraph_lazy_adjlist2_init(const igraph_t *graph,
|
||||
igraph_lazy_adjlist2_t *al,
|
||||
igraph_neimode_t mode,
|
||||
igraph_loops_t loops,
|
||||
igraph_bool_t multiple) {
|
||||
if (mode != IGRAPH_IN && mode != IGRAPH_OUT && mode != IGRAPH_ALL) {
|
||||
IGRAPH_ERROR("Cannor create lazy adjacency list view", IGRAPH_EINVMODE);
|
||||
}
|
||||
|
||||
if (!igraph_is_directed(graph)) {
|
||||
mode = IGRAPH_ALL;
|
||||
}
|
||||
|
||||
al->mode = mode;
|
||||
al->loops = loops;
|
||||
al->multiple = multiple;
|
||||
al->graph = graph;
|
||||
|
||||
al->length = igraph_vcount(graph);
|
||||
al->data_length = igraph_ecount(graph) * 2;
|
||||
al->adjs = IGRAPH_CALLOC(al->length, igraph_vector_int_t);
|
||||
al->data = IGRAPH_CALLOC(al->data_length, igraph_int_t);
|
||||
al->next_data = 0;
|
||||
|
||||
if (al->adjs == NULL || al->data == NULL) {
|
||||
IGRAPH_ERROR("Cannot create lazy adjacency list view", IGRAPH_ENOMEM);
|
||||
}
|
||||
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
void igraph_lazy_adjlist2_destroy(igraph_lazy_adjlist2_t *al) {
|
||||
IGRAPH_FREE(al->adjs);
|
||||
IGRAPH_FREE(al->data);
|
||||
}
|
||||
|
||||
igraph_vector_int_t *igraph_i_lazy_adjlist2_get_real(
|
||||
igraph_lazy_adjlist2_t *al, igraph_int_t pno
|
||||
) {
|
||||
igraph_int_t no = pno;
|
||||
igraph_error_t ret;
|
||||
|
||||
if (al->adjs[no].stor_begin == NULL) {
|
||||
al->adjs[no] = igraph_vector_int_view(al->data + al->next_data, al->data_length - al->next_data);
|
||||
/* igraph_neighbors calls a resize. Since we're handling our own
|
||||
* vectors, we can't have our stor_begin be realloced. A realloc should only
|
||||
* happen when the vector is too small to handle the neighbors, which
|
||||
* should never happen, because the stor_end is set to one past the
|
||||
* end of the latest integer.
|
||||
*/
|
||||
ret = igraph_neighbors(al->graph, &al->adjs[no], no, al->mode, al->loops, al->multiple);
|
||||
if (ret != IGRAPH_SUCCESS) {
|
||||
igraph_error("", IGRAPH_FILE_BASENAME, __LINE__, ret);
|
||||
return NULL;
|
||||
}
|
||||
al->next_data += igraph_vector_int_size(&(al->adjs[no]));
|
||||
}
|
||||
|
||||
return &al->adjs[no];
|
||||
}
|
||||
|
||||
igraph_error_t igraph_neighborhood_adjl2(const igraph_t *graph, igraph_vector_int_list_t *res,
|
||||
igraph_vs_t vids, igraph_int_t order,
|
||||
igraph_neimode_t mode, igraph_int_t mindist) {
|
||||
|
||||
igraph_int_t no_of_nodes = igraph_vcount(graph);
|
||||
igraph_dqueue_int_t q;
|
||||
igraph_vit_t vit;
|
||||
igraph_int_t i, j;
|
||||
igraph_int_t *added;
|
||||
igraph_vector_int_t *neis;
|
||||
igraph_vector_int_t tmp;
|
||||
igraph_lazy_adjlist2_t adjlist2;
|
||||
|
||||
if (order < 0) {
|
||||
IGRAPH_ERROR("Negative order in neighborhood size", IGRAPH_EINVAL);
|
||||
}
|
||||
|
||||
if (mindist < 0 || mindist > order) {
|
||||
IGRAPH_ERROR("Minimum distance should be between zero and order",
|
||||
IGRAPH_EINVAL);
|
||||
}
|
||||
|
||||
added = IGRAPH_CALLOC(no_of_nodes, igraph_int_t);
|
||||
if (added == 0) {
|
||||
IGRAPH_ERROR("Cannot calculate neighborhood size", IGRAPH_ENOMEM);
|
||||
}
|
||||
IGRAPH_FINALLY(igraph_free, added);
|
||||
IGRAPH_DQUEUE_INT_INIT_FINALLY(&q, 100);
|
||||
IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit));
|
||||
IGRAPH_FINALLY(igraph_vit_destroy, &vit);
|
||||
IGRAPH_VECTOR_INT_INIT_FINALLY(&tmp, 0);
|
||||
IGRAPH_CHECK(igraph_vector_int_list_reserve(res, IGRAPH_VIT_SIZE(vit)));
|
||||
igraph_vector_int_list_clear(res);
|
||||
|
||||
if (!igraph_is_directed(graph) || mode == IGRAPH_ALL) {
|
||||
IGRAPH_CHECK(igraph_lazy_adjlist2_init(graph, &adjlist2, mode, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE));
|
||||
} else {
|
||||
IGRAPH_CHECK(igraph_lazy_adjlist2_init(graph, &adjlist2, mode, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE));
|
||||
}
|
||||
IGRAPH_FINALLY(igraph_lazy_adjlist2_destroy, &adjlist2);
|
||||
for (i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) {
|
||||
igraph_int_t node = IGRAPH_VIT_GET(vit);
|
||||
added[node] = i + 1;
|
||||
igraph_vector_int_clear(&tmp);
|
||||
if (mindist == 0) {
|
||||
IGRAPH_CHECK(igraph_vector_int_push_back(&tmp, node));
|
||||
}
|
||||
if (order > 0) {
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, node));
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, 0));
|
||||
}
|
||||
|
||||
while (!igraph_dqueue_int_empty(&q)) {
|
||||
igraph_int_t actnode = igraph_dqueue_int_pop(&q);
|
||||
igraph_int_t actdist = igraph_dqueue_int_pop(&q);
|
||||
igraph_int_t n;
|
||||
neis = igraph_i_lazy_adjlist2_get_real(&adjlist2, actnode);
|
||||
n = igraph_vector_int_size(neis);
|
||||
|
||||
if (actdist < order - 1) {
|
||||
/* we add them to the q */
|
||||
for (j = 0; j < n; j++) {
|
||||
igraph_int_t nei = VECTOR(*neis)[j];
|
||||
if (added[nei] != i + 1) {
|
||||
added[nei] = i + 1;
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, nei));
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, actdist + 1));
|
||||
if (actdist + 1 >= mindist) {
|
||||
IGRAPH_CHECK(igraph_vector_int_push_back(&tmp, nei));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* we just count them but don't add them to q */
|
||||
for (j = 0; j < n; j++) {
|
||||
igraph_int_t nei = VECTOR(*neis)[j];
|
||||
if (added[nei] != i + 1) {
|
||||
added[nei] = i + 1;
|
||||
if (actdist + 1 >= mindist) {
|
||||
IGRAPH_CHECK(igraph_vector_int_push_back(&tmp, nei));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* while q not empty */
|
||||
|
||||
IGRAPH_CHECK(igraph_vector_int_list_push_back_copy(res, &tmp));
|
||||
}
|
||||
|
||||
igraph_lazy_adjlist2_destroy(&adjlist2);
|
||||
igraph_vector_int_destroy(&tmp);
|
||||
igraph_vit_destroy(&vit);
|
||||
igraph_dqueue_int_destroy(&q);
|
||||
IGRAPH_FREE(added);
|
||||
IGRAPH_FINALLY_CLEAN(5);
|
||||
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
igraph_error_t igraph_neighborhood_adjl(const igraph_t *graph, igraph_vector_int_list_t *res,
|
||||
igraph_vs_t vids, igraph_int_t order,
|
||||
igraph_neimode_t mode, igraph_int_t mindist) {
|
||||
|
||||
igraph_int_t no_of_nodes = igraph_vcount(graph);
|
||||
igraph_dqueue_int_t q;
|
||||
igraph_vit_t vit;
|
||||
igraph_int_t i, j;
|
||||
igraph_int_t *added;
|
||||
igraph_vector_int_t *neis;
|
||||
igraph_vector_int_t tmp;
|
||||
igraph_lazy_adjlist_t adjlist;
|
||||
|
||||
if (order < 0) {
|
||||
IGRAPH_ERROR("Negative order in neighborhood size", IGRAPH_EINVAL);
|
||||
}
|
||||
|
||||
if (mindist < 0 || mindist > order) {
|
||||
IGRAPH_ERROR("Minimum distance should be between zero and order",
|
||||
IGRAPH_EINVAL);
|
||||
}
|
||||
|
||||
added = IGRAPH_CALLOC(no_of_nodes, igraph_int_t);
|
||||
if (added == 0) {
|
||||
IGRAPH_ERROR("Cannot calculate neighborhood size", IGRAPH_ENOMEM);
|
||||
}
|
||||
IGRAPH_FINALLY(igraph_free, added);
|
||||
IGRAPH_DQUEUE_INT_INIT_FINALLY(&q, 100);
|
||||
IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit));
|
||||
IGRAPH_FINALLY(igraph_vit_destroy, &vit);
|
||||
IGRAPH_VECTOR_INT_INIT_FINALLY(&tmp, 0);
|
||||
IGRAPH_CHECK(igraph_vector_int_list_reserve(res, IGRAPH_VIT_SIZE(vit)));
|
||||
igraph_vector_int_list_clear(res);
|
||||
|
||||
if (!igraph_is_directed(graph) || mode == IGRAPH_ALL) {
|
||||
IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &adjlist, mode, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE));
|
||||
} else {
|
||||
IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &adjlist, mode, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE));
|
||||
}
|
||||
IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &adjlist);
|
||||
for (i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) {
|
||||
igraph_int_t node = IGRAPH_VIT_GET(vit);
|
||||
added[node] = i + 1;
|
||||
igraph_vector_int_clear(&tmp);
|
||||
if (mindist == 0) {
|
||||
IGRAPH_CHECK(igraph_vector_int_push_back(&tmp, node));
|
||||
}
|
||||
if (order > 0) {
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, node));
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, 0));
|
||||
}
|
||||
|
||||
while (!igraph_dqueue_int_empty(&q)) {
|
||||
igraph_int_t actnode = igraph_dqueue_int_pop(&q);
|
||||
igraph_int_t actdist = igraph_dqueue_int_pop(&q);
|
||||
igraph_int_t n;
|
||||
neis = igraph_lazy_adjlist_get(&adjlist, actnode);
|
||||
n = igraph_vector_int_size(neis);
|
||||
|
||||
if (actdist < order - 1) {
|
||||
/* we add them to the q */
|
||||
for (j = 0; j < n; j++) {
|
||||
igraph_int_t nei = VECTOR(*neis)[j];
|
||||
if (added[nei] != i + 1) {
|
||||
added[nei] = i + 1;
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, nei));
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, actdist + 1));
|
||||
if (actdist + 1 >= mindist) {
|
||||
IGRAPH_CHECK(igraph_vector_int_push_back(&tmp, nei));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* we just count them but don't add them to q */
|
||||
for (j = 0; j < n; j++) {
|
||||
igraph_int_t nei = VECTOR(*neis)[j];
|
||||
if (added[nei] != i + 1) {
|
||||
added[nei] = i + 1;
|
||||
if (actdist + 1 >= mindist) {
|
||||
IGRAPH_CHECK(igraph_vector_int_push_back(&tmp, nei));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* while q not empty */
|
||||
|
||||
IGRAPH_CHECK(igraph_vector_int_list_push_back_copy(res, &tmp));
|
||||
}
|
||||
|
||||
igraph_lazy_adjlist_destroy(&adjlist);
|
||||
igraph_vector_int_destroy(&tmp);
|
||||
igraph_vit_destroy(&vit);
|
||||
igraph_dqueue_int_destroy(&q);
|
||||
IGRAPH_FREE(added);
|
||||
IGRAPH_FINALLY_CLEAN(5);
|
||||
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
igraph_error_t igraph_neighborhood_adj(const igraph_t *graph, igraph_vector_int_list_t *res,
|
||||
igraph_vs_t vids, igraph_int_t order,
|
||||
igraph_neimode_t mode, igraph_int_t mindist) {
|
||||
|
||||
igraph_int_t no_of_nodes = igraph_vcount(graph);
|
||||
igraph_dqueue_int_t q;
|
||||
igraph_vit_t vit;
|
||||
igraph_int_t i, j;
|
||||
igraph_int_t *added;
|
||||
igraph_vector_int_t *neis;
|
||||
igraph_vector_int_t tmp;
|
||||
igraph_adjlist_t adjlist;
|
||||
|
||||
if (order < 0) {
|
||||
IGRAPH_ERROR("Negative order in neighborhood size", IGRAPH_EINVAL);
|
||||
}
|
||||
|
||||
if (mindist < 0 || mindist > order) {
|
||||
IGRAPH_ERROR("Minimum distance should be between zero and order",
|
||||
IGRAPH_EINVAL);
|
||||
}
|
||||
|
||||
added = IGRAPH_CALLOC(no_of_nodes, igraph_int_t);
|
||||
if (added == 0) {
|
||||
IGRAPH_ERROR("Cannot calculate neighborhood size", IGRAPH_ENOMEM);
|
||||
}
|
||||
IGRAPH_FINALLY(igraph_free, added);
|
||||
IGRAPH_DQUEUE_INT_INIT_FINALLY(&q, 100);
|
||||
IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit));
|
||||
IGRAPH_FINALLY(igraph_vit_destroy, &vit);
|
||||
IGRAPH_VECTOR_INT_INIT_FINALLY(&tmp, 0);
|
||||
IGRAPH_CHECK(igraph_vector_int_list_reserve(res, IGRAPH_VIT_SIZE(vit)));
|
||||
igraph_vector_int_list_clear(res);
|
||||
|
||||
if (!igraph_is_directed(graph) || mode == IGRAPH_ALL) {
|
||||
IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, mode, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE));
|
||||
} else {
|
||||
IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, mode, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE));
|
||||
}
|
||||
IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist);
|
||||
for (i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) {
|
||||
igraph_int_t node = IGRAPH_VIT_GET(vit);
|
||||
added[node] = i + 1;
|
||||
igraph_vector_int_clear(&tmp);
|
||||
if (mindist == 0) {
|
||||
IGRAPH_CHECK(igraph_vector_int_push_back(&tmp, node));
|
||||
}
|
||||
if (order > 0) {
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, node));
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, 0));
|
||||
}
|
||||
|
||||
while (!igraph_dqueue_int_empty(&q)) {
|
||||
igraph_int_t actnode = igraph_dqueue_int_pop(&q);
|
||||
igraph_int_t actdist = igraph_dqueue_int_pop(&q);
|
||||
igraph_int_t n;
|
||||
neis = igraph_adjlist_get(&adjlist, actnode);
|
||||
n = igraph_vector_int_size(neis);
|
||||
|
||||
if (actdist < order - 1) {
|
||||
/* we add them to the q */
|
||||
for (j = 0; j < n; j++) {
|
||||
igraph_int_t nei = VECTOR(*neis)[j];
|
||||
if (added[nei] != i + 1) {
|
||||
added[nei] = i + 1;
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, nei));
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, actdist + 1));
|
||||
if (actdist + 1 >= mindist) {
|
||||
IGRAPH_CHECK(igraph_vector_int_push_back(&tmp, nei));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* we just count them but don't add them to q */
|
||||
for (j = 0; j < n; j++) {
|
||||
igraph_int_t nei = VECTOR(*neis)[j];
|
||||
if (added[nei] != i + 1) {
|
||||
added[nei] = i + 1;
|
||||
if (actdist + 1 >= mindist) {
|
||||
IGRAPH_CHECK(igraph_vector_int_push_back(&tmp, nei));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* while q not empty */
|
||||
|
||||
IGRAPH_CHECK(igraph_vector_int_list_push_back_copy(res, &tmp));
|
||||
}
|
||||
|
||||
igraph_adjlist_destroy(&adjlist);
|
||||
igraph_vector_int_destroy(&tmp);
|
||||
igraph_vit_destroy(&vit);
|
||||
igraph_dqueue_int_destroy(&q);
|
||||
IGRAPH_FREE(added);
|
||||
IGRAPH_FINALLY_CLEAN(5);
|
||||
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
void do_benchmark(igraph_t *g, igraph_vs_t vids, igraph_int_t repeat)
|
||||
{
|
||||
igraph_vector_int_list_t result_orig;
|
||||
igraph_vector_int_list_t result_adj;
|
||||
igraph_vector_int_list_t result_adjl;
|
||||
igraph_vector_int_list_t result_adjl2;
|
||||
|
||||
igraph_vector_int_list_init(&result_orig, 0);
|
||||
igraph_vector_int_list_init(&result_adj, 0);
|
||||
igraph_vector_int_list_init(&result_adjl, 0);
|
||||
igraph_vector_int_list_init(&result_adjl2, 0);
|
||||
|
||||
for (igraph_int_t order = 1; order <= 3; order++) {
|
||||
printf("order %" IGRAPH_PRId ":\n", order);
|
||||
BENCH("Original function:",
|
||||
REPEAT(igraph_neighborhood(g, &result_orig, vids, order,
|
||||
/*mode*/ IGRAPH_ALL, /*mindist*/ 0), repeat));
|
||||
|
||||
BENCH("Using a lazy adjlist:",
|
||||
REPEAT(igraph_neighborhood_adjl(g, &result_adjl, vids, order,
|
||||
/*mode*/ IGRAPH_ALL, /*mindist*/ 0), repeat));
|
||||
|
||||
BENCH("Using lazy adjlist 2:",
|
||||
REPEAT(igraph_neighborhood_adjl2(g, &result_adjl2, vids, order,
|
||||
/*mode*/ IGRAPH_ALL, /*mindist*/ 0), repeat));
|
||||
|
||||
BENCH("Using adjlist:",
|
||||
REPEAT(igraph_neighborhood_adj(g, &result_adj, vids, order,
|
||||
/*mode*/ IGRAPH_ALL, /*mindist*/ 0), repeat));
|
||||
for (igraph_int_t i = 0; i <= order; i++) {
|
||||
IGRAPH_ASSERT(!igraph_vector_int_lex_cmp(&VECTOR(result_orig)[i], &VECTOR(result_adj)[i]));
|
||||
IGRAPH_ASSERT(!igraph_vector_int_lex_cmp(&VECTOR(result_adj)[i], &VECTOR(result_adjl)[i]));
|
||||
IGRAPH_ASSERT(!igraph_vector_int_lex_cmp(&VECTOR(result_adjl)[i], &VECTOR(result_adjl2)[i]));
|
||||
}
|
||||
}
|
||||
igraph_vector_int_list_destroy(&result_orig);
|
||||
igraph_vector_int_list_destroy(&result_adj);
|
||||
igraph_vector_int_list_destroy(&result_adjl);
|
||||
igraph_vector_int_list_destroy(&result_adjl2);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_t g_full, g_ring, g_er;
|
||||
igraph_vs_t vids_all, vids_50, vids_5000, vids_200;
|
||||
|
||||
igraph_vs_all(&vids_all);
|
||||
igraph_vs_range(&vids_50, 0, 50);
|
||||
igraph_vs_range(&vids_5000, 0, 5000);
|
||||
igraph_vs_range(&vids_200, 0, 200);
|
||||
|
||||
igraph_full(&g_full, 500, IGRAPH_UNDIRECTED, IGRAPH_NO_LOOPS);
|
||||
igraph_ring(&g_ring, 50000, IGRAPH_UNDIRECTED, /* mutual */ 0, /*circular*/ 0);
|
||||
igraph_erdos_renyi_game_gnm(&g_er, 2000, 20000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
|
||||
printf("Select all vertices:\n\n");
|
||||
printf("Full graph:\n");
|
||||
do_benchmark(&g_full, vids_all, 10);
|
||||
printf("\nRing graph:\n");
|
||||
do_benchmark(&g_ring, vids_all, 40);
|
||||
printf("\nRandom graph:\n");
|
||||
do_benchmark(&g_er, vids_all, 15);
|
||||
|
||||
printf("\n\nSelect 10%% of vertices:\n\n");
|
||||
printf("Full graph:\n");
|
||||
do_benchmark(&g_full, vids_50, 100);
|
||||
printf("\nRing graph:\n");
|
||||
do_benchmark(&g_ring, vids_5000, 400);
|
||||
printf("\nRandom graph:\n");
|
||||
do_benchmark(&g_er, vids_200, 150);
|
||||
|
||||
igraph_destroy(&g_full);
|
||||
igraph_destroy(&g_ring);
|
||||
igraph_destroy(&g_er);
|
||||
igraph_vs_destroy(&vids_all);
|
||||
igraph_vs_destroy(&vids_50);
|
||||
igraph_vs_destroy(&vids_5000);
|
||||
igraph_vs_destroy(&vids_200);
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_t res;
|
||||
igraph_arpack_options_t arpack_opts;
|
||||
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
|
||||
igraph_arpack_options_init(&arpack_opts);
|
||||
|
||||
igraph_vector_init(&res, 0);
|
||||
|
||||
igraph_barabasi_game(&graph, 100000, 1, 4, NULL, 1, 0, IGRAPH_DIRECTED, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
BENCH(" 1 PageRank, Barabasi n=100000 m=4, PRPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 10)
|
||||
);
|
||||
BENCH(" 2 PageRank, Barabasi n=100000 m=4, ARPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 10)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_barabasi_game(&graph, 100000, 1, 10, NULL, 1, 0, IGRAPH_DIRECTED, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
BENCH(" 3 PageRank, Barabasi n=100000 m=10, PRPACK, 5x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 5)
|
||||
);
|
||||
BENCH(" 4 PageRank, Barabasi n=100000 m=10, ARPACK, 5x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 5)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 100, 1000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
BENCH(" 5 PageRank, GNM(100,1000), PRPACK, 1000x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 1000)
|
||||
);
|
||||
BENCH(" 6 PageRank, GNM(100,1000), ARPACK, 1000x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 1000)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 200, 4000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
BENCH(" 7 PageRank, GNM(200,4000), PRPACK, 1000x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 1000)
|
||||
);
|
||||
BENCH(" 8 PageRank, GNM(200,4000), ARPACK, 1000x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 1000)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 10000, 20000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
BENCH(" 9 PageRank, GNM(10000,20000), PRPACK, 100x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 100)
|
||||
);
|
||||
BENCH("10 PageRank, GNM(10000,20000), ARPACK, 100x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 100)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 100000, 100000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
BENCH("11 PageRank, GNM(100000,100000), PRPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 10)
|
||||
);
|
||||
BENCH("12 PageRank, GNM(100000,100000), ARPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 10)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 100000, 500000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
BENCH("13 PageRank, GNM(100000,500000), PRPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 10)
|
||||
);
|
||||
BENCH("14 PageRank, GNM(100000,500000), ARPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 10)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_kautz(&graph, 6, 6);
|
||||
BENCH("13 PageRank, Kautz(6,6), PRPACK, 1x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 1)
|
||||
);
|
||||
BENCH("14 PageRank, Kautz(6,6), ARPACK, 1x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 1)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_de_bruijn(&graph, 7, 7);
|
||||
BENCH("13 PageRank, DeBruijn(7,7), PRPACK, 1x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 1)
|
||||
);
|
||||
BENCH("14 PageRank, DeBruijn(7,7), ARPACK, 1x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 1)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_vector_destroy(&res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
void rand_weight_vec(igraph_vector_t *vec, const igraph_t *graph) {
|
||||
igraph_int_t i, n = igraph_ecount(graph);
|
||||
igraph_vector_resize(vec, n);
|
||||
for (i=0; i < n; ++i) {
|
||||
VECTOR(*vec)[i] = RNG_UNIF(1, 10);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_t res, weights;
|
||||
igraph_arpack_options_t arpack_opts;
|
||||
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
|
||||
igraph_arpack_options_init(&arpack_opts);
|
||||
|
||||
igraph_vector_init(&res, 0);
|
||||
igraph_vector_init(&weights, 0);
|
||||
|
||||
igraph_barabasi_game(&graph, 100000, 1, 4, NULL, 1, 0, IGRAPH_DIRECTED, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weight_vec(&weights, &graph);
|
||||
BENCH(" 1 PageRank weighted, Barabasi n=100000 m=4, PRPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 10)
|
||||
);
|
||||
BENCH(" 2 PageRank weighted, Barabasi n=100000 m=4, ARPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 10)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_barabasi_game(&graph, 100000, 1, 10, NULL, 1, 0, IGRAPH_DIRECTED, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weight_vec(&weights, &graph);
|
||||
BENCH(" 3 PageRank weighted, Barabasi n=100000 m=10, PRPACK, 5x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 5)
|
||||
);
|
||||
BENCH(" 4 PageRank weighted, Barabasi n=100000 m=10, ARPACK, 5x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 5)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 100, 1000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weight_vec(&weights, &graph);
|
||||
BENCH(" 5 PageRank weighted, GNM(100,1000), PRPACK, 1000x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 1000)
|
||||
);
|
||||
BENCH(" 6 PageRank weighted, GNM(100,1000), ARPACK, 1000x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 1000)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 200, 4000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weight_vec(&weights, &graph);
|
||||
BENCH(" 7 PageRank weighted, GNM(200,4000), PRPACK, 1000x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 1000)
|
||||
);
|
||||
BENCH(" 8 PageRank weighted, GNM(200,4000), ARPACK, 1000x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 1000)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 10000, 20000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weight_vec(&weights, &graph);
|
||||
BENCH(" 9 PageRank weighted, GNM(10000,20000), PRPACK, 100x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 100)
|
||||
);
|
||||
BENCH("10 PageRank weighted, GNM(10000,20000), ARPACK, 100x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 100)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 100000, 100000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weight_vec(&weights, &graph);
|
||||
BENCH("11 PageRank weighted, GNM(100000,100000), PRPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 10)
|
||||
);
|
||||
BENCH("12 PageRank weighted, GNM(100000,100000), ARPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 10)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 100000, 500000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weight_vec(&weights, &graph);
|
||||
BENCH("13 PageRank weighted, GNM(100000,500000), PRPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 10)
|
||||
);
|
||||
BENCH("14 PageRank weighted, GNM(100000,500000), ARPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 10)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_kautz(&graph, 6, 6);
|
||||
rand_weight_vec(&weights, &graph);
|
||||
BENCH("13 PageRank weighted, Kautz(6,6), PRPACK, 1x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 1)
|
||||
);
|
||||
BENCH("14 PageRank weighted, Kautz(6,6), ARPACK, 1x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 1)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_de_bruijn(&graph, 7, 7);
|
||||
rand_weight_vec(&weights, &graph);
|
||||
BENCH("13 PageRank weighted, DeBruijn(7,7), PRPACK, 1x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 1)
|
||||
);
|
||||
BENCH("14 PageRank weighted, DeBruijn(7,7), ARPACK, 1x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 1)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_vector_destroy(&weights);
|
||||
igraph_vector_destroy(&res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
#include <plfit_sampling.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
igraph_vector_t data;
|
||||
|
||||
double rpareto(double xmin, double alpha) {
|
||||
/* 1-u is used in the base here because we want to avoid the case of
|
||||
* sampling zero */
|
||||
return pow(1 - RNG_UNIF01(), -1.0 / alpha) * xmin;
|
||||
}
|
||||
|
||||
double rzeta(igraph_int_t xmin, double alpha) {
|
||||
double u, v, t;
|
||||
igraph_int_t x;
|
||||
double alpha_minus_1 = alpha-1;
|
||||
double minus_1_over_alpha_minus_1 = -1.0 / (alpha-1);
|
||||
double b;
|
||||
double one_over_b_minus_1;
|
||||
|
||||
xmin = (igraph_int_t) round(xmin);
|
||||
|
||||
/* Rejection sampling for the win. We use Y=floor(U^{-1/alpha} * xmin) as the
|
||||
* envelope distribution, similarly to Chapter X.6 of Luc Devroye's book
|
||||
* (where xmin is assumed to be 1): http://luc.devroye.org/chapter_ten.pdf
|
||||
*
|
||||
* Some notes that should help me recover what I was doing:
|
||||
*
|
||||
* p_i = 1/zeta(alpha, xmin) * i^-alpha
|
||||
* q_i = (xmin/i)^{alpha-1} - (xmin/(i+1))^{alpha-1}
|
||||
* = (i/xmin)^{1-alpha} - ((i+1)/xmin)^{1-alpha}
|
||||
* = [i^{1-alpha} - (i+1)^{1-alpha}] / xmin^{1-alpha}
|
||||
*
|
||||
* p_i / q_i attains its maximum at xmin=i, so the rejection constant is:
|
||||
*
|
||||
* c = p_xmin / q_xmin
|
||||
*
|
||||
* We have to accept the sample if V <= (p_i / q_i) * (q_xmin / p_xmin) =
|
||||
* (i/xmin)^-alpha * [xmin^{1-alpha} - (xmin+1)^{1-alpha}] / [i^{1-alpha} - (i+1)^{1-alpha}] =
|
||||
* [xmin - xmin^alpha / (xmin+1)^{alpha-1}] / [i - i^alpha / (i+1)^{alpha-1}] =
|
||||
* xmin/i * [1-(xmin/(xmin+1))^{alpha-1}]/[1-(i/(i+1))^{alpha-1}]
|
||||
*
|
||||
* In other words (and substituting i with X, which is the same),
|
||||
*
|
||||
* V * (X/xmin) <= [1 - (1+1/xmin)^{1-alpha}] / [1 - (1+1/i)^{1-alpha}]
|
||||
*
|
||||
* Let b := (1+1/xmin)^{alpha-1} and let T := (1+1/i)^{alpha-1}. Then:
|
||||
*
|
||||
* V * (X/xmin) <= [(b-1)/b] / [(T-1)/T]
|
||||
* V * (X/xmin) * (T-1) / (b-1) <= T / b
|
||||
*
|
||||
* which is the same as in Devroye's book, except for the X/xmin term, and
|
||||
* the definition of b.
|
||||
*/
|
||||
b = pow(1 + 1.0/xmin, alpha_minus_1);
|
||||
one_over_b_minus_1 = 1.0/(b-1);
|
||||
do {
|
||||
do {
|
||||
u = RNG_UNIF01();
|
||||
v = RNG_UNIF01();
|
||||
/* 1-u is used in the base here because we want to avoid the case of
|
||||
* having zero in x */
|
||||
x = (igraph_int_t) floor(pow(1-u, minus_1_over_alpha_minus_1) * xmin);
|
||||
} while (x < xmin);
|
||||
t = pow((x+1.0)/x, alpha_minus_1);
|
||||
} while (v*x*(t-1)*one_over_b_minus_1*b > t*xmin);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
int generate_continuous(double xmin, double alpha, size_t num_samples) {
|
||||
IGRAPH_CHECK(igraph_vector_resize(&data, num_samples));
|
||||
|
||||
for (size_t i = 0; i < num_samples; i++) {
|
||||
VECTOR(data)[i] = rpareto(xmin, alpha);
|
||||
}
|
||||
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
int generate_discrete(double xmin, double alpha, size_t num_samples) {
|
||||
IGRAPH_CHECK(igraph_vector_resize(&data, num_samples));
|
||||
|
||||
for (size_t i = 0; i < num_samples; i++) {
|
||||
VECTOR(data)[i] = rzeta(xmin, alpha);
|
||||
}
|
||||
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
int fit_continuous(double known_xmin) {
|
||||
igraph_plfit_result_t result;
|
||||
IGRAPH_CHECK(igraph_power_law_fit(&data, &result, known_xmin, /* force_continuous = */ 1));
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
int fit_discrete(double known_xmin) {
|
||||
igraph_plfit_result_t result;
|
||||
IGRAPH_CHECK(igraph_power_law_fit(&data, &result, known_xmin, 0));
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
|
||||
igraph_vector_init(&data, 0);
|
||||
|
||||
BENCH_INIT();
|
||||
|
||||
generate_continuous(1, 3, 100000);
|
||||
BENCH(" 1 Continuous, xmin = 1, alpha = 3, samples = 100K, fitting alpha only", fit_continuous(1));
|
||||
|
||||
generate_continuous(1, 3, 200000);
|
||||
BENCH(" 2 Continuous, xmin = 1, alpha = 3, samples = 200K, fitting alpha only", fit_continuous(1));
|
||||
|
||||
generate_continuous(1, 3, 500000);
|
||||
BENCH(" 3 Continuous, xmin = 1, alpha = 3, samples = 500K, fitting alpha only", fit_continuous(1));
|
||||
|
||||
generate_continuous(1, 3, 5000);
|
||||
BENCH(" 4 Continuous, xmin = 1, alpha = 3, samples = 5K, fitting xmin and alpha", fit_continuous(-1));
|
||||
|
||||
generate_continuous(1, 3, 10000);
|
||||
BENCH(" 5 Continuous, xmin = 1, alpha = 3, samples = 10K, fitting xmin and alpha", fit_continuous(-1));
|
||||
|
||||
generate_continuous(1, 3, 15000);
|
||||
BENCH(" 6 Continuous, xmin = 1, alpha = 3, samples = 15K, fitting xmin and alpha", fit_continuous(-1));
|
||||
|
||||
generate_discrete(3, 3, 1000000);
|
||||
BENCH(" 7 Discrete, xmin = 3, alpha = 3, samples = 1M, fitting alpha only", fit_discrete(3));
|
||||
|
||||
generate_discrete(3, 3, 5000000);
|
||||
BENCH(" 8 Discrete, xmin = 3, alpha = 3, samples = 5M, fitting alpha only", fit_discrete(3));
|
||||
|
||||
generate_discrete(3, 3, 10000000);
|
||||
BENCH(" 9 Discrete, xmin = 3, alpha = 3, samples = 10M, fitting alpha only", fit_discrete(3));
|
||||
|
||||
generate_discrete(3, 3, 1000000);
|
||||
BENCH("10 Discrete, xmin = 3, alpha = 3, samples = 1M, fitting xmin and alpha", fit_discrete(-1));
|
||||
|
||||
generate_discrete(3, 3, 5000000);
|
||||
BENCH("11 Discrete, xmin = 3, alpha = 3, samples = 5M, fitting xmin and alpha", fit_discrete(-1));
|
||||
|
||||
generate_discrete(3, 3, 10000000);
|
||||
BENCH("12 Discrete, xmin = 3, alpha = 3, samples = 10M, fitting xmin and alpha", fit_discrete(-1));
|
||||
|
||||
igraph_vector_destroy(&data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
/* This program benchmarks igraph_qsort() indirectly through vector_sort() */
|
||||
|
||||
int main(void) {
|
||||
igraph_vector_int_t vec;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
|
||||
igraph_vector_int_init(&vec, 0);
|
||||
|
||||
#define N 10000000
|
||||
|
||||
igraph_vector_int_resize(&vec, N);
|
||||
for (igraph_int_t i=0; i < N; i++) {
|
||||
VECTOR(vec)[i] = RNG_INTEGER(0, N-1);
|
||||
}
|
||||
BENCH("Sort vector of length " IGRAPH_I_STRINGIFY(N), igraph_vector_int_sort(&vec));
|
||||
|
||||
#undef N
|
||||
#define N 1000000
|
||||
|
||||
igraph_vector_int_resize(&vec, N);
|
||||
for (igraph_int_t i=0; i < N; i++) {
|
||||
VECTOR(vec)[i] = RNG_INTEGER(0, N-1);
|
||||
}
|
||||
BENCH("Sort vector of length " IGRAPH_I_STRINGIFY(N), igraph_vector_int_sort(&vec));
|
||||
|
||||
#undef N
|
||||
#define N 100000
|
||||
|
||||
igraph_vector_int_resize(&vec, N);
|
||||
for (igraph_int_t i=0; i < N; i++) {
|
||||
VECTOR(vec)[i] = RNG_INTEGER(0, N-1);
|
||||
}
|
||||
BENCH("Sort vector of length " IGRAPH_I_STRINGIFY(N), igraph_vector_int_sort(&vec));
|
||||
|
||||
igraph_vector_int_destroy(&vec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
#include "bench.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_int_t vertices;
|
||||
igraph_vector_int_t edges;
|
||||
igraph_vector_t weights;
|
||||
igraph_int_t ec, i;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_vector_int_init(&vertices, 0);
|
||||
igraph_vector_int_init(&edges, 0);
|
||||
igraph_vector_init(&weights, 0);
|
||||
|
||||
/* create a small graph, and a compatible weight vector */
|
||||
igraph_de_bruijn(&graph, 3, 2); /* 9 vertices, 27 edges, average degree: 6 */
|
||||
ec = igraph_ecount(&graph);
|
||||
|
||||
igraph_vector_resize(&weights, ec);
|
||||
for (i = 0; i < ec; ++i) {
|
||||
VECTOR(weights)[i] = igraph_rng_get_unif01(igraph_rng_default());
|
||||
}
|
||||
|
||||
/* Only edges */
|
||||
|
||||
BENCH(" 1 Random edge walk, directed, unweighted, small graph ",
|
||||
igraph_random_walk(&graph, NULL, NULL, &edges, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 2 Random edge walk, directed, weighted, small graph ",
|
||||
igraph_random_walk(&graph, &weights, NULL, &edges, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 3 Random edge walk, undirected, unweighted, small graph ",
|
||||
igraph_random_walk(&graph, NULL, NULL, &edges, 0, IGRAPH_ALL, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 4 Random edge walk, undirected, weighted, small graph ",
|
||||
igraph_random_walk(&graph, &weights, NULL, &edges, 0, IGRAPH_ALL, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
/* Only vertices */
|
||||
|
||||
BENCH(" 5 Random vertex walk, directed, unweighted, small graph ",
|
||||
igraph_random_walk(&graph, NULL, &vertices, NULL, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 6 Random vertex walk, directed, weighted, small graph ",
|
||||
igraph_random_walk(&graph, &weights, &vertices, NULL, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 7 Random vertex walk, undirected, unweighted, small graph ",
|
||||
igraph_random_walk(&graph, NULL, &vertices, NULL, 0, IGRAPH_ALL, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 8 Random vertex walk, undirected, weighted, small graph ",
|
||||
igraph_random_walk(&graph, &weights, &vertices, NULL, 0, IGRAPH_ALL, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
/* Both edges and vertices */
|
||||
|
||||
BENCH(" 9 Random walk, directed, unweighted, small graph ",
|
||||
igraph_random_walk(&graph, NULL, &vertices, &edges, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 10 Random walk, directed, weighted, small graph ",
|
||||
igraph_random_walk(&graph, &weights, &vertices, &edges, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
/* create a big graph, and a compatible weight vector */
|
||||
igraph_de_bruijn(&graph, 8, 5); /* 32768 vertices, 262144 edges, average degree: 16 */
|
||||
ec = igraph_ecount(&graph);
|
||||
|
||||
igraph_vector_resize(&weights, ec);
|
||||
for (i = 0; i < ec; ++i) {
|
||||
VECTOR(weights)[i] = igraph_rng_get_unif01(igraph_rng_default());
|
||||
}
|
||||
|
||||
/* Only edges */
|
||||
|
||||
BENCH(" 11 Random edge walk, directed, unweighted, large graph ",
|
||||
igraph_random_walk(&graph, NULL, NULL, &edges, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 12 Random edge walk, directed, weighted, large graph ",
|
||||
igraph_random_walk(&graph, &weights, NULL, &edges, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 13 Random edge walk, undirected, unweighted, large graph ",
|
||||
igraph_random_walk(&graph, NULL, NULL, &edges, 0, IGRAPH_ALL, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 14 Random edge walk, undirected, weighted, large graph ",
|
||||
igraph_random_walk(&graph, &weights, NULL, &edges, 0, IGRAPH_ALL, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
/* Only vertices */
|
||||
|
||||
BENCH(" 15 Random vertex walk, directed, unweighted, large graph ",
|
||||
igraph_random_walk(&graph, NULL, &vertices, NULL, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 16 Random vertex walk, directed, weighted, large graph ",
|
||||
igraph_random_walk(&graph, &weights, &vertices, NULL, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 17 Random vertex walk, undirected, unweighted, large graph ",
|
||||
igraph_random_walk(&graph, NULL, &vertices, NULL, 0, IGRAPH_ALL, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 18 Random vertex walk, undirected, weighted, large graph ",
|
||||
igraph_random_walk(&graph, &weights, &vertices, NULL, 0, IGRAPH_ALL, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
/* Both edges and vertices */
|
||||
|
||||
BENCH(" 19 Random walk, directed, unweighted, large graph ",
|
||||
igraph_random_walk(&graph, NULL, &vertices, &edges, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 20 Random walk, directed, weighted, large graph ",
|
||||
igraph_random_walk(&graph, &weights, &vertices, &edges, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
/* Only edges */
|
||||
|
||||
BENCH(" 21 Short edge walk, directed, unweighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, NULL, NULL, &edges, 0, IGRAPH_OUT, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
BENCH(" 22 Short edge walk, directed, weighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, &weights, NULL, &edges, 0, IGRAPH_OUT, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
BENCH(" 23 Short edge walk, undirected, unweighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, NULL, NULL, &edges, 0, IGRAPH_ALL, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
BENCH(" 24 Short edge walk, undirected, weighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, &weights, NULL, &edges, 0, IGRAPH_ALL, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
/* Only vertices */
|
||||
|
||||
BENCH(" 25 Short vertex walk, directed, unweighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, NULL, &vertices, NULL, 0, IGRAPH_OUT, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
BENCH(" 26 Short vertex walk, directed, weighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, &weights, &vertices, NULL, 0, IGRAPH_OUT, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
BENCH(" 27 Short vertex walk, undirected, unweighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, NULL, &vertices, NULL, 0, IGRAPH_ALL, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
BENCH(" 28 Short vertex walk, undirected, weighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, &weights, &vertices, NULL, 0, IGRAPH_ALL, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
/* Both edges and vertices */
|
||||
|
||||
BENCH(" 29 Short random walk, directed, unweighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, NULL, &vertices, &edges, 0, IGRAPH_OUT, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
BENCH(" 30 Short random walk, directed, weighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, &weights, &vertices, &edges, 0, IGRAPH_OUT, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_vector_destroy(&weights);
|
||||
igraph_vector_int_destroy(&vertices);
|
||||
igraph_vector_int_destroy(&edges);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2025 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
void bench(const igraph_t *graph, const char *what, int rep) {
|
||||
const igraph_int_t vcount = igraph_vcount(graph);
|
||||
const igraph_int_t ecount = igraph_ecount(graph);
|
||||
igraph_vector_int_t degrees;
|
||||
igraph_t new_graph;
|
||||
|
||||
igraph_vector_int_init(°rees, 0);
|
||||
igraph_degree(graph, °rees, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS);
|
||||
|
||||
char name[200];
|
||||
sprintf(name, "%s, n=%5" IGRAPH_PRId ", m=%5" IGRAPH_PRId ", LARGEST, %dx", what, vcount, ecount, rep);
|
||||
BENCH(name, REPEAT(igraph_realize_degree_sequence(&new_graph, °rees, NULL, IGRAPH_SIMPLE_SW, IGRAPH_REALIZE_DEGSEQ_LARGEST), rep));
|
||||
igraph_destroy(&new_graph);
|
||||
|
||||
sprintf(name, "%s, n=%5" IGRAPH_PRId ", m=%5" IGRAPH_PRId ", SMALLEST, %dx", what, vcount, ecount, rep);
|
||||
BENCH(name, REPEAT(igraph_realize_degree_sequence(&new_graph, °rees, NULL, IGRAPH_SIMPLE_SW, IGRAPH_REALIZE_DEGSEQ_SMALLEST), rep));
|
||||
igraph_destroy(&new_graph);
|
||||
|
||||
sprintf(name, "%s, n=%5" IGRAPH_PRId ", m=%5" IGRAPH_PRId ", INDEX, %dx", what, vcount, ecount, rep);
|
||||
BENCH(name, REPEAT(igraph_realize_degree_sequence(&new_graph, °rees, NULL, IGRAPH_SIMPLE_SW, IGRAPH_REALIZE_DEGSEQ_INDEX), rep));
|
||||
igraph_destroy(&new_graph);
|
||||
|
||||
printf("\n");
|
||||
|
||||
igraph_vector_int_destroy(°rees);
|
||||
}
|
||||
|
||||
void bench_gnm(igraph_int_t n, igraph_int_t m, int rep) {
|
||||
igraph_t graph;
|
||||
igraph_erdos_renyi_game_gnm(&graph, n, m, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
bench(&graph, "G(n,m)", rep);
|
||||
igraph_destroy(&graph);
|
||||
}
|
||||
|
||||
void bench_ba(igraph_int_t n, igraph_int_t m, int rep) {
|
||||
igraph_t graph;
|
||||
igraph_barabasi_game(&graph, n, 1, m, NULL, true, 0, IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
bench(&graph, "BA", rep);
|
||||
igraph_destroy(&graph);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 789);
|
||||
BENCH_INIT();
|
||||
|
||||
bench_gnm(100, 200, 10000);
|
||||
bench_gnm(100, 1000, 10000);
|
||||
|
||||
bench_gnm(10000, 20000, 1);
|
||||
bench_gnm(10000, 100000, 1);
|
||||
|
||||
bench_ba(100, 1, 10000);
|
||||
bench_ba(100, 10, 10000);
|
||||
|
||||
bench_ba(10000, 1, 1);
|
||||
bench_ba(10000, 10, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2025 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
#include "bench.h"
|
||||
|
||||
void bench(const char *name, igraph_t *graph, int rep) {
|
||||
igraph_int_t vcount = igraph_vcount(graph);
|
||||
igraph_int_t ecount = igraph_ecount(graph);
|
||||
igraph_int_t trials = 10*ecount;
|
||||
char msg[200];
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%s, |V|=%6" IGRAPH_PRId ", |E|=%6" IGRAPH_PRId ", %6" IGRAPH_PRId " swaps, %dx",
|
||||
name, vcount, ecount, trials, rep);
|
||||
|
||||
BENCH(msg, REPEAT(igraph_rewire(graph, trials, IGRAPH_SIMPLE_SW, NULL), rep));
|
||||
}
|
||||
|
||||
void bench_er(igraph_int_t n, igraph_int_t m, int rep) {
|
||||
igraph_t graph;
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, n, m, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
|
||||
bench("G(n,m)", &graph, rep);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
}
|
||||
|
||||
void bench_ba(igraph_int_t n, igraph_int_t m, int rep) {
|
||||
igraph_t graph;
|
||||
|
||||
igraph_barabasi_game(&graph, n, 1, m ,NULL, true, 1, IGRAPH_UNDIRECTED, IGRAPH_BARABASI_BAG, NULL);
|
||||
|
||||
bench("BA", &graph, rep);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
bench_er(100, 3000, 100);
|
||||
bench_er(300, 3000, 100);
|
||||
bench_er(1000, 3000, 100);
|
||||
bench_er(3000, 3000, 100);
|
||||
bench_er(10000, 3000, 100);
|
||||
|
||||
printf("\n");
|
||||
bench_er(300, 30000, 10);
|
||||
bench_er(1000, 30000, 10);
|
||||
bench_er(3000, 30000, 10);
|
||||
bench_er(10000, 30000, 10);
|
||||
|
||||
printf("\n");
|
||||
bench_ba(1000, 3, 100);
|
||||
bench_ba(10000, 3, 10);
|
||||
bench_ba(100000, 3, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
void rand_weight_vec(igraph_vector_t *vec, const igraph_t *graph) {
|
||||
igraph_int_t i, n = igraph_ecount(graph);
|
||||
igraph_vector_resize(vec, n);
|
||||
for (i=0; i < n; ++i) {
|
||||
VECTOR(*vec)[i] = RNG_UNIF(1, 10);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_t g;
|
||||
igraph_vector_t strength, weights;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 54);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_vector_init(&strength, 0);
|
||||
igraph_vector_init(&weights, 0);
|
||||
|
||||
/* igraph_strength() uses an optimized, cache friendly code path when given
|
||||
* a vertex selector for which igraph_vs_is_all() returns true (this is
|
||||
* currently igraph_vs_all()). We pass both igraph_vss_all() and
|
||||
* igraph_vss_range(0, igraph_vcount(graph)) as vertex selectors
|
||||
* to compare the performance of the two code paths.
|
||||
*
|
||||
* NOTE: While currently igraph_vs_is_all() does not return true for
|
||||
* a range-type vertex selector, this may change in the future.
|
||||
* An altrenative is to to use igraph_vs_vector(), with the vector
|
||||
* initialized to a range.
|
||||
*/
|
||||
|
||||
#define N 1000
|
||||
#define M 10
|
||||
#define REP 10000
|
||||
|
||||
igraph_barabasi_game(&g, N, 1, M, NULL, true, 0, IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE_MULTIPLE, NULL);
|
||||
rand_weight_vec(&weights, &g);
|
||||
|
||||
BENCH(" 1a igraph_strength(), preferential attachment n=" TOSTR(N) ", m=" TOSTR(M) ", " TOSTR(REP) "x",
|
||||
REPEAT(igraph_strength(&g, &strength, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS, &weights), REP)
|
||||
);
|
||||
BENCH(" 1b igraph_strength(), preferential attachment n=" TOSTR(N) ", m=" TOSTR(M) ", " TOSTR(REP) "x",
|
||||
REPEAT(igraph_strength(&g, &strength, igraph_vss_range(0, igraph_vcount(&g)), IGRAPH_ALL, IGRAPH_LOOPS, &weights), REP)
|
||||
);
|
||||
printf("\n");
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef N
|
||||
#undef M
|
||||
#undef REP
|
||||
|
||||
#define N 10000
|
||||
#define M 10
|
||||
#define REP 1000
|
||||
|
||||
igraph_barabasi_game(&g, N, 1, M, NULL, true, 0, IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE_MULTIPLE, NULL);
|
||||
rand_weight_vec(&weights, &g);
|
||||
|
||||
BENCH(" 2a igraph_strength(), preferential attachment n=" TOSTR(N) ", m=" TOSTR(M) ", " TOSTR(REP) "x",
|
||||
REPEAT(igraph_strength(&g, &strength, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS, &weights), REP)
|
||||
);
|
||||
BENCH(" 2b igraph_strength(), preferential attachment n=" TOSTR(N) ", m=" TOSTR(M) ", " TOSTR(REP) "x",
|
||||
REPEAT(igraph_strength(&g, &strength, igraph_vss_range(0, igraph_vcount(&g)), IGRAPH_ALL, IGRAPH_LOOPS, &weights), REP)
|
||||
);
|
||||
printf("\n");
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef N
|
||||
#undef M
|
||||
#undef REP
|
||||
|
||||
#define N 100000
|
||||
#define M 10
|
||||
#define REP 100
|
||||
|
||||
igraph_barabasi_game(&g, N, 1, M, NULL, true, 0, IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE_MULTIPLE, NULL);
|
||||
rand_weight_vec(&weights, &g);
|
||||
|
||||
BENCH(" 3a igraph_strength(), preferential attachment n=" TOSTR(N) ", m=" TOSTR(M) ", " TOSTR(REP) "x",
|
||||
REPEAT(igraph_strength(&g, &strength, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS, &weights), REP)
|
||||
);
|
||||
BENCH(" 3b igraph_strength(), preferential attachment n=" TOSTR(N) ", m=" TOSTR(M) ", " TOSTR(REP) "x",
|
||||
REPEAT(igraph_strength(&g, &strength, igraph_vss_range(0, igraph_vcount(&g)), IGRAPH_ALL, IGRAPH_LOOPS, &weights), REP)
|
||||
);
|
||||
printf("\n");
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef N
|
||||
#undef M
|
||||
#undef REP
|
||||
|
||||
#define N 100000
|
||||
#define M 100
|
||||
#define REP 10
|
||||
|
||||
igraph_barabasi_game(&g, N, 1, M, NULL, true, 0, IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE_MULTIPLE, NULL);
|
||||
rand_weight_vec(&weights, &g);
|
||||
|
||||
BENCH(" 4a igraph_strength(), preferential attachment n=" TOSTR(N) ", m=" TOSTR(M) ", " TOSTR(REP) "x",
|
||||
REPEAT(igraph_strength(&g, &strength, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS, &weights), REP)
|
||||
);
|
||||
BENCH(" 4b igraph_strength(), preferential attachment n=" TOSTR(N) ", m=" TOSTR(M) ", " TOSTR(REP) "x",
|
||||
REPEAT(igraph_strength(&g, &strength, igraph_vss_range(0, igraph_vcount(&g)), IGRAPH_ALL, IGRAPH_LOOPS, &weights), REP)
|
||||
);
|
||||
printf("\n");
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef N
|
||||
#undef M
|
||||
#undef REP
|
||||
|
||||
igraph_vector_destroy(&weights);
|
||||
igraph_vector_destroy(&strength);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2013-2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_t g;
|
||||
igraph_vector_t trans;
|
||||
igraph_vs_t all_vertices;
|
||||
igraph_real_t avg_trans, global_trans, tri_count;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
BENCH_INIT();
|
||||
|
||||
#define N 6000
|
||||
#define M 2000000
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, N, M, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_init(&trans, igraph_vcount(&g));
|
||||
igraph_vs_range(&all_vertices, 0, igraph_vcount(&g));
|
||||
|
||||
BENCH(" 1 Local transitivity, all vertices method, GNM",
|
||||
igraph_transitivity_local_undirected(&g, &trans, igraph_vss_all(),
|
||||
IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 2 Local transitivity, subset method, GNM",
|
||||
igraph_transitivity_local_undirected(&g, &trans, all_vertices,
|
||||
IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 3 Average local transitivity GNM",
|
||||
igraph_transitivity_avglocal_undirected(&g, &avg_trans, IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 4 Global transitivity GNM",
|
||||
igraph_transitivity_undirected(&g, &global_trans, IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 5 Count triangles per vertex, all vertices method, GNM",
|
||||
igraph_count_adjacent_triangles(&g, &trans, igraph_vss_all());
|
||||
);
|
||||
|
||||
BENCH(" 6 Count triangles per vertex, subset method, GNM",
|
||||
igraph_count_adjacent_triangles(&g, &trans, all_vertices);
|
||||
);
|
||||
|
||||
BENCH(" 7 Count all triangles, GNM",
|
||||
igraph_count_triangles(&g, &tri_count);
|
||||
);
|
||||
|
||||
igraph_vs_destroy(&all_vertices);
|
||||
igraph_destroy(&g);
|
||||
|
||||
printf("\n");
|
||||
|
||||
igraph_barabasi_game(&g, N, /*power=*/ 1, M / N, /*outseq=*/ 0,
|
||||
/*outpref=*/ 0, /*A=*/ 1, IGRAPH_UNDIRECTED,
|
||||
IGRAPH_BARABASI_PSUMTREE, /*start_from=*/ 0);
|
||||
igraph_vector_resize(&trans, igraph_vcount(&g));
|
||||
igraph_vs_range(&all_vertices, 0, igraph_vcount(&g));
|
||||
|
||||
BENCH(" 1 Local transitivity, all vertices method, Barabasi",
|
||||
igraph_transitivity_local_undirected(&g, &trans, igraph_vss_all(),
|
||||
IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 2 Local transitivity, subset method, Barabasi",
|
||||
igraph_transitivity_local_undirected(&g, &trans, all_vertices,
|
||||
IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 3 Average local transitivity, Barabasi",
|
||||
igraph_transitivity_avglocal_undirected(&g, &avg_trans, IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 4 Global transitivity, Barabasi",
|
||||
igraph_transitivity_undirected(&g, &global_trans, IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 5 Count triangles per vertex, all vertices method, Barabasi",
|
||||
igraph_count_adjacent_triangles(&g, &trans, igraph_vss_all());
|
||||
);
|
||||
|
||||
BENCH(" 6 Count triangles per vertex, subset method, Barabasi",
|
||||
igraph_count_adjacent_triangles(&g, &trans, all_vertices);
|
||||
);
|
||||
|
||||
BENCH(" 7 Count all triangles, Barabasi",
|
||||
igraph_count_triangles(&g, &tri_count);
|
||||
);
|
||||
|
||||
igraph_vs_destroy(&all_vertices);
|
||||
igraph_destroy(&g);
|
||||
|
||||
printf("\n");
|
||||
|
||||
#undef N
|
||||
#undef M
|
||||
|
||||
#define N 1000000
|
||||
#define M 10000000
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, N, M, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_init(&trans, igraph_vcount(&g));
|
||||
igraph_vs_range(&all_vertices, 0, igraph_vcount(&g));
|
||||
|
||||
BENCH(" 1 Local transitivity, all vertices method, large GNM",
|
||||
igraph_transitivity_local_undirected(&g, &trans, igraph_vss_all(),
|
||||
IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 2 Local transitivity, subset method, large GNM",
|
||||
igraph_transitivity_local_undirected(&g, &trans, all_vertices,
|
||||
IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 3 Average local transitivity, large GNM",
|
||||
igraph_transitivity_avglocal_undirected(&g, &avg_trans, IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 4 Global transitivity, large GNM",
|
||||
igraph_transitivity_undirected(&g, &global_trans, IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 5 Count triangles per vertex, all vertices method, large GNM",
|
||||
igraph_count_adjacent_triangles(&g, &trans, igraph_vss_all());
|
||||
);
|
||||
|
||||
BENCH(" 6 Count triangles per vertex, subset method, large GNM",
|
||||
igraph_count_adjacent_triangles(&g, &trans, all_vertices);
|
||||
);
|
||||
|
||||
BENCH(" 7 Count all triangles, large GNM",
|
||||
igraph_count_triangles(&g, &tri_count);
|
||||
);
|
||||
|
||||
igraph_vs_destroy(&all_vertices);
|
||||
igraph_destroy(&g);
|
||||
|
||||
printf("\n");
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 500, 2000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_resize(&trans, igraph_vcount(&g));
|
||||
igraph_vs_range(&all_vertices, 0, igraph_vcount(&g));
|
||||
|
||||
#define REPS 1000
|
||||
|
||||
BENCH(" 1 Local transitivity, all vertices method, small GNM",
|
||||
REPEAT(igraph_transitivity_local_undirected(&g, &trans, igraph_vss_all(),
|
||||
IGRAPH_TRANSITIVITY_NAN), REPS);
|
||||
);
|
||||
|
||||
BENCH(" 2 Local transitivity, subset method, small GNM",
|
||||
REPEAT(igraph_transitivity_local_undirected(&g, &trans, all_vertices,
|
||||
IGRAPH_TRANSITIVITY_NAN), REPS);
|
||||
);
|
||||
|
||||
BENCH(" 3 Average local transitivity, small GNM",
|
||||
REPEAT(igraph_transitivity_avglocal_undirected(&g, &avg_trans, IGRAPH_TRANSITIVITY_NAN),
|
||||
REPS);
|
||||
);
|
||||
|
||||
BENCH(" 4 Global transitivity, small GNM",
|
||||
REPEAT(igraph_transitivity_undirected(&g, &global_trans, IGRAPH_TRANSITIVITY_NAN),
|
||||
REPS);
|
||||
);
|
||||
|
||||
BENCH(" 5 Count triangles per vertex, all vertices method, small GNM",
|
||||
REPEAT(igraph_count_adjacent_triangles(&g, &trans, igraph_vss_all()), REPS);
|
||||
);
|
||||
|
||||
BENCH(" 6 Count triangles per vertex, subset method, small GNM",
|
||||
REPEAT(igraph_count_adjacent_triangles(&g, &trans, all_vertices), REPS);
|
||||
);
|
||||
|
||||
BENCH(" 7 Count all triangles, small GNM",
|
||||
REPEAT(igraph_count_triangles(&g, &tri_count), REPS);
|
||||
);
|
||||
|
||||
igraph_vs_destroy(&all_vertices);
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef REPS
|
||||
|
||||
printf("\n");
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 50, 300, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_resize(&trans, igraph_vcount(&g));
|
||||
igraph_vs_range(&all_vertices, 0, igraph_vcount(&g));
|
||||
|
||||
#define REPS 10000
|
||||
|
||||
BENCH(" 1 Local transitivity, all vertices method, tiny GNM",
|
||||
REPEAT(igraph_transitivity_local_undirected(&g, &trans, igraph_vss_all(),
|
||||
IGRAPH_TRANSITIVITY_NAN), REPS);
|
||||
);
|
||||
|
||||
BENCH(" 2 Local transitivity, subset method, tiny GNM",
|
||||
REPEAT(igraph_transitivity_local_undirected(&g, &trans, all_vertices,
|
||||
IGRAPH_TRANSITIVITY_NAN), REPS);
|
||||
);
|
||||
|
||||
BENCH(" 3 Average local transitivity, tiny GNM",
|
||||
REPEAT(igraph_transitivity_avglocal_undirected(&g, &avg_trans, IGRAPH_TRANSITIVITY_NAN),
|
||||
REPS);
|
||||
);
|
||||
|
||||
BENCH(" 4 Global transitivity, tiny GNM",
|
||||
REPEAT(igraph_transitivity_undirected(&g, &global_trans, IGRAPH_TRANSITIVITY_NAN),
|
||||
REPS);
|
||||
);
|
||||
|
||||
BENCH(" 5 Count triangles per vertex, all vertices method, tiny GNM",
|
||||
REPEAT(igraph_count_adjacent_triangles(&g, &trans, igraph_vss_all()), REPS);
|
||||
);
|
||||
|
||||
BENCH(" 6 Count triangles per vertex, subset method, tiny GNM",
|
||||
REPEAT(igraph_count_adjacent_triangles(&g, &trans, all_vertices), REPS);
|
||||
);
|
||||
|
||||
BENCH(" 7 Count all triangles, tiny GNM",
|
||||
REPEAT(igraph_count_triangles(&g, &tri_count), REPS);
|
||||
);
|
||||
|
||||
igraph_vs_destroy(&all_vertices);
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef REPS
|
||||
|
||||
igraph_vector_destroy(&trans);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
void tree_game(igraph_int_t n, igraph_bool_t directed, igraph_random_tree_t method) {
|
||||
igraph_t g;
|
||||
igraph_tree_game(&g, n, directed, method);
|
||||
igraph_destroy(&g);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
#define VCOUNT 100
|
||||
#define REP 100000
|
||||
|
||||
BENCH(" 1 vcount=" TOSTR(VCOUNT) ", Prufer, " TOSTR(REP) "x",
|
||||
REPEAT(tree_game(VCOUNT, IGRAPH_UNDIRECTED, IGRAPH_RANDOM_TREE_PRUFER), REP);
|
||||
);
|
||||
|
||||
BENCH(" 2 vcount=" TOSTR(VCOUNT) ", LERW, " TOSTR(REP) "x",
|
||||
REPEAT(tree_game(VCOUNT, IGRAPH_UNDIRECTED, IGRAPH_RANDOM_TREE_LERW), REP);
|
||||
);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef DENS
|
||||
#undef REP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 1000
|
||||
#define REP 10000
|
||||
|
||||
BENCH(" 1 vcount=" TOSTR(VCOUNT) ", Prufer, " TOSTR(REP) "x",
|
||||
REPEAT(tree_game(VCOUNT, IGRAPH_UNDIRECTED, IGRAPH_RANDOM_TREE_PRUFER), REP);
|
||||
);
|
||||
|
||||
BENCH(" 2 vcount=" TOSTR(VCOUNT) ", LERW, " TOSTR(REP) "x",
|
||||
REPEAT(tree_game(VCOUNT, IGRAPH_UNDIRECTED, IGRAPH_RANDOM_TREE_LERW), REP);
|
||||
);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef DENS
|
||||
#undef REP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 10000
|
||||
#define REP 1000
|
||||
|
||||
BENCH(" 3 vcount=" TOSTR(VCOUNT) ", Prufer, " TOSTR(REP) "x",
|
||||
REPEAT(tree_game(VCOUNT, IGRAPH_UNDIRECTED, IGRAPH_RANDOM_TREE_PRUFER), REP);
|
||||
);
|
||||
|
||||
BENCH(" 4 vcount=" TOSTR(VCOUNT) ", LERW, " TOSTR(REP) "x",
|
||||
REPEAT(tree_game(VCOUNT, IGRAPH_UNDIRECTED, IGRAPH_RANDOM_TREE_LERW), REP);
|
||||
);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef DENS
|
||||
#undef REP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 100000
|
||||
#define REP 100
|
||||
|
||||
BENCH(" 3 vcount=" TOSTR(VCOUNT) ", Prufer, " TOSTR(REP) "x",
|
||||
REPEAT(tree_game(VCOUNT, IGRAPH_UNDIRECTED, IGRAPH_RANDOM_TREE_PRUFER), REP);
|
||||
);
|
||||
|
||||
BENCH(" 4 vcount=" TOSTR(VCOUNT) ", LERW, " TOSTR(REP) "x",
|
||||
REPEAT(tree_game(VCOUNT, IGRAPH_UNDIRECTED, IGRAPH_RANDOM_TREE_LERW), REP);
|
||||
);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef DENS
|
||||
#undef REP
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_t g;
|
||||
igraph_int_t vconn;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 54);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_grg_game(&g, 100, 0.2, /* torus = */ false, /* x = */ NULL, /* y = */ NULL);
|
||||
|
||||
BENCH(" 1 Vertex connectivity of geometric random graph, n=100, r=0.2",
|
||||
igraph_vertex_connectivity(&g, &vconn, /* checks = */ false);
|
||||
);
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_grg_game(&g, 200, 0.141, /* torus = */ false, /* x = */ NULL, /* y = */ NULL);
|
||||
|
||||
BENCH(" 2 Vertex connectivity of geometric random graph, n=200, r=0.141",
|
||||
igraph_vertex_connectivity(&g, &vconn, /* checks = */ false);
|
||||
);
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_grg_game(&g, 400, 0.1, /* torus = */ false, /* x = */ NULL, /* y = */ NULL);
|
||||
|
||||
BENCH(" 3 Vertex connectivity of geometric random graph, n=400, r=0.1",
|
||||
igraph_vertex_connectivity(&g, &vconn, /* checks = */ false);
|
||||
);
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
igraph_vector_int_t membership;
|
||||
igraph_vector_t distances;
|
||||
igraph_vector_t weights;
|
||||
igraph_vector_int_t generators;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_vector_int_init(&membership, 0);
|
||||
igraph_vector_init(&distances, 0);
|
||||
igraph_vector_init(&weights, 0);
|
||||
igraph_vector_int_init(&generators, 0);
|
||||
|
||||
#define VCOUNT 100
|
||||
#define DENS 0.5
|
||||
#define REP 1000
|
||||
|
||||
igraph_erdos_renyi_game_gnp(&g, VCOUNT, DENS, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_int_resize(&membership, igraph_vcount(&g));
|
||||
igraph_vector_resize(&distances, igraph_vcount(&g));
|
||||
igraph_vector_resize(&weights, igraph_ecount(&g));
|
||||
|
||||
for (igraph_int_t i=0; i < igraph_ecount(&g); i++) {
|
||||
VECTOR(weights)[i] = RNG_EXP(1);
|
||||
}
|
||||
|
||||
igraph_random_sample(&generators, 0, igraph_vcount(&g)-1, 20);
|
||||
|
||||
BENCH(" 1 vcount=" TOSTR(VCOUNT) ", p=" TOSTR(DENS) ", Unweighted, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_voronoi(&g, &membership, &distances, &generators, NULL, IGRAPH_OUT, IGRAPH_VORONOI_RANDOM), REP);
|
||||
);
|
||||
BENCH(" 2 vcount=" TOSTR(VCOUNT) ", p=" TOSTR(DENS) ", Dijkstra, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_voronoi(&g, &membership, &distances, &generators, &weights, IGRAPH_OUT, IGRAPH_VORONOI_RANDOM), REP);
|
||||
);
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef DENS
|
||||
#undef REP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 500
|
||||
#define DENS 0.1
|
||||
#define REP 1000
|
||||
|
||||
igraph_erdos_renyi_game_gnp(&g, VCOUNT, DENS, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_int_resize(&membership, igraph_vcount(&g));
|
||||
igraph_vector_resize(&distances, igraph_vcount(&g));
|
||||
igraph_vector_resize(&weights, igraph_ecount(&g));
|
||||
|
||||
for (igraph_int_t i=0; i < igraph_ecount(&g); i++) {
|
||||
VECTOR(weights)[i] = RNG_EXP(1);
|
||||
}
|
||||
|
||||
igraph_random_sample(&generators, 0, igraph_vcount(&g)-1, 20);
|
||||
|
||||
BENCH(" 1 vcount=" TOSTR(VCOUNT) ", p=" TOSTR(DENS) ", Unweighted, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_voronoi(&g, &membership, &distances, &generators, NULL, IGRAPH_OUT, IGRAPH_VORONOI_RANDOM), REP);
|
||||
);
|
||||
BENCH(" 2 vcount=" TOSTR(VCOUNT) ", p=" TOSTR(DENS) ", Dijkstra, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_voronoi(&g, &membership, &distances, &generators, &weights, IGRAPH_OUT, IGRAPH_VORONOI_RANDOM), REP);
|
||||
);
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef DENS
|
||||
#undef REP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 5000
|
||||
#define DENS 0.01
|
||||
#define REP 100
|
||||
|
||||
igraph_erdos_renyi_game_gnp(&g, VCOUNT, DENS, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_int_resize(&membership, igraph_vcount(&g));
|
||||
igraph_vector_resize(&distances, igraph_vcount(&g));
|
||||
igraph_vector_resize(&weights, igraph_ecount(&g));
|
||||
|
||||
for (igraph_int_t i=0; i < igraph_ecount(&g); i++) {
|
||||
VECTOR(weights)[i] = RNG_EXP(1);
|
||||
}
|
||||
|
||||
igraph_random_sample(&generators, 0, igraph_vcount(&g)-1, 20);
|
||||
|
||||
BENCH(" 1 vcount=" TOSTR(VCOUNT) ", p=" TOSTR(DENS) ", Unweighted, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_voronoi(&g, &membership, &distances, &generators, NULL, IGRAPH_OUT, IGRAPH_VORONOI_RANDOM), REP);
|
||||
);
|
||||
BENCH(" 2 vcount=" TOSTR(VCOUNT) ", p=" TOSTR(DENS) ", Dijkstra, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_voronoi(&g, &membership, &distances, &generators, &weights, IGRAPH_OUT, IGRAPH_VORONOI_RANDOM), REP);
|
||||
);
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef DENS
|
||||
#undef REP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 100000
|
||||
#define DENS 0.0001
|
||||
#define REP 1
|
||||
|
||||
igraph_erdos_renyi_game_gnp(&g, VCOUNT, DENS, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_int_resize(&membership, igraph_vcount(&g));
|
||||
igraph_vector_resize(&distances, igraph_vcount(&g));
|
||||
igraph_vector_resize(&weights, igraph_ecount(&g));
|
||||
|
||||
for (igraph_int_t i=0; i < igraph_ecount(&g); i++) {
|
||||
VECTOR(weights)[i] = RNG_EXP(1);
|
||||
}
|
||||
|
||||
igraph_random_sample(&generators, 0, igraph_vcount(&g)-1, 100);
|
||||
|
||||
BENCH(" 1 vcount=" TOSTR(VCOUNT) ", p=" TOSTR(DENS) ", Unweighted, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_voronoi(&g, &membership, &distances, &generators, NULL, IGRAPH_OUT, IGRAPH_VORONOI_RANDOM), REP);
|
||||
);
|
||||
BENCH(" 2 vcount=" TOSTR(VCOUNT) ", p=" TOSTR(DENS) ", Dijkstra, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_voronoi(&g, &membership, &distances, &generators, &weights, IGRAPH_OUT, IGRAPH_VORONOI_RANDOM), REP);
|
||||
);
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef DENS
|
||||
#undef REP
|
||||
|
||||
igraph_vector_int_destroy(&generators);
|
||||
igraph_vector_destroy(&weights);
|
||||
igraph_vector_destroy(&distances);
|
||||
igraph_vector_int_destroy(&membership);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,456 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2013-2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
typedef struct igraph_incadjlist_inter_t {
|
||||
igraph_int_t length;
|
||||
igraph_vector_int_t *incadjs;
|
||||
} igraph_incadjlist_inter_t;
|
||||
|
||||
#define igraph_incadjlist_inter_get(il,no) (&(il)->incadjs[(igraph_int_t)(no)])
|
||||
#define igraph_incadjlist_sep_get_inc(il,no) (&(il)->incs[(igraph_int_t)(no)])
|
||||
#define igraph_incadjlist_sep_get_adj(il,no) (&(il)->adjs[(igraph_int_t)(no)])
|
||||
|
||||
void igraph_incadjlist_inter_destroy(igraph_incadjlist_inter_t *il) {
|
||||
igraph_int_t i;
|
||||
for (i = 0; i < il->length; i++) {
|
||||
/* This works if some igraph_vector_int_t's contain NULL,
|
||||
because igraph_vector_int_destroy can handle this. */
|
||||
igraph_vector_int_destroy(&il->incadjs[i]);
|
||||
}
|
||||
IGRAPH_FREE(il->incadjs);
|
||||
}
|
||||
|
||||
igraph_error_t igraph_incadjlist_inter_init(const igraph_t *graph,
|
||||
igraph_incadjlist_inter_t *il,
|
||||
igraph_neimode_t mode) {
|
||||
igraph_int_t i, j, n;
|
||||
igraph_vector_int_t tmp;
|
||||
|
||||
if (mode != IGRAPH_IN && mode != IGRAPH_OUT && mode != IGRAPH_ALL) {
|
||||
IGRAPH_ERROR("Cannot create incadjlist.", IGRAPH_EINVMODE);
|
||||
}
|
||||
|
||||
igraph_vector_int_init(&tmp, 0);
|
||||
IGRAPH_FINALLY(igraph_vector_int_destroy, &tmp);
|
||||
|
||||
if (!igraph_is_directed(graph)) {
|
||||
mode = IGRAPH_ALL;
|
||||
}
|
||||
|
||||
il->length = igraph_vcount(graph);
|
||||
il->incadjs = IGRAPH_CALLOC(il->length, igraph_vector_int_t);
|
||||
if (il->incadjs == 0) {
|
||||
IGRAPH_ERROR("Cannot create incadjlist.", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */
|
||||
}
|
||||
IGRAPH_FINALLY(igraph_incadjlist_inter_destroy, il);
|
||||
|
||||
for (i = 0; i < il->length; i++) {
|
||||
//IGRAPH_ALLOW_INTERRUPTION();
|
||||
|
||||
IGRAPH_CHECK(igraph_incident(graph, &tmp, i, mode, IGRAPH_LOOPS));
|
||||
|
||||
n = igraph_vector_int_size(&tmp);
|
||||
IGRAPH_CHECK(igraph_vector_int_init(&il->incadjs[i], n * 2));
|
||||
|
||||
for (j = 0; j < n; j++) {
|
||||
VECTOR(il->incadjs[i])[j * 2] = VECTOR(tmp)[j];
|
||||
VECTOR(il->incadjs[i])[j * 2 + 1] =
|
||||
IGRAPH_OTHER(graph, VECTOR(tmp)[j], i);
|
||||
}
|
||||
}
|
||||
|
||||
igraph_vector_int_destroy(&tmp);
|
||||
IGRAPH_FINALLY_CLEAN(2); /* + igraph_incadjlist_inter_destroy */
|
||||
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
typedef struct igraph_incadjlist_sep_t {
|
||||
igraph_int_t length;
|
||||
igraph_vector_int_t *incs;
|
||||
igraph_vector_int_t *adjs;
|
||||
} igraph_incadjlist_sep_t;
|
||||
|
||||
void igraph_incadjlist_sep_destroy(igraph_incadjlist_sep_t *il) {
|
||||
igraph_int_t i;
|
||||
for (i = 0; i < il->length; i++) {
|
||||
/* This works if some igraph_vector_int_t's contain NULL,
|
||||
because igraph_vector_int_destroy can handle this. */
|
||||
igraph_vector_int_destroy(&il->incs[i]);
|
||||
igraph_vector_int_destroy(&il->adjs[i]);
|
||||
}
|
||||
IGRAPH_FREE(il->incs);
|
||||
IGRAPH_FREE(il->adjs);
|
||||
}
|
||||
|
||||
igraph_error_t igraph_incadjlist_sep_init(const igraph_t *graph,
|
||||
igraph_incadjlist_sep_t *il,
|
||||
igraph_neimode_t mode) {
|
||||
igraph_int_t i, j, n;
|
||||
igraph_vector_int_t tmp;
|
||||
|
||||
if (mode != IGRAPH_IN && mode != IGRAPH_OUT && mode != IGRAPH_ALL) {
|
||||
IGRAPH_ERROR("Cannot create incadjlist.", IGRAPH_EINVMODE);
|
||||
}
|
||||
|
||||
igraph_vector_int_init(&tmp, 0);
|
||||
IGRAPH_FINALLY(igraph_vector_int_destroy, &tmp);
|
||||
|
||||
if (!igraph_is_directed(graph)) {
|
||||
mode = IGRAPH_ALL;
|
||||
}
|
||||
|
||||
il->length = igraph_vcount(graph);
|
||||
il->incs = IGRAPH_CALLOC(il->length, igraph_vector_int_t);
|
||||
if (il->incs == 0) {
|
||||
IGRAPH_ERROR("Cannot create incadjlist.", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */
|
||||
}
|
||||
|
||||
il->adjs = IGRAPH_CALLOC(il->length, igraph_vector_int_t);
|
||||
if (il->adjs == 0) {
|
||||
IGRAPH_FREE(il->incs);
|
||||
IGRAPH_ERROR("Cannot create incadjlist.", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */
|
||||
}
|
||||
|
||||
IGRAPH_FINALLY(igraph_incadjlist_sep_destroy, il);
|
||||
|
||||
for (i = 0; i < il->length; i++) {
|
||||
//IGRAPH_ALLOW_INTERRUPTION();
|
||||
|
||||
IGRAPH_CHECK(igraph_incident(graph, &tmp, i, mode, IGRAPH_LOOPS));
|
||||
|
||||
n = igraph_vector_int_size(&tmp);
|
||||
IGRAPH_CHECK(igraph_vector_int_init(&il->incs[i], n));
|
||||
IGRAPH_CHECK(igraph_vector_int_init(&il->adjs[i], n));
|
||||
|
||||
for (j = 0; j < n; j++) {
|
||||
VECTOR(il->incs[i])[j] = VECTOR(tmp)[j];
|
||||
VECTOR(il->adjs[i])[j] =
|
||||
IGRAPH_OTHER(graph, VECTOR(tmp)[j], i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
igraph_vector_int_destroy(&tmp);
|
||||
IGRAPH_FINALLY_CLEAN(2); /* + igraph_incadjlist_sep_destroy */
|
||||
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
/* In the below tests, the 'dummy' variable is used to prevent the compilers
|
||||
* from optimizing away the entire side-effects-free function. We use XOR
|
||||
* instead of e.g. addition in order to prevent triggering undefined behaviour. */
|
||||
|
||||
igraph_int_t test_direct(igraph_t *g)
|
||||
{
|
||||
igraph_int_t dummy = 0;
|
||||
igraph_int_t vcount = igraph_vcount(g);
|
||||
igraph_int_t ecount = igraph_ecount(g);
|
||||
|
||||
igraph_int_t ei = 0;
|
||||
igraph_int_t eo = 0;
|
||||
for (igraph_int_t i = 0; i < vcount; i++) {
|
||||
while (ei < ecount && VECTOR(g->from)[VECTOR(g->oi)[ei]] == i) {
|
||||
igraph_int_t neighbor = VECTOR(g->to)[VECTOR(g->oi)[ei]];
|
||||
dummy ^= neighbor ^ VECTOR(g->oi)[ei];
|
||||
ei++;
|
||||
}
|
||||
while (eo < ecount && VECTOR(g->to)[VECTOR(g->ii)[eo]] == i) {
|
||||
igraph_int_t neighbor = VECTOR(g->from)[VECTOR(g->ii)[eo]];
|
||||
dummy ^= neighbor ^ VECTOR(g->ii)[eo] ;
|
||||
eo++;
|
||||
}
|
||||
}
|
||||
return dummy;
|
||||
}
|
||||
|
||||
igraph_int_t test_adj(igraph_t *g, igraph_adjlist_t *adj)
|
||||
{
|
||||
igraph_int_t dummy = 0;
|
||||
igraph_int_t vcount = igraph_vcount(g);
|
||||
|
||||
for (igraph_int_t i = 0; i < vcount; i++) {
|
||||
igraph_vector_int_t *neis = igraph_adjlist_get(adj, i);
|
||||
igraph_int_t nneis = igraph_vector_int_size(neis);
|
||||
for (int j = 0; j < nneis; j++) {
|
||||
igraph_int_t neighbor = VECTOR(*neis)[j];
|
||||
dummy ^= neighbor;
|
||||
}
|
||||
}
|
||||
return dummy;
|
||||
}
|
||||
|
||||
igraph_int_t test_inc_adj(igraph_t *g, igraph_inclist_t *inc, igraph_adjlist_t *adj)
|
||||
{
|
||||
igraph_int_t dummy = 0;
|
||||
igraph_int_t vcount = igraph_vcount(g);
|
||||
|
||||
for (igraph_int_t i = 0; i < vcount; i++) {
|
||||
igraph_vector_int_t *adjs = igraph_adjlist_get(adj, i);
|
||||
igraph_vector_int_t *incs = igraph_inclist_get(inc, i);
|
||||
igraph_int_t nneis = igraph_vector_int_size(adjs);
|
||||
for (int j = 0; j < nneis; j++) {
|
||||
igraph_int_t edge = VECTOR(*incs)[j];
|
||||
igraph_int_t neighbor = VECTOR(*adjs)[j];
|
||||
dummy ^= neighbor ^ edge;
|
||||
}
|
||||
}
|
||||
return dummy;
|
||||
}
|
||||
|
||||
igraph_int_t test_inc_other(igraph_t *g, igraph_inclist_t *inc)
|
||||
{
|
||||
igraph_int_t dummy = 0;
|
||||
igraph_int_t vcount = igraph_vcount(g);
|
||||
|
||||
for (igraph_int_t i = 0; i < vcount; i++) {
|
||||
igraph_vector_int_t *neis = igraph_inclist_get(inc, i);
|
||||
igraph_int_t nneis = igraph_vector_int_size(neis);
|
||||
for (igraph_int_t j = 0; j < nneis; j++) {
|
||||
igraph_int_t edge = VECTOR(*neis)[j];
|
||||
igraph_int_t neighbor = IGRAPH_OTHER(g, edge, i);
|
||||
dummy ^= neighbor ^ edge;
|
||||
}
|
||||
}
|
||||
return dummy;
|
||||
}
|
||||
|
||||
igraph_int_t test_incadj_sep(igraph_t *g, igraph_incadjlist_sep_t *inc)
|
||||
{
|
||||
igraph_int_t dummy = 0;
|
||||
igraph_int_t vcount = igraph_vcount(g);
|
||||
|
||||
for (igraph_int_t i = 0; i < vcount; i++) {
|
||||
igraph_vector_int_t *incs = igraph_incadjlist_sep_get_inc(inc, i);
|
||||
igraph_vector_int_t *adjs = igraph_incadjlist_sep_get_adj(inc, i);
|
||||
igraph_int_t nneis = igraph_vector_int_size(incs);
|
||||
for (igraph_int_t j = 0; j < nneis; j++) {
|
||||
igraph_int_t edge = VECTOR(*incs)[j];
|
||||
igraph_int_t neighbor = VECTOR(*adjs)[j];
|
||||
dummy ^= neighbor ^ edge;
|
||||
}
|
||||
}
|
||||
return dummy;
|
||||
}
|
||||
|
||||
igraph_int_t test_incadj_inter(igraph_t *g, igraph_incadjlist_inter_t *inc)
|
||||
{
|
||||
igraph_int_t dummy = 0;
|
||||
igraph_int_t vcount = igraph_vcount(g);
|
||||
|
||||
for (igraph_int_t i = 0; i < vcount; i++) {
|
||||
igraph_vector_int_t *ias = igraph_incadjlist_inter_get(inc, i);
|
||||
igraph_int_t nneis = igraph_vector_int_size(ias) / 2;
|
||||
for (igraph_int_t j = 0; j < nneis; j++) {
|
||||
igraph_int_t edge = VECTOR(*ias)[j * 2];
|
||||
igraph_int_t neighbor = VECTOR(*ias)[j * 2 + 1];
|
||||
dummy ^= neighbor ^ edge;
|
||||
}
|
||||
}
|
||||
return dummy;
|
||||
}
|
||||
|
||||
igraph_int_t test_inc_to(igraph_t *g, igraph_inclist_t *inc)
|
||||
{
|
||||
igraph_int_t dummy = 0;
|
||||
igraph_int_t vcount = igraph_vcount(g);
|
||||
|
||||
for (igraph_int_t i = 0; i < vcount; i++) {
|
||||
igraph_vector_int_t *neis = igraph_inclist_get(inc, i);
|
||||
igraph_int_t nneis = igraph_vector_int_size(neis);
|
||||
for (igraph_int_t j = 0; j < nneis; j++) {
|
||||
igraph_int_t edge = VECTOR(*neis)[j];
|
||||
igraph_int_t neighbor = IGRAPH_TO(g, edge);
|
||||
dummy ^= neighbor ^ edge;
|
||||
}
|
||||
}
|
||||
return dummy;
|
||||
}
|
||||
|
||||
igraph_int_t test_inc_nop(igraph_t *g, igraph_inclist_t *inc)
|
||||
{
|
||||
igraph_int_t dummy = 0;
|
||||
igraph_int_t vcount = igraph_vcount(g);
|
||||
|
||||
for (igraph_int_t i = 0; i < vcount; i++) {
|
||||
igraph_vector_int_t *neis = igraph_inclist_get(inc, i);
|
||||
igraph_int_t nneis = igraph_vector_int_size(neis);
|
||||
for (igraph_int_t j = 0; j < nneis; j++) {
|
||||
igraph_int_t edge = VECTOR(*neis)[j];
|
||||
dummy ^= edge;
|
||||
}
|
||||
}
|
||||
return dummy;
|
||||
}
|
||||
|
||||
/* Used to prevent optimizing away the result.
|
||||
* This must be a global variable to prevent "variable set but not used"
|
||||
* warnings from some compilers. */
|
||||
volatile igraph_int_t result;
|
||||
|
||||
void do_benchmarks(char *name, igraph_t *g, int repeat) {
|
||||
igraph_adjlist_t adj;
|
||||
igraph_inclist_t inc;
|
||||
igraph_incadjlist_inter_t incadj_inter;
|
||||
igraph_incadjlist_sep_t incadj_sep;
|
||||
|
||||
/* The init() call is in a REPEAT loop, so we include destroy() as well to avoid a memory leak.
|
||||
* This is representative of real use cases, where init/destroy should always come in pairs. */
|
||||
printf("%s", name);
|
||||
BENCH("1 init/destroy adjlist.",
|
||||
REPEAT(
|
||||
do {
|
||||
igraph_adjlist_init(g, &adj, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE);
|
||||
igraph_adjlist_destroy(&adj);
|
||||
} while (0),
|
||||
repeat);
|
||||
);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("2 init/destroy inclist.",
|
||||
REPEAT(
|
||||
do {
|
||||
igraph_inclist_init(g, &inc, IGRAPH_ALL, IGRAPH_LOOPS_TWICE);
|
||||
igraph_inclist_destroy(&inc);
|
||||
} while (0),
|
||||
repeat);
|
||||
);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("3 init/destroy adjlist, remove loops and multiple (which aren't present).",
|
||||
REPEAT(
|
||||
do {
|
||||
igraph_adjlist_init(g, &adj, IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE);
|
||||
igraph_adjlist_destroy(&adj);
|
||||
} while (0),
|
||||
repeat);
|
||||
);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("4 init/destroy inclist, remove loops (which aren't present).",
|
||||
REPEAT(
|
||||
do {
|
||||
igraph_inclist_init(g, &inc, IGRAPH_ALL, IGRAPH_NO_LOOPS);
|
||||
igraph_inclist_destroy(&inc);
|
||||
} while (0),
|
||||
repeat);
|
||||
);
|
||||
|
||||
/* Initialize adjlist / inclist for the following benchmarks. */
|
||||
igraph_adjlist_init(g, &adj, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE);
|
||||
igraph_inclist_init(g, &inc, IGRAPH_ALL, IGRAPH_LOOPS_TWICE);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("5 go over vertices (multiple times) using adjlist.",
|
||||
REPEAT(result = test_adj(g, &adj), repeat);
|
||||
);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("6 go over vertices (multiple times) using inclist, IGRAPH_OTHER.",
|
||||
REPEAT(result = test_inc_other(g, &inc), repeat);
|
||||
);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("7 go over vertices (multiple times) using inclist, IGRAPH_TO.",
|
||||
REPEAT(result = test_inc_to(g, &inc), repeat);
|
||||
);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("8 go over edges using inclist, don't retrieve vertex.",
|
||||
REPEAT(result = test_inc_nop(g, &inc), repeat);
|
||||
);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("9 go over edges and vertices using adjlist and inclist.",
|
||||
REPEAT(result = test_inc_adj(g, &inc, &adj), repeat);
|
||||
);
|
||||
|
||||
igraph_adjlist_destroy(&adj);
|
||||
igraph_inclist_destroy(&inc);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("10 go over edges and vertices using graph internals directly.",
|
||||
REPEAT(result = test_direct(g), repeat);
|
||||
);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("11 init/destroy interleaved incadjlist.",
|
||||
REPEAT(
|
||||
do {
|
||||
igraph_incadjlist_inter_init(g, &incadj_inter, IGRAPH_ALL);
|
||||
igraph_incadjlist_inter_destroy(&incadj_inter);
|
||||
} while (0),
|
||||
repeat);
|
||||
);
|
||||
|
||||
igraph_incadjlist_inter_init(g, &incadj_inter, IGRAPH_ALL);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("12 go over edges and vertices using interleaved incadjlist.",
|
||||
REPEAT(result = test_incadj_inter(g, &incadj_inter), repeat);
|
||||
);
|
||||
|
||||
igraph_incadjlist_inter_destroy(&incadj_inter);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("13 init/destroy incadjlist with two vectors.",
|
||||
REPEAT(
|
||||
do {
|
||||
igraph_incadjlist_sep_init(g, &incadj_sep, IGRAPH_ALL);
|
||||
igraph_incadjlist_sep_destroy(&incadj_sep);
|
||||
} while (0), repeat);
|
||||
);
|
||||
|
||||
igraph_incadjlist_sep_init(g, &incadj_sep, IGRAPH_ALL);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("14 go over edges and vertices using incadjlist.",
|
||||
REPEAT(result = test_incadj_sep(g, &incadj_sep), repeat);
|
||||
);
|
||||
|
||||
igraph_incadjlist_sep_destroy(&incadj_sep);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
BENCH_INIT();
|
||||
|
||||
printf("Full graph tests:\n");
|
||||
igraph_full(&g, 10000, IGRAPH_UNDIRECTED, IGRAPH_NO_LOOPS);
|
||||
do_benchmarks(" fg - ", &g, 1);
|
||||
igraph_destroy(&g);
|
||||
|
||||
printf("\nRandom graph tests:\n");
|
||||
igraph_erdos_renyi_game_gnm(&g, 10000, 49994999, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
do_benchmarks(" rg - ", &g, 1);
|
||||
igraph_destroy(&g);
|
||||
|
||||
printf("\nSmall graph tests:\n");
|
||||
igraph_full(&g, 1000, IGRAPH_UNDIRECTED, IGRAPH_NO_LOOPS);
|
||||
do_benchmarks(" sg - ", &g, 100);
|
||||
igraph_destroy(&g);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
void rand_vec(igraph_vector_int_t *v, igraph_int_t n, igraph_int_t k) {
|
||||
igraph_vector_int_resize(v, n);
|
||||
for (igraph_int_t i=0; i < n; i++) {
|
||||
VECTOR(*v)[i] = RNG_INTEGER(0, k);
|
||||
}
|
||||
}
|
||||
|
||||
void run_bench(int i, int n, int r) {
|
||||
igraph_vector_int_t a, b;
|
||||
igraph_int_t na = n, nb = r*n;
|
||||
int rep = 300000000 / nb;
|
||||
char msg[255];
|
||||
|
||||
igraph_vector_int_init(&a, na);
|
||||
igraph_vector_int_init(&b, nb);
|
||||
|
||||
rand_vec(&a, na, nb);
|
||||
igraph_vector_int_sort(&a);
|
||||
rand_vec(&b, nb, nb);
|
||||
igraph_vector_int_sort(&b);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%2d n = %5d, r = %3d, %dx", i, n, r, rep);
|
||||
|
||||
/* 'volatile' is needed to prevent the compiler from optimizing
|
||||
* away multiple calls to the function with the same parameters within REPEAT.
|
||||
* This would normally happen due to the use of IGRAPH_FUNCATTR_PURE.
|
||||
* ATTENTION! 'volatile', when used this way, may not prevent this optimization
|
||||
* with future compiler versions. */
|
||||
volatile igraph_int_t res;
|
||||
BENCH(msg, REPEAT(res = igraph_vector_int_intersection_size_sorted(&a, &b), rep));
|
||||
(void) res; /* silence unused-but-set-variable warning */
|
||||
|
||||
igraph_vector_int_destroy(&a);
|
||||
igraph_vector_int_destroy(&b);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int i = 0;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
#define BENCHSET(n) \
|
||||
run_bench(++i, n, 1); \
|
||||
run_bench(++i, n, 3); \
|
||||
run_bench(++i, n, 10); \
|
||||
run_bench(++i, n, 30); \
|
||||
run_bench(++i, n, 100); \
|
||||
printf("\n");
|
||||
|
||||
BENCHSET(1);
|
||||
BENCHSET(3);
|
||||
BENCHSET(10);
|
||||
BENCHSET(30);
|
||||
BENCHSET(100);
|
||||
BENCHSET(300);
|
||||
BENCHSET(1000);
|
||||
BENCHSET(3000);
|
||||
BENCHSET(10000);
|
||||
BENCHSET(30000);
|
||||
BENCHSET(100000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
void match(const igraph_t *graph,
|
||||
const igraph_t patt[], igraph_int_t n,
|
||||
igraph_vector_int_list_t *maps) {
|
||||
|
||||
igraph_vector_int_list_clear(maps);
|
||||
for (igraph_int_t i=0; i < n; i++) {
|
||||
igraph_subisomorphic_lad(&patt[i], graph, NULL, NULL, NULL, maps, false);
|
||||
}
|
||||
}
|
||||
|
||||
#define NP 8
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_t patt[NP];
|
||||
igraph_vector_int_list_t maps;
|
||||
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_vector_int_list_init(&maps, 0);
|
||||
|
||||
for (igraph_int_t i=0; i < NP; i++) {
|
||||
igraph_ring(&patt[i], i+1, IGRAPH_DIRECTED, false, true);
|
||||
}
|
||||
|
||||
igraph_kautz(&graph, 3, 3);
|
||||
BENCH("1 Kautz(3,3) 10x", REPEAT(match(&graph, patt, NP, &maps), 10));
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_kautz(&graph, 3, 4);
|
||||
BENCH("2 Kautz(3,4) 3x", REPEAT(match(&graph, patt, NP, &maps), 3));
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_kautz(&graph, 4, 3);
|
||||
BENCH("3 Kautz(4,3) 1x", REPEAT(match(&graph, patt, NP, &maps), 1));
|
||||
igraph_destroy(&graph);
|
||||
|
||||
for (igraph_int_t i=0; i < NP; i++) {
|
||||
igraph_destroy(&patt[i]);
|
||||
}
|
||||
|
||||
igraph_vector_int_list_destroy(&maps);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2025 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
void run_bench(int n) {
|
||||
igraph_t graph;
|
||||
igraph_matrix_t modmat;
|
||||
int rep;
|
||||
char msg[255];
|
||||
|
||||
rep = 20000 / n;
|
||||
rep = rep*rep;
|
||||
|
||||
igraph_matrix_init(&modmat, n, n);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, n, 10 * n, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"G(n,m), directed, n = %5d, m = %7" IGRAPH_PRId ", %dx", n, igraph_ecount(&graph), rep);
|
||||
BENCH(msg, REPEAT(igraph_modularity_matrix(&graph, NULL, 1.0, &modmat, IGRAPH_DIRECTED), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"G(n,m), undirected, n = %5d, m = %7" IGRAPH_PRId ", %dx", n, igraph_ecount(&graph), rep);
|
||||
BENCH(msg, REPEAT(igraph_modularity_matrix(&graph, NULL, 1.0, &modmat, IGRAPH_UNDIRECTED), rep));
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnp(&graph, n, 0.1, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"G(n,p), directed, n = %5d, m = %7" IGRAPH_PRId ", %dx", n, igraph_ecount(&graph), rep);
|
||||
BENCH(msg, REPEAT(igraph_modularity_matrix(&graph, NULL, 1.0, &modmat, IGRAPH_DIRECTED), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"G(n,p), undirected, n = %5d, m = %7" IGRAPH_PRId ", %dx", n, igraph_ecount(&graph), rep);
|
||||
BENCH(msg, REPEAT(igraph_modularity_matrix(&graph, NULL, 1.0, &modmat, IGRAPH_UNDIRECTED), rep));
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_matrix_destroy(&modmat);
|
||||
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
run_bench(100);
|
||||
run_bench(1000);
|
||||
run_bench(10000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 The igraph development team <igraph@igraph.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
void run_bench(const igraph_t *graph, const igraph_vector_t *weights, int rep, const char *name) {
|
||||
igraph_vector_int_t edges;
|
||||
igraph_int_t vcount = igraph_vcount(graph);
|
||||
igraph_int_t ecount = igraph_ecount(graph);
|
||||
char msg[128];
|
||||
|
||||
igraph_vector_int_init(&edges, vcount - 1);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%s, vcount=%" IGRAPH_PRId ", ecount=%" IGRAPH_PRId ", unweigthed, %dx",
|
||||
name, vcount, ecount, rep);
|
||||
BENCH(msg, REPEAT(igraph_minimum_spanning_tree(graph, &edges, NULL, IGRAPH_MST_UNWEIGHTED), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%s, vcount=%" IGRAPH_PRId ", ecount=%" IGRAPH_PRId ", Prim, %dx",
|
||||
name, vcount, ecount, rep);
|
||||
BENCH(msg, REPEAT(igraph_minimum_spanning_tree(graph, &edges, weights, IGRAPH_MST_UNWEIGHTED), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%s, vcount=%" IGRAPH_PRId ", ecount=%" IGRAPH_PRId ", Kruskal, %dx",
|
||||
name, vcount, ecount, rep);
|
||||
BENCH(msg, REPEAT(igraph_minimum_spanning_tree(graph, &edges, weights, IGRAPH_MST_UNWEIGHTED), rep));
|
||||
|
||||
printf("\n");
|
||||
|
||||
igraph_vector_int_destroy(&edges);
|
||||
}
|
||||
|
||||
void rand_weights(const igraph_t *graph, igraph_vector_t *weights) {
|
||||
igraph_int_t ecount = igraph_ecount(graph);
|
||||
igraph_vector_resize(weights, ecount);
|
||||
for (igraph_int_t i=0; i < ecount; i++) {
|
||||
VECTOR(*weights)[i] = RNG_UNIF01();
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
igraph_vector_t weights;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_vector_init(&weights, 0);
|
||||
|
||||
igraph_barabasi_game(&g, 100, 1, 1, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 50000, "PA");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_barabasi_game(&g, 100, 1, 5, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 10000, "PA");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_barabasi_game(&g, 1000, 1, 5, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 1000, "PA");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_barabasi_game(&g, 10000, 1, 5, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 100, "PA");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_barabasi_game(&g, 100, 1, 50, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 1000, "PA");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_barabasi_game(&g, 1000, 1, 50, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 100, "PA");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_barabasi_game(&g, 10000, 1, 50, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 10, "PA");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_barabasi_game(&g, 1000, 1, 500, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 10, "PA");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_barabasi_game(&g, 10000, 1, 500, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 1, "PA");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 1000, 500, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 60000, "G(n,m)");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 1000, 1000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 30000, "G(n,m)");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 1000, 3000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 10000, "G(n,m)");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 1000, 10000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 3000, "G(n,m)");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 1000, 30000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 1000, "G(n,m)");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 1000, 100000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 300, "G(n,m)");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_full(&g, 100, false, false);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 10000, "K");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_full(&g, 1000, false, false);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 100, "K");
|
||||
igraph_destroy(&g);
|
||||
|
||||
{
|
||||
igraph_t K;
|
||||
igraph_full(&K, 100, false, false);
|
||||
igraph_disjoint_union(&g, &K, &K);
|
||||
igraph_destroy(&K);
|
||||
}
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 10000, "K + K");
|
||||
igraph_destroy(&g);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user