Exemplo n.º 1
0
// Will return '_undef_' if 'cost_limit' is exceeded.
//
Formula buildConstraint(const Linear& c, int max_cost)
{
    vec<Formula>    ps;
    vec<Int>        Cs;

    for (int j = 0; j < c.size; j++)
        ps.push(lit2fml(c[j])),
        Cs.push(c(j));

    vec<Int> dummy;
    int      cost;
    vec<int> base;
    optimizeBase(Cs, dummy, cost, base);
    FEnv::push();

    Formula ret;
    try {
        ret = buildConstraint(ps, Cs, base, c.lo, c.hi, max_cost);
    }catch (Exception_TooBig){
        FEnv::pop();
        return _undef_;
    }

    if (opt_verbosity >= 1){
        reportf("Sorter-cost:%5d     ", FEnv::topSize());
        reportf("Base:"); for (int i = 0; i < base.size(); i++) reportf(" %d", base[i]); reportf("\n");
    }
    FEnv::keep();
    return ret;
}
Exemplo n.º 2
0
/**
 * Probably one of the more interesting functions.
 */
SearchMetaData* searchForBase(vec<Int>& inCoeffs, vec<int>& outputBase,PrimesLoader& pl, PBOptions* options) {
  std::map<unsigned int,unsigned int> multiSet;
  vecToMultiSet(inCoeffs,multiSet);
  unsigned int weights[multiSet.size()][2];
  coeffsToDescendingWeights(multiSet, weights);
  SearchMetaData* data = 0;
  unsigned int cutof = pl.loadPrimes(weights[0][0],options->opt_max_generator);
  std::vector<unsigned int>& pri = pl.primeVector();
  if      (options->opt_base == base_Forward) data = findBaseFWD(weights, multiSet.size(), pri,cutof);
  else if (options->opt_base == base_SOD)     data = bnb_SOD_Carry_Cost_search(weights, multiSet.size(),pri,cutof,false,true,true);
  else if (options->opt_base == base_Carry)   data = bnb_SOD_Carry_Cost_search(weights, multiSet.size(), pri,cutof,options->opt_non_prime,options->opt_abstract);
  else if (options->opt_base == base_Comp)    data = bnb_Comp_Cost_search(weights, multiSet.size(), pri,cutof,options->opt_non_prime,options->opt_abstract);
  else if (options->opt_base == base_oddEven)    data = bnb_oddEven_Cost_search(weights, multiSet.size(), pri,cutof,options->opt_non_prime,options->opt_abstract);
  else if (options->opt_base == base_Rel)     data = bnb_Relative_search(weights, multiSet.size() , pri,cutof,options->opt_non_prime,options->opt_abstract);
  else if (options->opt_base == base_Bin) {
  		data =  new SearchMetaData(lg2(weights[0][0]),cutof,weights[0][0],multiSet.size(),"BinaryBase");
  		data->finalize(0);
  }    
  else if (options->opt_base == base_M) {
  	vec<Int> dummy;
    int      cost;
  	data = optimizeBase(inCoeffs, dummy, cost, outputBase,weights,multiSet.size(), cutof);
  }
  else printf("Unknown option!"), exit(-1);  
  data->inputCountCost = inputCountEval(weights,data->base,multiSet.size());
  data->carryOnlyCost  = carryOnlyEval(weights,data->base,multiSet.size());
  data->compCost       = compCountEval(weights,data->base,multiSet.size());
  for (unsigned int j=0;j<multiSet.size();j++){  	
  	data->emptyBaseNOI += weights[j][0]*weights[j][1];
  	data->numOfCoffes  += weights[j][1];
  }
  carryVecEval(weights,data->base,multiSet.size(),data->carry);
  inputVecEval(weights,data->base,multiSet.size(),data->inputs);
  if (options->opt_verbosity >= 1) {
    data->print();
  	printf("Run time is in micro seconds!!!\n");
  }
  if (options->opt_base != base_M) metaDataToBase(data, outputBase);
  options->baseMetaData.push_back(data);
  return data;
}
Exemplo n.º 3
0
static
void optimizeBase(vec<Int>& seq, int carry_ins, vec<Int>& rhs, int cost, vec<int>& base, int& cost_bestfound, vec<int>& base_bestfound)
{
    if (cost >= cost_bestfound)
        return;

    // "Base case" -- don't split further, build sorting network for current sequence:
    int final_cost = 0;
    for (int i = 0; i < seq.size(); i++){
        if (seq[i] > INT_MAX)
            goto TooBig;
      #ifdef ExpensiveBigConstants
        final_cost += toint(seq[i]);
      #else
        int c; for (c = 1; c*c < seq[i]; c++);
        final_cost += c;
      #endif
        if (final_cost < 0)
            goto TooBig;
    }
    if (cost + final_cost < cost_bestfound){
        base.copyTo(base_bestfound);
        cost_bestfound = cost + final_cost;
    }
  TooBig:;

    /**/static int depth = 0;

    // <<== could count 1:s here for efficiency

    vec<Int> new_seq;
    vec<Int> new_rhs;
#ifdef PickSmallest
    int p = -1;
    for (int i = 0; i < seq.size(); i++)
        if (seq[i] > 1){ p = seq[i]; break; }
    if (p != -1){
#else
    //int upper_lim = (seq.size() == 0) ? 1 : seq.last(); // <<== Check that sqRoot is an 'int' (no truncation of 'Int')
    //for (int i = 0; i < (int)elemsof(primes) && primes[i] <= upper_lim; i++){
    for (int i = 0; i < (int)elemsof(primes); i++){
        int p    = primes[i];
#endif
        int rest = carry_ins;   // Sum of all the remainders.
        Int div, rem;

        /**/for (int n = depth; n != 0; n--) pf("  "); pf("prime=%d   carry_ins=%d\n", p, carry_ins);
        /**/for (int n = depth; n != 0; n--) pf("  "); pf("New seq:");
        for (int j = 0; j < seq.size(); j++){
            rest += toint(seq[j] % Int(p));
            div = seq[j] / Int(p);
            if (div > 0)
                //**/pf(" %d", div),
                new_seq.push(div);
        }
        /**/pf("\n");
        /**/for (int n = depth; n != 0; n--) pf("  "); pf("rest=%d\n", rest);

        /**/for (int n = depth; n != 0; n--) pf("  "); pf("New rhs:");
#ifdef AllDigitsImportant
        bool    digit_important = true;
#else
        bool    digit_important = false;
#endif
        for (int j = 0; j < rhs.size(); j++){
            div = rhs[j] / p;
            if (new_rhs.size() == 0 || div > new_rhs.last()){
                rem = rhs[j] % p;
                /**/pf(" %d:%d", div, rem),
                new_rhs.push(div);
                if (!(rem == 0 && rest < p) && !(rem > rest))
                    digit_important = true;
            }
            /* <<==
            om 'rhs' slutar på 0:a och 'rest' inte kan overflowa, då behövs inte det sorterande nätverket för 'rest' ("always TRUE")
            samma sak om 'rhs' sista siffra är strikt större än 'rest' ("never TRUE")
            */
        }
        /**/pf("\n\n");

        base.push(p);
        /**/depth++;
        optimizeBase(new_seq, rest/p, new_rhs, cost+(digit_important ? rest : 0), base, cost_bestfound, base_bestfound);
        /**/depth--;
        base.pop();

        new_seq.clear();
        new_rhs.clear();
    }
}


static
void optimizeBase(vec<Int>& seq, vec<Int>& rhs, int& cost_bestfound, vec<int>& base_bestfound)
{
    vec<int>    base;
    cost_bestfound = INT_MAX;
    base_bestfound.clear();
    optimizeBase(seq, 0, rhs, 0, base, cost_bestfound, base_bestfound);
}