int igraph_i_largest_weighted_cliques(const igraph_t *graph, const igraph_vector_t *vertex_weights, igraph_vector_ptr_t *res) { graph_t *g; igraph_integer_t vcount = igraph_vcount(graph); if (vcount == 0) { igraph_vector_ptr_clear(res); return IGRAPH_SUCCESS; } igraph_to_cliquer(graph, &g); IGRAPH_FINALLY(graph_free, g); IGRAPH_CHECK(set_weights(vertex_weights, g)); igraph_vector_ptr_clear(res); igraph_cliquer_opt.user_data = res; igraph_cliquer_opt.user_function = &collect_cliques_callback; IGRAPH_FINALLY(free_clique_list, res); CLIQUER_INTERRUPTABLE(clique_find_all(g, 0, 0, FALSE, &igraph_cliquer_opt)); IGRAPH_FINALLY_CLEAN(1); graph_free(g); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; }
int FindCliques(graph_t *ptrGraph, int iMinWeight, int iMaxWeight, int bOnlyMaximal, int iMaxNumCliques, set_t *ptrCliqueList, int iCliqueListLength) { int iNumCliques; clique_options localopts; /* Set the clique_options. These fields should all be null except * 'clique_list' and 'clique_list_length', which store the list of * cliques and the maximum length of the list of cliques, respectively. */ localopts.time_function = NULL; localopts.reorder_function = NULL; localopts.reorder_map = NULL; localopts.clique_list = ptrCliqueList; localopts.clique_list_length = iCliqueListLength; localopts.user_function = NULL; localopts.user_data = NULL; /* Find all of the maximal (argument 4) cliques in this graph of * minimum size 1 (argument 2) and no maximum size (argument 3). */ iNumCliques = clique_find_all(ptrGraph, iMinWeight, iMaxWeight, bOnlyMaximal, &localopts); return iNumCliques; }
int igraph_i_weighted_cliques(const igraph_t *graph, const igraph_vector_t *vertex_weights, igraph_vector_ptr_t *res, igraph_real_t min_weight, igraph_real_t max_weight, igraph_bool_t maximal) { graph_t *g; igraph_integer_t vcount = igraph_vcount(graph); if (vcount == 0) { igraph_vector_ptr_clear(res); return IGRAPH_SUCCESS; } if (min_weight != (int) min_weight) { IGRAPH_WARNING("Only integer vertex weights are supported; the minimum weight will be truncated to its integer part"); min_weight = (int) min_weight; } if (max_weight != (int) max_weight) { IGRAPH_WARNING("Only integer vertex weights are supported; the maximum weight will be truncated to its integer part"); max_weight = (int) max_weight; } if (min_weight <= 0) min_weight = 1; if (max_weight <= 0) max_weight = 0; if (max_weight > 0 && max_weight < min_weight) IGRAPH_ERROR("max_weight must not be smaller than min_weight", IGRAPH_EINVAL); igraph_to_cliquer(graph, &g); IGRAPH_FINALLY(graph_free, g); IGRAPH_CHECK(set_weights(vertex_weights, g)); igraph_vector_ptr_clear(res); igraph_cliquer_opt.user_data = res; igraph_cliquer_opt.user_function = &collect_cliques_callback; IGRAPH_FINALLY(free_clique_list, res); CLIQUER_INTERRUPTABLE(clique_find_all(g, min_weight, max_weight, maximal, &igraph_cliquer_opt)); IGRAPH_FINALLY_CLEAN(1); graph_free(g); IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; }
void multibinpacking(Home home, int n, int m, int k, const IntVarArgs& y, const IntVarArgs& x, const IntSharedArray& D, const IntSharedArray& B, IntConLevel) { /// Check input sizes if (n*k != D.size() ) throw ArgumentSizeMismatch("Int::multibinpacking"); if (k != B.size() ) throw ArgumentSizeMismatch("Int::multibinpacking"); if (n != x.size() ) throw ArgumentSizeMismatch("Int::multibinpacking"); if (m*k != y.size() ) throw ArgumentSizeMismatch("Int::multibinpacking"); for (int i=B.size(); i--; ) Limits::nonnegative(B[i],"Int::multibinpacking"); if (home.failed()) return; /// Post first each single binpacking constraint /// Capacity constraint for each dimension for ( int j = 0; j < m; ++j ) for ( int l = 0; l < k; ++l ) { IntView yi(y[j*k+l]); GECODE_ME_FAIL(yi.lq(home,B[l])); } /// Post a binpacking constraints for each dimension for ( int l = 0; l < k; ++l ) { ViewArray<OffsetView> yv(home,m); for (int j=m; j--; ) yv[j] = OffsetView(y[j*k+l],0); ViewArray<BinPacking::Item> xs(home,x.size()); for (int i=xs.size(); i--; ) xs[i] = BinPacking::Item(x[i],D[i*k+l]); Support::quicksort(&xs[0], xs.size()); GECODE_ES_FAIL(Int::BinPacking::Pack::post(home,yv,xs)); } /// Clique Finding and Alldifferent posting { /// Firt construct the conflict graph graph_t* g = graph_new(n); for ( int a = 0; a < n-1; ++a ) { for ( int b = a+1; b < n; ++b ) { int v = a; /// The variable with smaller domain int w = b; unsigned int nl = 0; if ( x[a].size() > x[b].size() ) { v = b; w = a; } IntVarValues i(x[v]); IntVarValues j(x[w]); while ( i() ) { if ( i.val() != j.val() ) { if ( i.val() < j.val() ) break; else ++i; } else { for ( int l = 0; l < k; ++l ) if ( D[a*k+l] + D[b*k+l] > B[l] ) { nl++; break; } ++i; ++j; } } if ( nl >= x[v].size() ) GRAPH_ADD_EDGE(g,a,b); } } /// Consitency cheking: look for the maximum clique clique_options* opts; opts = (clique_options*) malloc (sizeof(clique_options)); opts->time_function=NULL; opts->reorder_function=reorder_by_default; opts->reorder_map=NULL; opts->user_function=NULL; opts->user_data=NULL; opts->clique_list=NULL; opts->clique_list_length=0; set_t s; s = clique_find_single ( g, 0, 0, TRUE, opts); if ( s != NULL ) { if ( set_size(s) > m ) { set_free(s); free(opts); graph_free(g); GECODE_ES_FAIL(ES_FAILED); } if ( true ) { //option == 1 ) { FIXING for ( int a = 0, j = 0; a < n; ++a ) { if ( SET_CONTAINS_FAST(s,a) ) { assert( x[a].in(j) ); IntView xi(x[a]); GECODE_ME_FAIL(xi.eq(home,j++)); } } } } if ( s!=NULL ) set_free(s); /// List every maximal clique in the conflict graph opts->user_function=record_clique_func; clique_find_all ( g, 2, 0, TRUE, opts); for ( int c = 0; c < clique_count; c++ ) { ViewArray<IntView> xv(home, set_size(clique_list[c])); for ( int a = 0, idx = 0; a < n; ++a ) if ( SET_CONTAINS_FAST(clique_list[c],a) ) xv[idx++] = x[a]; GECODE_ES_FAIL(Distinct::Dom<IntView>::post(home,xv)); set_free(clique_list[c]); } free(opts); graph_free(g); } }