/* call-seq: * IGraph::GenerateRandom.preference_game(nodes,types,type_dist,pref_matrixdirected,loops) -> IGraph * * Generates a graph with vertex types and connection preferences * * This is practically the nongrowing variant of igraph_establishment_game. * A given number of vertices are generated. Every vertex is assigned to a * vertex type according to the given type probabilities. Finally, every * vertex pair is evaluated and an edge is created between them with a * probability depending on the types of the vertices involved. * * nodes: The number of vertices in the graph. * * types: The number of vertex types. * * type_dist: Vector giving the distribution of vertex types. * * pref_matrix: IGraphMatrix giving the connection probabilities for * different vertex types. * * directed: Logical, whether to generate a directed graph. If undirected * graphs are requested, only the lower left triangle of the preference * matrix is considered. * * loops: Logical, whether loop edges are allowed. */ VALUE cIGraph_preference_game(VALUE self, VALUE nodes, VALUE types, VALUE type_dist, VALUE pref_matrix, VALUE directed, VALUE loops) { igraph_t *graph; VALUE new_graph; igraph_vector_t type_distv; igraph_matrix_t *pref_matrixm; int i; new_graph = cIGraph_alloc(cIGraph); Data_Get_Struct(new_graph, igraph_t, graph); Data_Get_Struct(pref_matrix, igraph_matrix_t, pref_matrixm); igraph_vector_init(&type_distv,0); for(i=0; i<RARRAY_LEN(type_dist); i++) { igraph_vector_push_back(&type_distv,NUM2DBL(RARRAY_PTR(type_dist)[i])); } igraph_destroy(graph); igraph_preference_game(graph, NUM2INT(nodes), NUM2INT(types), &type_distv, pref_matrixm, NULL, directed == Qtrue ? 1: 0, loops == Qtrue ? 1 : 0); igraph_vector_destroy(&type_distv); return new_graph; }
int main() { igraph_t g; igraph_vector_t tdist; igraph_matrix_t pmat; igraph_bool_t conn; igraph_vector_bool_t bs; int i, ret; /* Symmetric preference game */ igraph_vector_bool_init(&bs, 0); igraph_vector_init_real(&tdist, 3, 1.0, 1.0, 1.0); igraph_matrix_init(&pmat, 3, 3); for (i=0; i<3; i++) MATRIX(pmat, i, i) = 0.2; /* undirected, no loops */ IGRAPH_CHECK(igraph_preference_game(&g, 1000, 3, &tdist, /*fixed_sizes=*/ 0, &pmat, 0, 0, 0)); if (igraph_vcount(&g) != 1000) return 18; if (igraph_is_directed(&g)) return 2; igraph_is_connected(&g, &conn, IGRAPH_STRONG); if (conn) return 3; igraph_is_loop(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs)) return 4; igraph_is_multiple(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs)) return 5; igraph_destroy(&g); for (i=0; i<2; i++) MATRIX(pmat, i, i+1) = 0.1; /* directed, no loops */ IGRAPH_CHECK(igraph_preference_game(&g, 1000, 3, &tdist, /*fixed_sizes=*/0, &pmat, 0, 1, 0)); if (igraph_vcount(&g) != 1000) return 17; if (!igraph_is_directed(&g)) return 6; igraph_is_loop(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs)) return 7; igraph_is_multiple(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs)) return 8; igraph_destroy(&g); /* undirected, loops */ for (i=0; i<3; i++) MATRIX(pmat, i, i) = 1.0; IGRAPH_CHECK(igraph_preference_game(&g, 100, 3, &tdist, /*fixed_sizes=*/ 0, &pmat, 0, 0, 1)); if (igraph_vcount(&g) != 100) return 16; if (igraph_ecount(&g) < 1395) return 20; if (igraph_is_directed(&g)) return 9; igraph_is_loop(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs) == 0) return 10; igraph_is_multiple(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs)) return 11; igraph_destroy(&g); /* directed, loops */ IGRAPH_CHECK(igraph_preference_game(&g, 100, 3, &tdist, /*fixed_sizes=*/ 0, &pmat, 0, 1, 1)); if (igraph_vcount(&g) != 100) return 15; if (igraph_ecount(&g) < 2700) return 19; if (!igraph_is_directed(&g)) return 12; igraph_is_loop(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs) == 0) return 13; igraph_is_multiple(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs)) return 14; igraph_destroy(&g); /* Asymmetric preference game */ /* directed, no loops */ igraph_matrix_resize(&pmat, 2, 2); MATRIX(pmat, 0, 0) = 1; MATRIX(pmat, 0, 1) = 1; MATRIX(pmat, 1, 0) = 1; MATRIX(pmat, 1, 1) = 1; IGRAPH_CHECK(igraph_asymmetric_preference_game(&g, 100, 2, 0, &pmat, 0, 0, 0)); if (igraph_vcount(&g) != 100) return 21; if (igraph_ecount(&g) != 9900) return 22; if (!igraph_is_directed(&g)) return 23; igraph_is_loop(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs)) return 24; igraph_is_multiple(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs)) return 25; igraph_destroy(&g); /* directed, loops */ igraph_matrix_resize(&pmat, 2, 2); MATRIX(pmat, 0, 0) = 1; MATRIX(pmat, 0, 1) = 1; MATRIX(pmat, 1, 0) = 1; MATRIX(pmat, 1, 1) = 1; IGRAPH_CHECK(igraph_asymmetric_preference_game(&g, 100, 2, 0, &pmat, 0, 0, 1)); if (igraph_vcount(&g) != 100) return 26; if (igraph_ecount(&g) != 10000) return 27; if (!igraph_is_directed(&g)) return 28; igraph_is_loop(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs) != 100) return 29; igraph_is_multiple(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs)) return 30; igraph_destroy(&g); igraph_vector_destroy(&tdist); igraph_matrix_destroy(&pmat); igraph_vector_bool_destroy(&bs); assert(IGRAPH_FINALLY_STACK_EMPTY); return 0; }