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"; */ }
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; }
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); }
void normalize(vec& v) { scalar mag = norm(v); for (vec::iterator it=v.begin(); it != v.end(); ++it) (*it) = (*it)/mag; }
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; }
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); }); }