30 std::function<int64_t(
int,
int)> load_demand_of_item_for_bin,
31 std::vector<LoadLimit> load_limit_per_bin) {
32 DCHECK_EQ(num_bins_, load_limit_per_bin.size());
33 for (
const LoadLimit& limit : load_limit_per_bin) {
34 const int64_t violation = std::max<int64_t>(0,
CapOpp(limit.soft_max_load));
36 CapAdd(total_cost_,
CapProd(violation, limit.cost_above_soft_max_load));
38 load_demands_per_dimension_.push_back(std::move(load_demand_of_item_for_bin));
39 for (
int b = 0; b < num_bins_; ++b) {
40 load_per_bin_[b].push_back(0);
41 load_limits_per_bin_[b].push_back(load_limit_per_bin[b]);
51 for (
size_t dim = 0; dim < load_demands_per_dimension_.size(); ++dim) {
52 const LoadLimit& limit = load_limits_per_bin_[bin][dim];
53 int64_t new_load = load_per_bin_[bin][dim];
54 for (
const int item : items) {
55 new_load =
CapAdd(new_load, load_demands_per_dimension_[dim](item, bin));
59 if (new_load > limit.
max_load)
return false;
66 for (
size_t dim = 0; dim < load_demands_per_dimension_.size(); ++dim) {
67 int64_t& load = load_per_bin_[bin][dim];
68 const LoadLimit& limit = load_limits_per_bin_[bin][dim];
69 const int64_t prev_violation =
71 load =
CapAdd(load, load_demands_per_dimension_[dim](item, bin));
72 const int64_t curr_violation =
84 for (
size_t dim = 0; dim < load_demands_per_dimension_.size(); ++dim) {
85 int64_t& load = load_per_bin_[bin][dim];
86 const LoadLimit& limit = load_limits_per_bin_[bin][dim];
87 const int64_t prev_violation =
89 load =
CapSub(load, load_demands_per_dimension_[dim](item, bin));
90 const int64_t curr_violation =
122 int num_arcs, int64_t start,
123 const std::function<int64_t(int64_t)>& next_accessor,
124 const std::function<
bool(int64_t)>& is_end,
125 const std::function<int64_t(int64_t, int64_t, int64_t)>&
126 arc_cost_for_route_start,
127 std::vector<std::pair<int64_t, int>>* most_expensive_arc_starts_and_ranks,
128 std::pair<int, int>* first_expensive_arc_indices) {
129 if (is_end(next_accessor(start))) {
131 *first_expensive_arc_indices = {-1, -1};
137 using ArcCostNegativeRankStart = std::tuple<int64_t, int, int64_t>;
138 std::priority_queue<ArcCostNegativeRankStart,
139 std::vector<ArcCostNegativeRankStart>,
140 std::greater<ArcCostNegativeRankStart>>
143 int64_t before_node = start;
145 while (!is_end(before_node)) {
146 const int64_t after_node = next_accessor(before_node);
147 const int64_t arc_cost =
148 arc_cost_for_route_start(before_node, after_node, start);
149 arc_info_pq.emplace(arc_cost, -rank, before_node);
151 before_node = after_node;
154 if (rank > num_arcs) {
160 DCHECK_EQ(arc_info_pq.size(), std::min(rank, num_arcs));
162 most_expensive_arc_starts_and_ranks->resize(arc_info_pq.size());
163 int arc_index = arc_info_pq.size() - 1;
164 while (!arc_info_pq.empty()) {
165 const ArcCostNegativeRankStart& arc_info = arc_info_pq.top();
166 (*most_expensive_arc_starts_and_ranks)[arc_index] = {
167 std::get<2>(arc_info), -std::get<1>(arc_info)};
172 *first_expensive_arc_indices = {0, 1};
bool FindMostExpensiveArcsOnRoute(int num_arcs, int64_t start, const std::function< int64_t(int64_t)> &next_accessor, const std::function< bool(int64_t)> &is_end, const std::function< int64_t(int64_t, int64_t, int64_t)> &arc_cost_for_route_start, std::vector< std::pair< int64_t, int > > *most_expensive_arc_starts_and_ranks, std::pair< int, int > *first_expensive_arc_indices)