// Copyright 2020 The Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "random_algorithm.h"

#include "utilities.h"

void RandomAlgorithm::Init(const SubmodularFunction& sub_func_f,
                     const FairnessConstraint& fairness,
                     const Matroid& matroid) {
  Algorithm::Init(sub_func_f, fairness, matroid);
  universe_elements_.clear();
  solution_.clear();
}

void RandomAlgorithm::Insert(int element) {
  universe_elements_.push_back(element);
}

double RandomAlgorithm::GetSolutionValue() {
  matroid_->Reset();
  solution_.clear();
  std::unique_ptr<Matroid> upper_bound_matroid = fairness_->UpperBoundsToMatroid();

  RandomHandler::Shuffle(universe_elements_);
  for (int element : universe_elements_) {
    if (matroid_->CanAdd(element) && upper_bound_matroid->CanAdd(element)) {
      matroid_->Add(element);
      upper_bound_matroid->Add(element);
      solution_.push_back(element);
    }
  }

  return sub_func_f_->ObjectiveAndIncreaseOracleCall(solution_);
}

std::vector<int> RandomAlgorithm::GetSolutionVector() {
  return solution_;
}

std::string RandomAlgorithm::GetAlgorithmName() const {
  return "Random algorithm";
}
