google-research
112 строк · 3.4 Кб
1// Copyright 2023 The Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "fairness_constraint.h"
16
17#include <algorithm>
18#include <cassert>
19#include <map>
20#include <memory>
21#include <set>
22#include <utility>
23#include <vector>
24
25#include "matroid.h"
26#include "partition_matroid.h"
27
28FairnessConstraint::FairnessConstraint(
29const std::map<int, int>& colors_map,
30const std::vector<std::pair<int, int>>& bounds) {
31colors_map_ = colors_map;
32bounds_ = bounds;
33ncolors_ = bounds.size();
34current_colorcounts_ = std::vector<int>(ncolors_, 0);
35}
36
37void FairnessConstraint::Reset() {
38std::fill(current_colorcounts_.begin(), current_colorcounts_.end(), 0);
39current_set_.clear();
40}
41
42bool FairnessConstraint::CanAdd(int element) const {
43assert(!current_set_.count(element));
44int elt_color = colors_map_.at(element);
45return current_colorcounts_[elt_color] + 1 <= bounds_[elt_color].second;
46}
47
48void FairnessConstraint::Add(int element) {
49assert(!current_set_.count(element));
50int elt_color = colors_map_.at(element);
51current_colorcounts_[elt_color]++;
52current_set_.insert(element);
53}
54
55bool FairnessConstraint::CanRemove(int element) const {
56assert(current_set_.count(element));
57int elt_color = colors_map_.at(element);
58return current_colorcounts_[elt_color] - 1 >= bounds_[elt_color].first;
59}
60
61void FairnessConstraint::Remove(int element) {
62assert(current_set_.count(element));
63int elt_color = colors_map_.at(element);
64current_colorcounts_[elt_color]--;
65current_set_.erase(element);
66}
67
68int FairnessConstraint::GetColor(int element) const {
69return colors_map_.at(element);
70}
71
72int FairnessConstraint::GetColorNum() const { return bounds_.size(); }
73
74std::vector<std::pair<int, int>> FairnessConstraint::GetBounds() const {
75return bounds_;
76}
77
78bool FairnessConstraint::IsFeasible(const std::vector<int> elements) {
79std::vector<int> colorcounts = std::vector<int>(ncolors_, 0);
80int elt_color;
81for (int elt : elements) {
82elt_color = colors_map_.at(elt);
83colorcounts[elt_color]++;
84if (colorcounts[elt_color] > bounds_[elt_color].second) return false;
85}
86for (int color = 0; color < ncolors_; color++) {
87if (colorcounts[color] < bounds_[color].first) return false;
88}
89return true;
90}
91
92std::unique_ptr<Matroid> FairnessConstraint::LowerBoundsToMatroid() const {
93std::vector<int> ks;
94ks.reserve(bounds_.size());
95for (const std::pair<int, int>& bound : bounds_) {
96ks.push_back(bound.first);
97}
98return std::make_unique<PartitionMatroid>(colors_map_, ks);
99}
100
101std::unique_ptr<Matroid> FairnessConstraint::UpperBoundsToMatroid() const {
102std::vector<int> ks;
103ks.reserve(bounds_.size());
104for (const std::pair<int, int>& bound : bounds_) {
105ks.push_back(bound.second);
106}
107return std::make_unique<PartitionMatroid>(colors_map_, ks);
108}
109
110std::unique_ptr<FairnessConstraint> FairnessConstraint::Clone() const {
111return std::make_unique<FairnessConstraint>(*this);
112}
113