void grasp_build_candidate_list( Grasp *grasp ) { float minEval; float maxEval; minEval = 9999999.0; maxEval = -9999999.0; { int i; for ( i=0 ; (i<grasp->nNodesLeft) ; ++i ) { const int node = grasp->nodesLeft[i]; /* node must have conflict with all nodes inserted */ int j=0; for ( ; (j<grasp->cliqueSize) ; ++j ) { const int nodeClique = grasp->clique[j]; if ( !(cgraph_conflicting_nodes( grasp->cgraph, node, nodeClique )) ) break; } if ( j < grasp->cliqueSize ) continue; const float degree = cgraph_degree( grasp->cgraph, node ); const float evalDegree = 1.0 - ( (grasp->maxDegree - degree) / (grasp->difDegree+1.0) ); const float evalWeight = 1.0 - (((double)frac_part_weight(grasp->w[node])) / (500.0)) ; const float eval = evalDegree + evalWeight; grasp->evalNodesLeft[ i ] = eval; if ( eval < minEval ) minEval = eval; if ( eval > maxEval ) maxEval = eval; } } const float diffEval = maxEval - minEval; const float filterEval = minEval + ( ( 1.0 - grasp->alpha ) * diffEval ) - 1e-5; grasp->nCandidates = 0; { int i; for ( i=0 ; (i<grasp->nNodesLeft) ; ++i ) if ( grasp->evalNodesLeft[ i ] >= filterEval) grasp->candidates[ grasp->nCandidates++ ] = grasp->nodesLeft[i]; } }
int clqe_get_best_candidates_clique_insertion( CliqueExtender *clqe, const IntSet *clique, const CliqueExtendingMethod clqem ) { /* node with the smallest degree */ int nodeSD = -1, degree = INT_MAX, i; const int cliqueSize = vint_set_size( clique ), *cliqueEl = vint_set_get_elements( clique ); const CGraph *cgraph = clqe->cgraph; /* picking node with the smallest degree */ for ( i=0 ; (i<cliqueSize) ; ++i ) { if ( cgraph_degree( cgraph, cliqueEl[i] ) < degree ) { degree = cgraph_degree( cgraph, cliqueEl[i] ); nodeSD = cliqueEl[i]; } } int nCandidates = 0; int *candidates = clqe->candidates; assert(clqem == CLQEM_PRIORITY_GREEDY || clqem == CLQEM_RANDOM); if(clqem == CLQEM_PRIORITY_GREEDY) //clique extender method uses greedy selection (reduced cost) { const int *costs = clqe->costs; #ifdef DEBUG assert( costs ); int previousCost = INT_MIN; #endif NeighIterator *nit = clqe->nit; int selected = -1; nit_start( nit, cgraph, nodeSD, costs ); while ( ( (selected=nit_next(nit))!=INT_MAX ) && (nCandidates<clqe->maxClqESize) ) { #ifdef DEBUG int curCost = costs[selected]; assert( curCost>=previousCost ); previousCost = curCost; #endif /* need to have conflict with all nodes in clique an all others inserted */ for ( i=0 ; (i<cliqueSize) ; ++i ) if ( (!cgraph_conflicting_nodes( cgraph, cliqueEl[i], selected )) || (selected==cliqueEl[i]) ) break; if (i<cliqueSize) continue; for ( i=0 ; (i<nCandidates) ; ++i ) if (!cgraph_conflicting_nodes( cgraph, candidates[i], selected )) break; if (i<nCandidates) continue; candidates[nCandidates++] = selected; } } else //clique extender method uses random selection { int *neighs = xmalloc(sizeof(int) * cgraph_size(cgraph) * 2); int nConflicts = cgraph_get_all_conflicting( cgraph, nodeSD, neighs, cgraph_size(cgraph) * 2); int j, selected; if(nConflicts < clqe->maxClqESize) { for(i = 0; i < nConflicts; i++) { selected = neighs[i]; for(j = 0; j < cliqueSize; j++) if((!cgraph_conflicting_nodes(cgraph, cliqueEl[j], selected)) || (selected == cliqueEl[j])) break; if(j < cliqueSize) continue; for(j = 0; j < nCandidates; j++) if(!cgraph_conflicting_nodes(cgraph, candidates[j], selected)) break; if(j < nCandidates) continue; candidates[nCandidates++] = selected; } } else { int r, remaining = nConflicts; char *isSelected = xmalloc(sizeof(char) * nConflicts); memset(isSelected, 0, sizeof(char) * nConflicts); while(nCandidates < clqe->maxClqESize && remaining > 0) { do { r = rand() % nConflicts; selected = neighs[r]; } while(isSelected[r]); isSelected[r] = 1; remaining--; for(j = 0; j < cliqueSize; j++) if((!cgraph_conflicting_nodes(cgraph, cliqueEl[j], selected)) || (selected == cliqueEl[j])) break; if(j < cliqueSize) continue; for(j = 0; j < nCandidates; j++) if(!cgraph_conflicting_nodes(cgraph, candidates[j], selected)) break; if(j < nCandidates) continue; candidates[nCandidates++] = selected; } free(isSelected); } free(neighs); } return nCandidates; }
int clqe_extend( CliqueExtender *clqe, const CGraph *cgraph, const IntSet *clique, const int weight, const CliqueExtendingMethod clqem ) { int result = 0; #ifdef DEBUG assert( (clqe) && (cgraph) && (clique) && ((vint_set_size(clique))) ); int en1, en2; if (!clq_validate( cgraph, vint_set_size(clique), vint_set_get_elements(clique), &en1, &en2 )) { fprintf( stderr, "ERROR clqe_extend : Nodes %d and %d are not in conflict.\n", en1, en2 ); exit( EXIT_FAILURE ); } #endif clqe->cgraph = cgraph; clqe_check_nodes_cap( clqe ); int nCandidates = clqe_get_best_candidates_clique_insertion( clqe, clique, clqem ); if (!nCandidates) goto TERMINATE; /* too many candidates, filtering */ if (nCandidates > (clqe->maxClqESize*2)) nCandidates = (clqe->maxClqESize*2); /* clique can be extended, starting to fill new clique */ memcpy( clqe->newClique, vint_set_get_elements( clique ), sizeof(int)*vint_set_size(clique) ); clqe->newCliqueSize = vint_set_size( clique ); int idxSelected = -1, selectedNode, i, removals; int *candidates = clqe->candidates; INSERT_CANDIDATE: if ( ( clqem == CLQEM_RANDOM ) || (clqe->costs == NULL) || (clqe->costsCap<cgraph_size(cgraph)) ) { idxSelected = ((int)((((double)rand()) / (((double)RAND_MAX)+1.0)) * ((double)nCandidates))); if ( clqem == CLQEM_PRIORITY_GREEDY ) fprintf( stderr, "Warning: using random selection for extension since no costs were informed.\n"); } else { /* costs informed, picking the one with the lowest cost */ int i, lowestCost = INT_MAX; for ( i=0 ; (i<nCandidates) ; ++i ) { if ( clqe->costs[ candidates[i] ] < lowestCost ) { lowestCost = clqe->costs[ candidates[i] ]; idxSelected = i; } } } #ifdef DEBUG assert( idxSelected >= 0 ); assert( idxSelected < nCandidates ); #endif selectedNode = candidates[ idxSelected ]; assert( selectedNode>=0 && selectedNode < cgraph_size(cgraph) ); clqe->newClique[ clqe->newCliqueSize++ ] = selectedNode; /* removing from candidates those which do not conflict with new inserted node */ removals = 0; for ( i=0 ; (i<nCandidates); ++i ) { if ( ( !cgraph_conflicting_nodes(cgraph, selectedNode, candidates[i] ) ) || (candidates[i]==selectedNode) ) { candidates[i] = INT_MAX; ++removals; } } qsort( candidates, nCandidates, sizeof(int), vint_set_cmp_int ); nCandidates -= removals; if ( ( nCandidates ) && (clqe->newCliqueSize<clqe->maxClqESize) ) goto INSERT_CANDIDATE; /* at this point we have an extended clique */ result += clq_set_add( clqe->clqSet, clqe->newCliqueSize, clqe->newClique, weight ); TERMINATE: /* { int n1, n2; int res = clq_validate( cgraph, clqe->newCliqueSize, clqe->newClique, &n1, &n2 ); assert(res); int i; printf("CLIQUE BEF ADD SIZE:\n"); for ( i=0 ; (i<clqe->newCliqueSize) ; ++i ) printf( "%d ", clqe->newClique[i] ); int sizeS = clq_set_clique_size( clqe->clqSet, clq_set_number_of_cliques(clqe->clqSet)-1 ); const int *el = clq_set_clique_elements( clqe->clqSet, clq_set_number_of_cliques(clqe->clqSet)-1 ); printf("\n-> -> CLIQUE BEF ADD SIZE: <- <-\n"); for ( i=0 ; (i<sizeS) ; ++i ) printf( "%d ", el[i] ); printf("\n"); } */ return result; }