int frobenius(const vec& a) { // O(n + A) space // Return the Frobenius number of the numbers in a[1..n], that is, // the largest t such that t cannot be expressed as a nonnegative // integer linear combination of the entries of a[1..n] if(gcd(a) > 1) return INF; int n = a.size()-1; int a_min = *min_element(a.begin()+1, a.end()); int A = *max_element(a.begin()+1, a.end()); int N = A; vector<bool> x(N, false); x[0] = true; int q = 0, m = 0; while(q < a_min) { ++m; bool repr = false; // check if m representable for(int i=1; i<=n; i++) { int r = (m + N - a[i]) % N; repr = repr || x[r]; if(repr) break; } if(repr) { x[m % N] = true; ++q; } else q = 0; } return m - a_min; }
vec operator+(const vec& lhs, const vec& rhs) { vec::const_iterator itL = lhs.begin(); vec::const_iterator itR = rhs.begin(); vec temp; for (; itL != lhs.end(); ++itL, ++itR) temp.push_back(*itL + *itR); roundZero(temp); return temp; }
scalar eucInnerProd(const vec& v1, const vec& v2) { scalar sum = 0; vec::const_iterator it1 = v1.begin(); vec::const_iterator it2 = v2.begin(); for (; it1 != v1.end(); ++it1, ++it2) sum += (*it1) * (*it2); if (abs(sum) < ROUND_CUTOFF) sum = 0; return sum; }
scalar eucInnerProd(const vec& v1, const vec& v2) { scalar sum = 0; vec::const_iterator it1 = v1.begin(); vec::const_iterator it2 = v2.begin(); for (; it1 != v1.end(); ++it1, ++it2) { sum += (*it1) * (*it2); //std::cout << "Sum = " << sum << std::endl; } if (fabs(sum) < ROUND_CUTOFF) { //std::cout << "Sum = " << sum << " abs(sum) = " << fabs(sum) << std::endl; sum = 0; } //std::cout << "Sum = " << sum << std::endl; return sum; }
void insert( double x ) { best.insert( std::upper_bound( best.begin(), best.end(), x, greater_than< double >() ), x ); if( size() > num_to_save ) { best.resize( num_to_save ); } }
vec<str> vcat(const vec<str> &top, const vec<str> &bottom) { // copy the top picture vec<str> ret = top; // copy the entire bottom picture ret.insert(ret.end(),bottom.begin(),bottom.end()); return ret; }
vec(const vec &v) { create(v.begin(),v.end()); }
// copy Constructor template<class T> vec<T>::vec(const vec& v) { // call create with iterators to handle mem and initialize value create(v.begin(), v.end()); }
void normalize(vec& v) { scalar mag = norm(v); for (vec::iterator it=v.begin(); it != v.end(); ++it) (*it) = (*it)/mag; }
scalar norm(const vec& v) { scalar sum = 0; for (vec::const_iterator it=v.begin(); it != v.end(); ++it) sum += (*it) * (*it); return sqrt(sum); }
vec operator*(const scalar s, const vec& v) { vec temp = {}; for (vec::const_iterator it=v.begin(); it != v.end(); ++it) temp.push_back(s * (*it)); return temp; }
valtype gapBabDp(vec<signed char> ¤tSolution, vec<signed char> &Bcontainer, indtype Nagent, indtype Ntask, WV<valtype, indtype> **info, indtype *residualBudget, int maxCore, std::time_t timer, double tlimit, int &Nnode, int &Nkp) { vec<signed char*> Bv(Ntask); for(indtype j = 0; j < Ntask; ++j) { INT tmp = j * (INT(Nagent) + 1); Bv[j] = &Bcontainer[0] + tmp; Bv[j][Nagent] = 0; } signed char **B = &Bv[0]; vec<indtype> overloadedAgent(Nagent); vec<vec<indtype> > overloadedAgentTask(Nagent, vec<indtype>(Ntask)); vec<vec<indtype> > overloadedAgentWeight(Nagent, vec<indtype>(Ntask)); vec<vec<valtype> > overloadedAgentPenalty(Nagent, vec<valtype>(Ntask)); // will be used as values in knapsacking vec<vec<indtype> > nextAgent(Nagent, vec<indtype>(Ntask)); vec<vec<indtype> > reassign(Nagent, vec<indtype>(Ntask)); vec<vec<indtype> > stay(Nagent, vec<indtype>(Ntask)); vec<indtype> budgetExceedance(Nagent); vec<stackEle<valtype, indtype> > T(INT(Nagent) * Ntask); T.resize(0); currentSolution.resize(INT(Nagent) * Ntask); valtype currentSolutionRevenue = -std::numeric_limits<valtype>::max(); // Auxiliary containers. maxCore = std::min<int> (maxCore, Nagent); vec<indtype> agentCosts(Nagent); // bool postKnapsack = false; while(true) { std::time_t now; std::time(&now); if(std::difftime(now, timer) > tlimit) break; while(true) // Repeat backtracking until knapsacking becomes necessary. { valtype revenueUB = 0; bool needNoBacktrack = findOverloadedAgentsPenaltyWeightNextAgent( revenueUB, overloadedAgent, info, B, Nagent, Ntask, residualBudget, &budgetExceedance[0], &agentCosts[0], overloadedAgentTask, overloadedAgentWeight, // of size Nagent overloadedAgentPenalty, // will be used as values in knapsacking nextAgent, T); // Rcout << "needNoBacktrack = " << needNoBacktrack << "\n"; if(needNoBacktrack and revenueUB > currentSolutionRevenue) { if(overloadedAgent.size() > 0) break; currentSolution.assign(Bcontainer.begin(), Bcontainer.end()); currentSolutionRevenue = revenueUB; } /* Rcout << "revenueUB = " << revenueUB << "\n"; Rcout << "before backtrack, T.size() = " << T.size() << "\n"; for(indtype i = 1, iend = T.size(); i < iend; ++i) { Rcout << T[i].agent << ", " << T[i].task << ", " << int(B[T[i].task][T[i].agent]) << ", "; } Rcout << "\n"; for(indtype i = 0; i < Nagent; ++i) { for(indtype j = 0; j < Ntask; ++j) { if(B[j][i] >= 0) Rcout << " " << int(B[j][i]) << ", "; else Rcout << int(B[j][i]) << ", "; } Rcout << "\n"; } */ bool bt = backtrack(T, B, Nagent, info, residualBudget); /* Rcout << "after backtrack, T.size() = " << T.size() << "\n"; for(indtype i = 1, iend = T.size(); i < iend; ++i) { Rcout << T[i].agent << ", " << T[i].task << ", " << int(B[T[i].task][T[i].agent]) << ", "; } Rcout << "\n"; for(indtype i = 0; i < Nagent; ++i) { for(indtype j = 0; j < Ntask; ++j) { if(B[j][i] >= 0) Rcout << " " << int(B[j][i]) << ", "; else Rcout << int(B[j][i]) << ", "; } Rcout << "\n"; } */ if(!bt) return currentSolutionRevenue; } /* { Rcout << "After initialization, B = \n"; for(indtype i = 0; i < Nagent; ++i) { for(indtype j = 0; j < Ntask; ++j) { if(B[j][i] >= 0) Rcout << " " << int(B[j][i]) << ", "; else Rcout << int(B[j][i]) << ", "; } Rcout << "\n"; } Rcout << "Overloaded agent = \n"; for(indtype i = 0, iend = overloadedAgent.size(); i < iend; ++i) { Rcout << overloadedAgent[i] << ", "; } Rcout << "\n"; Rcout << "Budget exceedance = \n"; for(indtype i = 0, iend = overloadedAgent.size(); i < iend; ++i) { Rcout << budgetExceedance[overloadedAgent[i]] << ", "; } Rcout << "\n"; Rcout << "overloadedAgentTask = \n"; for(indtype i = 0, iend = overloadedAgent.size(); i < iend; ++i) { indtype a = overloadedAgent[i]; for(indtype j = 0, jend = overloadedAgentTask[a].size(); j < jend; ++j) { Rcout << overloadedAgentTask[a][j] << ", "; } Rcout << "\n"; } Rcout << "overloadedAgentWeight = \n"; for(indtype i = 0, iend = overloadedAgent.size(); i < iend; ++i) { indtype a = overloadedAgent[i]; for(indtype j = 0, jend = overloadedAgentWeight[a].size(); j < jend; ++j) { Rcout << overloadedAgentWeight[a][j] << ", "; } Rcout << "\n"; } Rcout << "next agent = \n"; for(indtype i = 0, iend = overloadedAgent.size(); i < iend; ++i) { indtype a = overloadedAgent[i]; for(indtype j = 0, jend = nextAgent[a].size(); j < jend; ++j) { Rcout << nextAgent[a][j] << ", "; } Rcout << "\n"; } Rcout << "overloadedAgentPenalty = \n"; for(indtype i = 0, iend = overloadedAgent.size(); i < iend; ++i) { indtype a = overloadedAgent[i]; for(indtype j = 0, jend = overloadedAgentPenalty[a].size(); j < jend; ++j) { Rcout << overloadedAgentPenalty[a][j] << ", "; } Rcout << "\n"; } } */ valtype totalPenalty = 0; ++Nnode; Nkp += overloadedAgent.size(); specialBiKpDPpara<valtype, indtype> ( totalPenalty, overloadedAgent, overloadedAgentWeight, overloadedAgentPenalty, stay, reassign, budgetExceedance, std::min<int> (maxCore, overloadedAgent.size())); // Set variables pointed by reassigned to -1. updateBafterKnapsacking<indtype> (overloadedAgent, B, nextAgent, overloadedAgentTask, reassign); /* { Rcout << "After KP, reassign = \n"; for(indtype i = 0, iend = overloadedAgent.size(); i < iend; ++i) { for(indtype j = 0, jend = reassign[i].size(); j < jend; ++j) { Rcout << reassign[i][j] << ", "; } Rcout << "\n"; } Rcout << "After KP, stay = \n"; for(indtype i = 0, iend = overloadedAgent.size(); i < iend; ++i) { for(indtype j = 0, jend = stay[i].size(); j < jend; ++j) { Rcout << stay[i][j] << ", "; } Rcout << "\n"; } Rcout << "After KP, B = \n"; for(indtype i = 0; i < Nagent; ++i) { for(indtype j = 0; j < Ntask; ++j) { if(B[j][i] >= 0) Rcout << " " << int(B[j][i]) << ", "; else Rcout << int(B[j][i]) << ", "; } Rcout << "\n"; } } */ valtype totalReve = 0; bool thereis = thereIsOverlodedAgent( info, B, Nagent, Ntask, residualBudget, &agentCosts[0], totalReve); // Rcout << "Knapsack solution, totalReve = " << totalReve << "\n"; // if(thereis) Rcout << "There is overloaded agent\n"; // else Rcout << "There is no overloaded agent\n"; if(!thereis) { if(totalReve > currentSolutionRevenue) { currentSolutionRevenue = totalReve; currentSolution.assign(Bcontainer.begin(), Bcontainer.end()); } bool bt = backtrack(T, B, Nagent, info, residualBudget); if(!bt) break; } else { pushAllBranchingVariableIntoStack<valtype, indtype, greedyBranch> ( T, B, Nagent, overloadedAgent, stay, overloadedAgentTask, overloadedAgentWeight, overloadedAgentPenalty, residualBudget, info); } // Rcout << "After KP locking, B = \n"; // for(indtype i = 0; i < Nagent; ++i) // { // for(indtype j = 0; j < Ntask; ++j) // { // if(B[j][i] >= 0) Rcout << " " << int(B[j][i]) << ", "; // else Rcout << int(B[j][i]) << ", "; // } // Rcout << "\n"; // } } return currentSolutionRevenue; }
void pushAllBranchingVariableIntoStack( vec<stackEle<valtype, indtype> > &T, signed char **B, indtype Nagent, vec<indtype> &overloaded, vec<vec<indtype> > &stay, vec<vec<indtype> > &targetTask, vec<vec<indtype> > &weight, // overloaded agent, task weights vec<vec<valtype> > &penalty, // overloaded agent, task values indtype *residualBudget, WV<valtype, indtype> **info) { // Push all elements in stay into stack. stackEle<valtype, indtype> *Tst = &*T.end(); for(indtype i = 0, iend = overloaded.size(); i < iend; ++i) { indtype a = overloaded[i]; for(indtype k = 0, kend = stay[i].size(); k < kend; ++k) { indtype tmp = stay[i][k]; valtype desirability = penalty[a][tmp] / weight[a][tmp] * residualBudget[a]; indtype tmpTask = targetTask[a][tmp]; T.push_back(stackEle<valtype, indtype> (a, tmpTask, desirability)); if(greedyBranch) { residualBudget[a] -= weight[a][tmp]; B[tmpTask][a] = 2; B[tmpTask][Nagent] = 1; } for(stackEle<valtype, indtype> *t = &T.back() - 1; t >= Tst; --t) { if(t->desirability >= (t + 1)->desirability) break; std::swap(t[0], t[1]); } } } if(greedyBranch) return; // Check if all newly pushed elements in T are appropriate, and if not, pop. // This check step is not necessary, but the branch tree may be shaped better. { indtype a = Tst->agent, t = Tst->task; residualBudget[a] -= info[t][a].weight; B[t][a] = 2; B[t][Nagent] = 1; } indtype i = 1; for(indtype iend = &*T.end() - Tst; i < iend; ++i) { indtype a = Tst[i].agent, t = Tst[i].task; valtype tmpResidualBudget = residualBudget[a] - info[t][a].weight; indtype *w = &weight[a][0]; indtype *ts = &targetTask[a][0]; bool stackStop = false; for(indtype j = 0, jend = weight[a].size(); j < jend; ++j) { if(ts[j] == t or w[j] <= tmpResidualBudget) continue; stackStop = true; break; } if(stackStop) break; residualBudget[a] = tmpResidualBudget; B[t][a] = 2; B[t][Nagent] = 1; } T.resize(Tst - &*T.begin() + i); /* Rcout << "stack increased by = " << T.size() - (Tst - &*T.begin()) << "\n"; Rcout << "After stack push:\n"; for(indtype t = 1, tend = T.size(); t < tend; ++t) { Rcout << T[t].agent << ", " << T[t].task << ", " << int(B[T[t].task][T[t].agent]) << ", "; } Rcout << "\n"; */ }
std::size_t hash_value(const vec & v) { return ::boost::hash_range(v.begin(), v.end()); }
int gcd(const vec& a) { // Return gcd(a[1], .., a[n]) return accumulate(a.begin()+1, a.end(), a[1], [] (int x, int y) { return gcd(x, y); }); }