Files
ortools-clone/examples/cpp/fap_utilities.cc
2012-09-13 16:25:28 +00:00

203 lines
8.7 KiB
C++

// Copyright 2010-2012 Google
// 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 "cpp/fap_utilities.h"
#include <map>
#include <set>
#include <vector>
#include "base/logging.h"
#include "base/stringprintf.h"
#include "base/concise_iterator.h"
#include "base/map-util.h"
namespace operations_research {
bool CheckConstraintSatisfaction(const std::vector<FapConstraint>& data_constraints,
const std::vector<int>& variables,
const std::map<int, int>& index_from_key) {
bool status = true;
for (ConstIter<std::vector<FapConstraint> > it(data_constraints);
!it.at_end(); ++it) {
const int index1 = FindOrDie(index_from_key, it->variable1_);
const int index2 = FindOrDie(index_from_key, it->variable2_);
CHECK_LT(index1, variables.size());
CHECK_LT(index2, variables.size());
const int var1 = variables[index1];
const int var2 = variables[index2];
const int absolute_difference = abs(var1 - var2);
if (it->hard_) {
if ((it->operator_ == ">") && (absolute_difference <= it->value_)) {
LOG(INFO) << StringPrintf(" Violation of contraint between variable %d"
" and variable %d.\n",
it->variable1_, it->variable2_);
LOG(INFO) << StringPrintf(" Expected |%d - %d| (= %d) > %d.",
var1, var2,
absolute_difference, it->value_);
status = false;
} else if ((it->operator_ == "=") &&
(absolute_difference != it->value_)) {
LOG(INFO) << StringPrintf(" Violation of contraint between variable %d"
" and variable %d.\n",
it->variable1_, it->variable2_);
LOG(INFO) << StringPrintf(" Expected |%d - %d| (= %d) == %d.",
var1, var2,
absolute_difference, it->value_);
status = false;
}
}
}
return status;
}
bool CheckVariablePosition(const std::map<int, FapVariable>& data_variables,
const std::vector<int>& variables,
const std::map<int, int>& index_from_key) {
bool status = true;
for (ConstIter<std::map<int, FapVariable> > it(data_variables);
!it.at_end(); ++it) {
const int index = FindOrDie(index_from_key, it->first);
CHECK_LT(index, variables.size());
const int var = variables[index];
if (it->second.hard_ &&
(it->second.initial_position_ != -1) &&
(var != it->second.initial_position_)) {
LOG(INFO) << StringPrintf(" Change of position of hard variable %d.\n",
it->first);
LOG(INFO) << StringPrintf(" Expected %d instead of given %d.",
it->second.initial_position_, var);
status = false;
}
}
return status;
}
int NumberOfAssignedValues(const std::vector<int>& variables) {
std::set<int> assigned(variables.begin(), variables.end());
return static_cast<int>(assigned.size());
}
void PrintElapsedTime(const int64 time1, const int64 time2) {
LOG(INFO) << "End of solving process.";
LOG(INFO) << "The Solve method took " << (time2 - time1)/1000.0 <<
" seconds.";
}
void PrintResultsHard(SolutionCollector* const collector,
const std::vector<IntVar*>& variables,
IntVar* const objective_var,
const std::map<int, FapVariable>& data_variables,
const std::vector<FapConstraint>& data_constraints,
const std::map<int, int>& index_from_key,
const std::vector<int>& key_from_index) {
LOG(INFO) << "Printing...";
LOG(INFO) << "Number of Solutions: " << collector->solution_count();
for (int solution_index = 0; solution_index < collector->solution_count();
++solution_index) {
Assignment* const solution = collector->solution(solution_index);
std::vector<int> results(variables.size());
LOG(INFO) << "------------------------------------------------------------";
LOG(INFO) << "Solution " << solution_index + 1;
for (int i = 0; i < variables.size(); ++i) {
LOG(INFO) << StringPrintf(" Variable %2d: %3lld",
key_from_index[i],
solution->Value(variables[i]));
results[i] = solution->Value(variables[i]);
}
if (CheckConstraintSatisfaction(data_constraints, results,
index_from_key)) {
LOG(INFO) << "All hard constraints satisfied.";
} else {
LOG(INFO) << "WARNING!!! Hard constraint violation detected!";
}
if (CheckVariablePosition(data_variables, results, index_from_key)) {
LOG(INFO) << "All hard variables stayed unharmed.";
} else {
LOG(INFO) << "WARNING!!! Hard variable modification detected!";
}
LOG(INFO) << "Values used: " << NumberOfAssignedValues(results);
LOG(INFO) << "Maximum value used: " << *max_element(results.begin(),
results.end());
LOG(INFO) << " Objective: " << solution->Value(objective_var);
LOG(INFO) << StringPrintf(" Failures: %3lld\n\n",
collector->failures(solution_index));
}
LOG(INFO) << " ============================================================";
LOG(INFO) << " ============================================================";
}
void PrintResultsSoft(SolutionCollector* const collector,
const std::vector<IntVar*>& variables,
IntVar* const total_cost,
const std::map<int, FapVariable>& hard_variables,
const std::vector<FapConstraint>& hard_constraints,
const std::map<int, FapVariable>& soft_variables,
const std::vector<FapConstraint>& soft_constraints,
const std::map<int, int>& index_from_key,
const std::vector<int>& key_from_index) {
LOG(INFO) << "Printing...";
LOG(INFO) << "Number of Solutions: " << collector->solution_count();
for (int solution_index = 0; solution_index < collector->solution_count();
++solution_index) {
Assignment* const solution = collector->solution(solution_index);
std::vector<int> results(variables.size());
LOG(INFO) << "------------------------------------------------------------";
LOG(INFO) << "Solution";
for (int i = 0; i < variables.size(); ++i) {
LOG(INFO) << StringPrintf(" Variable %2d: %3lld",
key_from_index[i],
solution->Value(variables[i]));
results[i] = solution->Value(variables[i]);
}
if (CheckConstraintSatisfaction(hard_constraints, results,
index_from_key)) {
LOG(INFO) << "All hard constraints satisfied.";
} else {
LOG(INFO) << "WARNING!!! Hard constraint violation detected!";
}
if (CheckVariablePosition(hard_variables, results, index_from_key)) {
LOG(INFO) << "All hard variables stayed unharmed.";
} else {
LOG(INFO) << "WARNING!!! Hard variable modification detected!";
}
if (CheckConstraintSatisfaction(soft_constraints, results,
index_from_key) &&
CheckVariablePosition(soft_variables, results, index_from_key)) {
LOG(INFO) << "Problem feasible: "
"Soft constraints and soft variables satisfied.";
LOG(INFO) << " Weighted Sum: " << solution->Value(total_cost);
} else {
LOG(INFO) << "Problem unfeasible. Optimized weighted sum of violations.";
LOG(INFO) << " Weighted Sum: " << solution->Value(total_cost);
}
LOG(INFO) << "Values used: " << NumberOfAssignedValues(results);
LOG(INFO) << "Maximum value used: " <<
*max_element(results.begin(), results.end());
LOG(INFO) << StringPrintf(" Failures: %3lld\n\n",
collector->failures(solution_index));
}
LOG(INFO) << " ============================================================";
LOG(INFO) << " ============================================================";
}
} // namespace operations_research