예제 #1
0
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];
   }
}
예제 #2
0
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;
}
예제 #3
0
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;
}