/* Internal function for calculating cliques or independent vertex sets. * They are practically the same except that the complementer of the graph * should be used in the latter case. */ int igraph_i_cliques(const igraph_t *graph, igraph_vector_ptr_t *res, igraph_integer_t min_size, igraph_integer_t max_size, igraph_bool_t independent_vertices) { igraph_integer_t no_of_nodes; igraph_vector_t neis; igraph_real_t *member_storage=0, *new_member_storage, *c1; long int i, j, k, clique_count, old_clique_count; if (igraph_is_directed(graph)) IGRAPH_WARNING("directionality of edges is ignored for directed graphs"); no_of_nodes = igraph_vcount(graph); if (min_size < 0) { min_size = 0; } if (max_size > no_of_nodes || max_size <= 0) { max_size = no_of_nodes; } igraph_vector_ptr_clear(res); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_FINALLY(igraph_i_cliques_free_res, res); /* Will be resized later, if needed. */ member_storage=igraph_Calloc(1, igraph_real_t); if (member_storage==0) { IGRAPH_ERROR("cliques failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, member_storage); /* Find all 1-cliques: every vertex will be a clique */ new_member_storage=igraph_Calloc(no_of_nodes, igraph_real_t); if (new_member_storage==0) { IGRAPH_ERROR("cliques failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, new_member_storage); for (i=0; i<no_of_nodes; i++) { new_member_storage[i] = i; } clique_count = no_of_nodes; old_clique_count = 0; /* Add size 1 cliques if requested */ if (min_size <= 1) { IGRAPH_CHECK(igraph_vector_ptr_resize(res, no_of_nodes)); igraph_vector_ptr_null(res); for (i=0; i<no_of_nodes; i++) { igraph_vector_t *p=igraph_Calloc(1, igraph_vector_t); if (p==0) { IGRAPH_ERROR("cliques failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, p); IGRAPH_CHECK(igraph_vector_init(p, 1)); VECTOR(*p)[0]=i; VECTOR(*res)[i]=p; IGRAPH_FINALLY_CLEAN(1); } } for (i=2; i<=max_size && clique_count > 1; i++) { /* Here new_member_storage contains the cliques found in the previous iteration. Save this into member_storage, might be needed later */ c1=member_storage; member_storage=new_member_storage; new_member_storage=c1; old_clique_count=clique_count; IGRAPH_ALLOW_INTERRUPTION(); /* Calculate the cliques */ IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_i_find_k_cliques(graph, i, member_storage, &new_member_storage, old_clique_count, &clique_count, &neis, independent_vertices)); IGRAPH_FINALLY(igraph_free, member_storage); IGRAPH_FINALLY(igraph_free, new_member_storage); /* Add the cliques just found to the result if requested */ if (i>=min_size && i<=max_size) { for (j=0, k=0; j<clique_count; j++, k+=i) { igraph_vector_t *p=igraph_Calloc(1, igraph_vector_t); if (p==0) { IGRAPH_ERROR("cliques failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, p); IGRAPH_CHECK(igraph_vector_init_copy(p, &new_member_storage[k], i)); IGRAPH_FINALLY(igraph_vector_destroy, p); IGRAPH_CHECK(igraph_vector_ptr_push_back(res, p)); IGRAPH_FINALLY_CLEAN(2); } } } /* i <= max_size && clique_count != 0 */ igraph_free(member_storage); igraph_free(new_member_storage); igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(4); /* 3 here, +1 is igraph_i_cliques_free_res */ return 0; }
QList<int> MWBM::run(QList<int> input_weights, int numberOfLeft, int numberOfRight, bool &isMatched) { igraph_t graph; igraph_vector_bool_t types; igraph_vector_long_t matching; igraph_vector_t weights; igraph_integer_t matching_size; igraph_real_t matching_weight; igraph_bool_t is_matching; igraph_vector_t v; int i; QList<int> out; igraph_real_t weight_array[input_weights.size()]; for(int j=0;j<input_weights.size();j++) { weight_array[j] = input_weights.at(j); }; QList<int> edges_list; for(int j=0;j<numberOfLeft;j++) { for(int k=numberOfLeft;k<numberOfRight+numberOfLeft;k++) { edges_list.append(j); edges_list.append(k); } } igraph_real_t edges[edges_list.size()]; for(int j=0;j<edges_list.size();j++) { edges[j] = edges_list.at(j); } igraph_vector_view(&v, edges, sizeof(edges)/sizeof(double)); igraph_create(&graph, &v, 0, IGRAPH_DIRECTED); igraph_vector_bool_init(&types, numberOfLeft+numberOfRight); for (i = 0; i < numberOfLeft+numberOfRight; i++) VECTOR(types)[i] = (i >= numberOfLeft); igraph_vector_long_init(&matching, 0); igraph_vector_init_copy(&weights, weight_array, sizeof(weight_array) / sizeof(weight_array[0])); igraph_maximum_bipartite_matching(&graph, &types, &matching_size, &matching_weight, &matching, &weights,DBL_EPSILON); igraph_is_maximal_matching(&graph, &types, &matching, &is_matching); if (!is_matching) { isMatched = false; } else { isMatched=true; } for(int j=0;j<numberOfLeft*2;j++) out.append(VECTOR(matching)[j]); igraph_vector_destroy(&weights); igraph_vector_long_destroy(&matching); igraph_vector_bool_destroy(&types); igraph_destroy(&graph); return out; }