### [option] -qpmult=[double] multiplier quadratic terms (default value is 2.0,...

[option] -qpmult=[double] multiplier quadratic terms (default value is 2.0, use 0.5 insteas for QPLIB instances) ; output QPBO solution found objective value in their original format
parent d786dcb8
 ... ... @@ -5,10 +5,9 @@ The goal is to minimize or maximize the quadratic function: X' * W * X = \sum_i=1 to N \sum_j=1 to N W_ij * X_i * X_j where W is a symmetric squared N*N matrix expressed by all its non-zero half (i<=j) squared matrix coefficients, X is a vector of N binary variables with domain values in {0,1} or {1,-1}, and X' is the transposed vector of X. Note: for two indices i != j, coefficient W_ij = W_ji (symmetric matrix) and appears twice in the previous sum. where W is a symmetric squared N*N matrix expressed by all its non-zero triangle (i<=j) matrix coefficients, X is a vector of N binary variables with domain values in {0,1} or {1,-1}, and X' is the transposed vector of X. Note: for two indices i < j, quadratic coefficient term W_ji = W_ij (symmetric matrix) and appears twice in the previous sum. W_ij is therefore multiplied by two from the original file. Note: coefficients can be positive or negative and are real float numbers. they are converted to fixed-point real numbers by multiplying them by 10^precision (see option -precision to modify it, default value is 7). Infinite coefficients are forbidden. Note: depending on the sign of the number of variables in the first text line, the domain of all variables is either {0,1} or {1, -1} ... ... @@ -35,4 +34,4 @@ such that i <= j and W_ij != 0 --- suggestions send to: simon.de-givry@inra.fr INRA @ 2012 INRA @ 2018
 // Cmake generated version #define Toulbar_VERSION "1.0.0-123-g75f2763-master-tainted (1540908133)" #define Toulbar_VERSION "1.0.0-124-ga60cca5-master-tainted (1541602277)"
 ... ... @@ -443,6 +443,7 @@ public: static LcLevelType LcLevel; static bool wcnf; static bool qpbo; static double qpboQuadraticCoefMultiplier; static char* varOrder; static int btdMode; ... ... @@ -527,7 +528,7 @@ inline bool CSP(Cost lb, Cost ub) { return CUT(lb + UNIT_COST, ub); } #ifdef LONGLONG_COST inline Cost rounding(Cost lb) { return (((lb % max(UNIT_COST, (Cost)floor(ToulBar2::costMultiplier))) != MIN_COST) ? (lb + (Cost)floor(ToulBar2::costMultiplier)) : lb); return (((lb % max(UNIT_COST, (Cost)floor(fabs(ToulBar2::costMultiplier)))) != MIN_COST) ? (lb + (Cost)floor(fabs(ToulBar2::costMultiplier))) : lb); } inline bool CUT(Cost lb, Cost ub) { ... ...
 ... ... @@ -144,6 +144,7 @@ Cost ToulBar2::deltaUb; BEP* ToulBar2::bep; bool ToulBar2::wcnf; bool ToulBar2::qpbo; double ToulBar2::qpboQuadraticCoefMultiplier; char* ToulBar2::varOrder; int ToulBar2::btdMode; ... ... @@ -303,6 +304,7 @@ void tb2init() ToulBar2::bep = NULL; ToulBar2::wcnf = false; ToulBar2::qpbo = false; ToulBar2::qpboQuadraticCoefMultiplier = 2.; ToulBar2::varOrder = NULL; ToulBar2::btdMode = 0; ... ... @@ -370,13 +372,8 @@ void tb2init() } /// \brief checks compatibility between selected options of ToulBar2 needed by numberjack/toulbar2 void tb2checkOptions(Cost ub) void tb2checkOptions() { if (ub <= MIN_COST) { cerr << "Error: wrong initial primal bound (negative or zero)." << endl; exit(1); } if (ToulBar2::costMultiplier != UNIT_COST && (ToulBar2::uai || ToulBar2::qpbo)) { cerr << "Error: cost multiplier cannot be used with UAI and QPBO formats. Use option -precision instead." << endl; exit(1); ... ... @@ -412,14 +409,6 @@ void tb2checkOptions(Cost ub) cerr << "Error: BTD search mode required for approximate solution counting (use '-B=1')." << endl; exit(1); } if (ToulBar2::allSolutions && ToulBar2::btdMode == 1 && ub > 1) { cerr << "Error: Solution enumeration by BTD-like search methods is only possible for feasability (use -ub=1 and integer costs only)." << endl; exit(1); } if (ToulBar2::allSolutions && ToulBar2::btdMode == 1 && ub == 1 && ToulBar2::hbfs) { cerr << "Error: Hybrid best-first search cannot currently look for all solutions when BTD mode is activated. Shift to DFS (use -hbfs:)." << endl; exit(1); } if (ToulBar2::allSolutions && ToulBar2::btdMode > 1) { cerr << "Error: RDS-like method cannot currently enumerate solutions. Use DFS/HBFS search or BTD (feasibility only)." << endl; exit(1); ... ... @@ -1954,8 +1943,12 @@ void WCSP::preprocessing() setDACOrder(elimorder); processTernary(); propagate(); if (ToulBar2::verbose >= 0 && getLb() > previouslb) cout << "PIC dual bound: " << getLb() << " (+" << 100. * (getLb() - previouslb) / getLb() << "%, " << numberOfConstraints() << " cost functions)" << endl; if (ToulBar2::verbose >= 0 && getLb() > previouslb) { if (ToulBar2::uai) cout << "PIC dual bound: " << std::fixed << std::setprecision(ToulBar2::decimalPoint) << getDDualBound() << std::setprecision(DECIMAL_POINT) << " energy: " << -(Cost2LogProb(getLb()) + ToulBar2::markov_log) << " (+" << 100. * (getLb() - previouslb) / getLb() << "%, " << numberOfConstraints() << " cost functions)" << endl; else cout << "PIC dual bound: " << std::fixed << std::setprecision(ToulBar2::decimalPoint) << getDDualBound() << std::setprecision(DECIMAL_POINT) << " (+" << 100. * (getLb() - previouslb) / getLb() << "%, " << numberOfConstraints() << " cost functions)" << endl; } } while (getLb() > previouslb && 100. * (getLb() - previouslb) / getLb() > 0.5); } else if (ToulBar2::preprocessNary > 0) { processTernary(); ... ...
 ... ... @@ -1465,7 +1465,18 @@ pair Solver::hybridSolve(Cluster* cluster, Cost clb, Cost cub) Cost Solver::beginSolve(Cost ub) { // Last-minute compatibility checks for ToulBar2 selected options tb2checkOptions(wcsp->getUb()); if (ub <= MIN_COST) { cerr << "Error: wrong initial primal bound (negative or zero)." << endl; exit(1); } if (ToulBar2::allSolutions && ToulBar2::btdMode == 1 && ub > 1) { cerr << "Error: Solution enumeration by BTD-like search methods is only possible for feasability (use -ub=1 and integer costs only)." << endl; exit(1); } if (ToulBar2::allSolutions && ToulBar2::btdMode == 1 && ub == 1 && ToulBar2::hbfs) { cerr << "Error: Hybrid best-first search cannot currently look for all solutions when BTD mode is activated. Shift to DFS (use -hbfs:)." << endl; exit(1); } if (ToulBar2::searchMethod != DFBB) { if (!ToulBar2::lds || ToulBar2::vnsLDSmax < 0) ... ... @@ -1476,8 +1487,8 @@ Cost Solver::beginSolve(Cost ub) ToulBar2::vnsKmax = wcsp->numberOfUnassignedVariables(); } if (wcsp->isGlobal() && ToulBar2::btdMode >= 1) { cout << "Warning! Cannot use BTD-like search methods with global cost functions." << endl; ToulBar2::btdMode = 0; cout << "Error: cannot use BTD-like search methods with monolithic global cost functions (remove -B option)." << endl; exit(1); } if (wcsp->isGlobal() && (ToulBar2::elimDegree_preprocessing >= 1 || ToulBar2::elimDegree_preprocessing < -1)) { cout << "Warning! Cannot use generic variable elimination with global cost functions." << endl; ... ...
 ... ... @@ -127,6 +127,7 @@ enum { OPT_treedec_ext, OPT_clusterdec_ext, OPT_qpbo_mult, // search option OPT_SEARCH_METHOD, OPT_btdRootCluster, ... ... @@ -298,6 +299,7 @@ CSimpleOpt::SOption g_rgOptions[] = { { OPT_treedec_ext, (char*)"--treedec_ext", SO_REQ_SEP }, { OPT_clusterdec_ext, (char*)"--clusterdec_ext", SO_REQ_SEP }, { OPT_qpbo_mult, (char*)"-qpmult", SO_REQ_SEP }, { OPT_SEARCH_METHOD, (char*)"-B", SO_REQ_SEP }, // -B [0,1,2] search method { OPT_SEARCH_METHOD, (char*)"--search", SO_REQ_SEP }, { OPT_btdRootCluster, (char*)"-R", SO_REQ_SEP }, // root cluster used in BTD ... ... @@ -598,7 +600,7 @@ void help_msg(char* toulbar2filename) #endif cout << " *.wcnf : Weighted Partial Max-SAT format (see Max-SAT Evaluation)" << endl; cout << " *.cnf : (Max-)SAT format" << endl; cout << " *.qpbo : quadratic pseudo-Boolean optimization (unconstrained quadratic programming) format" << endl; cout << " *.qpbo : quadratic pseudo-Boolean optimization (unconstrained quadratic programming) format (see also option -qpmult)" << endl; #ifdef XMLFLAG cout << " *.xml : CSP and weighted CSP in XML format XCSP 2.1"; #ifdef MAXCSP ... ... @@ -631,6 +633,7 @@ void help_msg(char* toulbar2filename) #ifndef MENDELSOFT cout << " -w=[filename] : writes last/all solutions in filename (or \"sol\" if no parameter is given)" << endl; cout << " -precision=[integer] defines the number of digits that should be representable on probabilities in uai/pre files (default value is " << ToulBar2::resolution << ")" << endl; cout << " -qpmult=[double] defines coefficient multiplier for quadratic terms (default value is " << ToulBar2::qpboQuadraticCoefMultiplier << ")" << endl; #else cout << " -w=[mode] : writes last solution found" << endl; cout << " mode=0: saves pedigree with erroneous genotypings removed" << endl; ... ... @@ -1396,6 +1399,12 @@ int _tmain(int argc, TCHAR* argv[]) ToulBar2::costMultiplier = co; } if (args.OptionId() == OPT_qpbo_mult) { double co = atof(args.OptionArg()); if (co != 0.) ToulBar2::qpboQuadraticCoefMultiplier = co; } if (args.OptionId() == OPT_singletonConsistency) ToulBar2::singletonConsistency = true; if (args.OptionId() == OPT_vacValueHeuristic) ... ... @@ -2178,13 +2187,17 @@ int _tmain(int argc, TCHAR* argv[]) ToulBar2::incop_cmd.replace(2, 1, sseed); } tb2checkOptions(); try { if (randomproblem) solver->read_random(n, m, p, ToulBar2::seed, forceSubModular, randomglobal); else globalUb = solver->read_wcsp((char*)strfile.c_str()); if (globalUb <= MIN_COST) { cerr << "Error: wrong initial primal bound (negative or zero)." << endl; exit(1); } tb2checkOptions(globalUb); //TODO: If --show_options then dump ToulBar2 object here if (certificate) { ... ...
 ... ... @@ -530,8 +530,7 @@ public: /// \brief initialization of ToulBar2 global variables (needed by numberjack/toulbar2) extern void tb2init(); /// \brief checks compatibility between selected options of ToulBar2 (needed by numberjack/toulbar2) /// \return new initial upper bound (if options assume it is a satisfaction problem instead of optimization) extern void tb2checkOptions(Cost initialUpperBound); extern void tb2checkOptions(); #endif /*TOULBAR2LIB_HPP_*/ /* Local Variables: */ ... ...
 ... ... @@ -3263,11 +3263,11 @@ void WCSP::read_wcnf(const char* fileName) } /// \brief minimizes/maximizes \f$X^t \times W \times X = \sum_{i=1}^N \sum_{j=1}^N W_{ij} \times X_i \times X_j \f$ /// where W is expressed by its M non-zero half squared matrix costs (can be positive or negative float numbers) /// \note Costs for \f$i \neq j \f$ are multiplied by 2 by this method (symmetric N*N squared matrix) /// where W is expressed by its M non-zero triangle matrix terms (W_ij, i<=j, it can be positive or negative float numbers) /// \note Quadratic terms for \f$i < j \f$ are multiplied by 2 (see option -qpmult to change this value) to get a symmetric N*N squared matrix /// \note If N is positive, then variable domain values are {0,1} /// \note If N is negative, then variable domain values are {1,-1} with value 1 having index 0 and value -1 having index 1 in the output solutions /// \note If M is positive then minimizes the quadratic function, else maximizes it /// \note If M is positive then minimizes the quadratic objective function, else maximizes it /// \warning It does not allow infinite costs (no forbidden assignments) void WCSP::read_qpbo(const char* fileName) { ... ... @@ -3340,6 +3340,8 @@ void WCSP::read_qpbo(const char* fileName) sumcost += 2. * abs(cost[e]); } Double multiplier = Exp10((Double)ToulBar2::resolution); ToulBar2::costMultiplier = multiplier; if (!minimize) ToulBar2::costMultiplier *= -1.0; if (multiplier * sumcost >= (Double)MAX_COST) { cerr << "This resolution cannot be ensured on the data type used to represent costs! (see option -precision)" << endl; exit(EXIT_FAILURE); ... ... @@ -3353,37 +3355,43 @@ void WCSP::read_qpbo(const char* fileName) if (booldom) { if (cost[e] > 0) { if (minimize) { costs = (Cost)(multiplier * 2. * cost[e]); costs = (Cost)(multiplier * ToulBar2::qpboQuadraticCoefMultiplier * cost[e]); } else { costs = (Cost)(multiplier * 2. * cost[e]); costs = (Cost)(multiplier * ToulBar2::qpboQuadraticCoefMultiplier * cost[e]); costs = costs; costs = costs; negCost += costs; } } else { if (minimize) { costs = (Cost)(multiplier * -2. * cost[e]); costs = (Cost)(multiplier * ToulBar2::qpboQuadraticCoefMultiplier * -cost[e]); costs = costs; costs = costs; negCost += costs; } else { costs = (Cost)(multiplier * -2. * cost[e]); costs = (Cost)(multiplier * ToulBar2::qpboQuadraticCoefMultiplier * -cost[e]); } } } else { if (cost[e] > 0) { if (minimize) { costs = (Cost)(multiplier * 2. * cost[e]); costs = (Cost)(multiplier * ToulBar2::qpboQuadraticCoefMultiplier * 2. * cost[e]); costs = costs; negCost += (Cost)(multiplier * ToulBar2::qpboQuadraticCoefMultiplier * cost[e]); } else { costs = (Cost)(multiplier * 2. * cost[e]); costs = (Cost)(multiplier * ToulBar2::qpboQuadraticCoefMultiplier * 2. * cost[e]); costs = costs; negCost += (Cost)(multiplier * ToulBar2::qpboQuadraticCoefMultiplier * cost[e]); } } else { if (minimize) { costs = (Cost)(multiplier * -2. * cost[e]); costs = (Cost)(multiplier * ToulBar2::qpboQuadraticCoefMultiplier * -2. * cost[e]); costs = costs; negCost += (Cost)(multiplier * ToulBar2::qpboQuadraticCoefMultiplier * -cost[e]); } else { costs = (Cost)(multiplier * -2. * cost[e]); costs = (Cost)(multiplier * ToulBar2::qpboQuadraticCoefMultiplier * -2. * cost[e]); costs = costs; negCost += (Cost)(multiplier * ToulBar2::qpboQuadraticCoefMultiplier * -cost[e]); } } } ... ... @@ -3395,10 +3403,12 @@ void WCSP::read_qpbo(const char* fileName) unaryCosts1[posx[e] - 1] += (Cost)(multiplier * cost[e]); } else { unaryCosts0[posx[e] - 1] += (Cost)(multiplier * cost[e]); negCost += (Cost)(multiplier * cost[e]); } } else { if (minimize) { unaryCosts0[posx[e] - 1] += (Cost)(multiplier * -cost[e]); negCost += (Cost)(multiplier * -cost[e]); } else { unaryCosts1[posx[e] - 1] += (Cost)(multiplier * -cost[e]); } ... ... @@ -3406,15 +3416,19 @@ void WCSP::read_qpbo(const char* fileName) } else { if (cost[e] > 0) { if (minimize) { unaryCosts0[posx[e] - 1] += (Cost)(multiplier * cost[e]); unaryCosts0[posx[e] - 1] += (Cost)(multiplier * 2. * cost[e]); negCost += (Cost)(multiplier * cost[e]); } else { unaryCosts1[posx[e] - 1] += (Cost)(multiplier * cost[e]); unaryCosts1[posx[e] - 1] += (Cost)(multiplier * 2. * cost[e]); negCost += (Cost)(multiplier * cost[e]); } } else { if (minimize) { unaryCosts1[posx[e] - 1] += (Cost)(multiplier * -cost[e]); unaryCosts1[posx[e] - 1] += (Cost)(multiplier * -2. * cost[e]); negCost += (Cost)(multiplier * -cost[e]); } else { unaryCosts0[posx[e] - 1] += (Cost)(multiplier * -cost[e]); unaryCosts0[posx[e] - 1] += (Cost)(multiplier * -2. * cost[e]); negCost += (Cost)(multiplier * -cost[e]); } } } ... ... @@ -3431,8 +3445,9 @@ void WCSP::read_qpbo(const char* fileName) } } sortConstraints(); if (ToulBar2::verbose >= 0) cout << "Read " << n << " variables, with " << 2 << " values at most, and " << m << " nonzero matrix costs." << endl; if (ToulBar2::verbose >= 0) { cout << "Read " << n << " variables, with " << 2 << " values at most, and " << m << " nonzero matrix costs (quadratic coef. multiplier: " << ToulBar2::qpboQuadraticCoefMultiplier << ", shifting value: " << -negCost << ")" << endl; } } /* Local Variables: */ ... ...
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment