edit multidim_knapsack to print assigned items + formatting the code

This commit is contained in:
Driss Lahlou
2016-11-16 18:20:16 +01:00
parent ca094af0e0
commit bd0ecc2d06
13 changed files with 105 additions and 68 deletions

View File

@@ -113,7 +113,8 @@ class OrderedLns : public BaseLns {
int current_index = work_index % dim;
work_index = work_index / dim;
std::pair<std::set<int>::iterator, bool> ret = fragment_set.insert(current_index);
std::pair<std::set<int>::iterator, bool> ret =
fragment_set.insert(current_index);
// Check if element has been used before
if (ret.second) {

View File

@@ -64,10 +64,10 @@ namespace operations_research {
class SymbolsSharedByTwoCardsConstraint : public Constraint {
public:
// This constructor does not take any ownership on its arguments.
SymbolsSharedByTwoCardsConstraint(Solver* const solver,
const std::vector<IntVar*>& card1_symbol_vars,
const std::vector<IntVar*>& card2_symbol_vars,
IntVar* const num_symbols_in_common_var)
SymbolsSharedByTwoCardsConstraint(
Solver* const solver, const std::vector<IntVar*>& card1_symbol_vars,
const std::vector<IntVar*>& card2_symbol_vars,
IntVar* const num_symbols_in_common_var)
: Constraint(solver),
card1_symbol_vars_(card1_symbol_vars),
card2_symbol_vars_(card2_symbol_vars),
@@ -370,9 +370,9 @@ class SwapSymbols : public DobbleOperator {
// one.
class SwapSymbolsOnCardPairs : public DobbleOperator {
public:
SwapSymbolsOnCardPairs(const std::vector<IntVar*>& card_symbol_vars, int num_cards,
int num_symbols, int num_symbols_per_card,
int max_num_swaps)
SwapSymbolsOnCardPairs(const std::vector<IntVar*>& card_symbol_vars,
int num_cards, int num_symbols,
int num_symbols_per_card, int max_num_swaps)
: DobbleOperator(card_symbol_vars, num_cards, num_symbols,
num_symbols_per_card),
rand_(FLAGS_ls_seed),

View File

@@ -40,7 +40,8 @@ void VariableParser::Parse() {
std::vector<std::string> lines;
ParseFileByLines(filename_, &lines);
for (const std::string& line : lines) {
std::vector<std::string> tokens = strings::Split(line, " ", strings::SkipEmpty());
std::vector<std::string> tokens =
strings::Split(line, " ", strings::SkipEmpty());
if (tokens.empty()) {
continue;
}
@@ -66,7 +67,8 @@ void DomainParser::Parse() {
std::vector<std::string> lines;
ParseFileByLines(filename_, &lines);
for (const std::string& line : lines) {
std::vector<std::string> tokens = strings::Split(line, " ", strings::SkipEmpty());
std::vector<std::string> tokens =
strings::Split(line, " ", strings::SkipEmpty());
if (tokens.empty()) {
continue;
}
@@ -96,7 +98,8 @@ void ConstraintParser::Parse() {
std::vector<std::string> lines;
ParseFileByLines(filename_, &lines);
for (const std::string& line : lines) {
std::vector<std::string> tokens = strings::Split(line, " ", strings::SkipEmpty());
std::vector<std::string> tokens =
strings::Split(line, " ", strings::SkipEmpty());
if (tokens.empty()) {
continue;
}
@@ -154,7 +157,8 @@ void ParametersParser::Parse() {
constraint_coefficient_no_ + variable_coefficient_no_);
objective = false;
if (line.find("=") != std::string::npos) {
std::vector<std::string> tokens = strings::Split(line, " ", strings::SkipEmpty());
std::vector<std::string> tokens =
strings::Split(line, " ", strings::SkipEmpty());
CHECK_GE(tokens.size(), 3);
coefficients.push_back(atoi32(tokens[2].c_str()));
}

View File

@@ -19,6 +19,7 @@
#ifndef OR_TOOLS_EXAMPLES_FAP_PARSER_H_
#define OR_TOOLS_EXAMPLES_FAP_PARSER_H_
#include "base/hash.h"
#include <map>
#include <string>
#include <vector>
@@ -26,7 +27,6 @@
#include "base/strtoint.h"
#include "base/split.h"
#include "base/map_util.h"
#include "base/hash.h"
namespace operations_research {
@@ -213,7 +213,9 @@ class ParametersParser {
~ParametersParser();
std::string objective() const { return objective_; }
const std::vector<int>& constraint_weights() const { return constraint_weights_; }
const std::vector<int>& constraint_weights() const {
return constraint_weights_;
}
const std::vector<int>& variable_weights() const { return variable_weights_; }
void Parse();

View File

@@ -25,9 +25,10 @@
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 CheckConstraintSatisfaction(
const std::vector<FapConstraint>& data_constraints,
const std::vector<int>& variables,
const std::map<int, int>& index_from_key) {
bool status = true;
for (const FapConstraint& ct : data_constraints) {
const int index1 = FindOrDie(index_from_key, ct.variable1);

View File

@@ -28,9 +28,10 @@ namespace operations_research {
// Checks if the solution given from the Solver satisfies all
// the hard binary constraints specified in the ctr.txt.
bool CheckConstraintSatisfaction(const std::vector<FapConstraint>& data_constraints,
const std::vector<int>& variables,
const std::map<int, int>& index_from_key);
bool CheckConstraintSatisfaction(
const std::vector<FapConstraint>& data_constraints,
const std::vector<int>& variables,
const std::map<int, int>& index_from_key);
// Checks if the solution given from the Solver has not modified the values of
// the variables that were initially assigned and denoted as hard in var.txt.

View File

@@ -329,8 +329,9 @@ bool ConstraintImpactComparator(FapConstraint constraint1,
return (constraint1.impact > constraint2.impact);
}
int64 ValueEvaluator(hash_map<int64, std::pair<int64, int64>>* value_evaluator_map,
int64 variable_index, int64 value) {
int64 ValueEvaluator(
hash_map<int64, std::pair<int64, int64>>* value_evaluator_map,
int64 variable_index, int64 value) {
CHECK_NOTNULL(value_evaluator_map);
// Evaluate the choice. Smaller ranking denotes a better choice.
int64 ranking = -1;
@@ -357,7 +358,8 @@ int64 ValueEvaluator(hash_map<int64, std::pair<int64, int64>>* value_evaluator_m
new_ranking = existing_value_ranking.second;
}
}
std::pair<int64, int64> new_value_ranking = std::make_pair(new_value, new_ranking);
std::pair<int64, int64> new_value_ranking =
std::make_pair(new_value, new_ranking);
InsertOrUpdate(value_evaluator_map, variable_index, new_value_ranking);
return new_ranking;
@@ -507,7 +509,8 @@ void CreateAdditionalMonitors(OptimizeVar* const objective, Solver* solver,
// of frequencies used to the solution.
void HardFapSolver(const std::map<int, FapVariable>& data_variables,
const std::vector<FapConstraint>& data_constraints,
const std::string& data_objective, const std::vector<int>& values) {
const std::string& data_objective,
const std::vector<int>& values) {
Solver solver("HardFapSolver");
std::vector<SearchMonitor*> monitors;
@@ -652,10 +655,11 @@ void SplitConstraintHardSoft(const std::vector<FapConstraint>& data_constraints,
// Penalize the modification of the initial position of soft variable of
// the instance.
void PenalizeVariablesViolation(const std::map<int, FapVariable>& soft_variables,
const std::map<int, int>& index_from_key,
const std::vector<IntVar*>& variables,
std::vector<IntVar*>* cost, Solver* solver) {
void PenalizeVariablesViolation(
const std::map<int, FapVariable>& soft_variables,
const std::map<int, int>& index_from_key,
const std::vector<IntVar*>& variables, std::vector<IntVar*>* cost,
Solver* solver) {
for (const auto& it : soft_variables) {
const int index = FindOrDie(index_from_key, it.first);
CHECK_LT(index, variables.size());
@@ -668,13 +672,12 @@ void PenalizeVariablesViolation(const std::map<int, FapVariable>& soft_variables
}
// Penalize the violation of soft constraints of the instance.
void PenalizeConstraintsViolation(const std::vector<FapConstraint>& constraints,
const std::vector<FapConstraint>& soft_constraints,
const std::map<int, int>& index_from_key,
const std::vector<IntVar*>& variables,
std::vector<IntVar*>* cost,
std::vector<IntVar*>* violated_constraints,
Solver* solver) {
void PenalizeConstraintsViolation(
const std::vector<FapConstraint>& constraints,
const std::vector<FapConstraint>& soft_constraints,
const std::map<int, int>& index_from_key,
const std::vector<IntVar*>& variables, std::vector<IntVar*>* cost,
std::vector<IntVar*>* violated_constraints, Solver* solver) {
int violated_constraints_index = 0;
for (const FapConstraint& ct : constraints) {
CHECK_LT(violated_constraints_index, violated_constraints->size());
@@ -719,7 +722,8 @@ void PenalizeConstraintsViolation(const std::vector<FapConstraint>& constraints,
// equal to 0 denotes that the instance is feasible.
int SoftFapSolver(const std::map<int, FapVariable>& data_variables,
const std::vector<FapConstraint>& data_constraints,
const std::string& data_objective, const std::vector<int>& values) {
const std::string& data_objective,
const std::vector<int>& values) {
Solver solver("SoftFapSolver");
std::vector<SearchMonitor*> monitors;

View File

@@ -149,8 +149,14 @@ void Solve(const std::vector<std::vector<Task>>& tasks_per_job, int horizon) {
}
} // namespace sat
} // namespace operations_research
int main(int argc, char** argv) {
gflags::ParseCommandLineFlags( &argc, &argv, true);
if (FLAGS_input.empty()) {
LOG(FATAL) << "Please supply a data file with --input=";
}
void LoadAndSolve() {
// Read a flexible/normal job shop problem based on the file extension.
int new_task_id = 0;
int horizon = 0;
@@ -190,15 +196,6 @@ void LoadAndSolve() {
}
// Solve it.
sat::Solve(data, horizon);
}
} // namespace operations_research
int main(int argc, char** argv) {
gflags::ParseCommandLineFlags( &argc, &argv, true);
if (FLAGS_input.empty()) {
LOG(FATAL) << "Please supply a data file with --input=";
}
operations_research::LoadAndSolve();
operations_research::sat::Solve(data, horizon);
return EXIT_SUCCESS;
}

View File

@@ -27,7 +27,8 @@
namespace operations_research {
class OneVarLns : public BaseLns {
public:
explicit OneVarLns(const std::vector<IntVar*>& vars) : BaseLns(vars), index_(0) {}
explicit OneVarLns(const std::vector<IntVar*>& vars)
: BaseLns(vars), index_(0) {}
~OneVarLns() override {}

View File

@@ -290,14 +290,20 @@ void SolveKnapsack(MultiDimKnapsackData* const data) {
std::vector<SearchMonitor*> monitors;
OptimizeVar* const objective_monitor = solver.MakeMaximize(objective, 1);
monitors.push_back(objective_monitor);
// Add a search collector of assign variables
SolutionCollector* const assign_solution_collector =
solver.MakeLastSolutionCollector();
assign_solution_collector->Add(assign);
monitors.push_back(assign_solution_collector);
if (FLAGS_display_search_log) {
SearchMonitor* const search_log = solver.MakeSearchLog(1000000, objective);
monitors.push_back(search_log);
}
DecisionBuilder* const db =
solver.MakePhase(assign, [data](int64 var, int64 value) {
return EvaluateItem(*data, var, value);
}, Solver::CHOOSE_STATIC_GLOBAL_BEST);
DecisionBuilder* const db = solver.MakePhase(
assign, [data](int64 var,
int64 value) { return EvaluateItem(*data, var, value); },
Solver::CHOOSE_STATIC_GLOBAL_BEST);
if (FLAGS_time_limit_in_ms != 0) {
LOG(INFO) << "adding time limit of " << FLAGS_time_limit_in_ms << " ms";
SearchLimit* const limit = solver.MakeLimit(
@@ -313,6 +319,19 @@ void SolveKnapsack(MultiDimKnapsackData* const data) {
if (solver.Solve(db, monitors)) {
LOG(INFO) << "Best solution found = " << objective_monitor->best();
std::string assigned_items = "";
for (int i = 0; i < assign.size(); i++) {
IntVar* assign_var = assign[i];
if (assign_solution_collector->Value(0, assign_var) == 1) {
assigned_items += ", " + std::to_string(i);
}
}
if (assigned_items == "") {
LOG(INFO) << "No items were assigned";
} else {
assigned_items.erase(0, 2);
LOG(INFO) << "Assigned items : " << assigned_items << ".";
}
}
}
} // namespace operations_research

View File

@@ -584,8 +584,8 @@ class NetworkRoutingSolver {
class PathBasedLns : public BaseLns {
public:
PathBasedLns(const std::vector<IntVar*>& vars, int fragment_size,
const std::vector<std::vector<OnePath> >& all_paths, int num_arcs,
const std::vector<int64>& actual_usage_costs)
const std::vector<std::vector<OnePath> >& all_paths,
int num_arcs, const std::vector<int64>& actual_usage_costs)
: BaseLns(vars),
rand_(FLAGS_lns_seed),
fragment_size_(fragment_size),
@@ -717,7 +717,8 @@ class NetworkRoutingSolver {
class StoreUsageCosts : public DecisionBuilder {
public:
StoreUsageCosts(const std::vector<IntVar*>& vars, std::vector<int64>* values)
StoreUsageCosts(const std::vector<IntVar*>& vars,
std::vector<int64>* values)
: vars_(vars), values_(values) {}
~StoreUsageCosts() override {}
@@ -874,8 +875,8 @@ class NetworkRoutingSolver {
}
void DisplaySolution(int num_arcs, int64 max_usage_cost,
const std::vector<IntVar*>& usage_costs,
const std::vector<std::vector<IntVar*> >& path_vars, bool precise,
int64 comfort_zone) {
const std::vector<std::vector<IntVar*> >& path_vars,
bool precise, int64 comfort_zone) {
// We will show paths above the comfort zone, or above the max
// utilization minus 5%.
const int64 kFivePercentInThousandth = 50;

View File

@@ -82,7 +82,8 @@ class NQueenSymmetry : public SymmetryBreaker {
// Symmetry vertical axis.
class SX : public NQueenSymmetry {
public:
SX(Solver* const s, const std::vector<IntVar*>& vars) : NQueenSymmetry(s, vars) {}
SX(Solver* const s, const std::vector<IntVar*>& vars)
: NQueenSymmetry(s, vars) {}
~SX() override {}
void VisitSetVariableValue(IntVar* const var, int64 value) override {
@@ -95,7 +96,8 @@ class SX : public NQueenSymmetry {
// Symmetry horizontal axis.
class SY : public NQueenSymmetry {
public:
SY(Solver* const s, const std::vector<IntVar*>& vars) : NQueenSymmetry(s, vars) {}
SY(Solver* const s, const std::vector<IntVar*>& vars)
: NQueenSymmetry(s, vars) {}
~SY() override {}
void VisitSetVariableValue(IntVar* const var, int64 value) override {
@@ -106,7 +108,8 @@ class SY : public NQueenSymmetry {
// Symmetry first diagonal axis.
class SD1 : public NQueenSymmetry {
public:
SD1(Solver* const s, const std::vector<IntVar*>& vars) : NQueenSymmetry(s, vars) {}
SD1(Solver* const s, const std::vector<IntVar*>& vars)
: NQueenSymmetry(s, vars) {}
~SD1() override {}
void VisitSetVariableValue(IntVar* const var, int64 value) override {
@@ -119,7 +122,8 @@ class SD1 : public NQueenSymmetry {
// Symmetry second diagonal axis.
class SD2 : public NQueenSymmetry {
public:
SD2(Solver* const s, const std::vector<IntVar*>& vars) : NQueenSymmetry(s, vars) {}
SD2(Solver* const s, const std::vector<IntVar*>& vars)
: NQueenSymmetry(s, vars) {}
~SD2() override {}
void VisitSetVariableValue(IntVar* const var, int64 value) override {
@@ -132,7 +136,8 @@ class SD2 : public NQueenSymmetry {
// Rotate 1/4 turn.
class R90 : public NQueenSymmetry {
public:
R90(Solver* const s, const std::vector<IntVar*>& vars) : NQueenSymmetry(s, vars) {}
R90(Solver* const s, const std::vector<IntVar*>& vars)
: NQueenSymmetry(s, vars) {}
~R90() override {}
void VisitSetVariableValue(IntVar* const var, int64 value) override {

View File

@@ -95,8 +95,8 @@ int64 TravelPlusServiceTime(const Coordinates* const coords,
// Returns the demand (quantity picked up or delivered) of a node, demands
// holds the demand of each node.
int64 Demand(const std::vector<int64>* const demands, RoutingModel::NodeIndex from,
RoutingModel::NodeIndex to) {
int64 Demand(const std::vector<int64>* const demands,
RoutingModel::NodeIndex from, RoutingModel::NodeIndex to) {
return demands->at(from.value());
}
@@ -245,12 +245,13 @@ bool LoadAndSolve(const std::string& pdp_file) {
routing.SetArcCostEvaluatorOfAllVehicles(
NewPermanentCallback(Travel, const_cast<const Coordinates*>(&coords)));
routing.AddDimension(
NewPermanentCallback(&Demand, const_cast<const std::vector<int64>*>(&demands)),
NewPermanentCallback(&Demand,
const_cast<const std::vector<int64>*>(&demands)),
0, capacity, /*fix_start_cumul_to_zero=*/true, "demand");
routing.AddDimension(
NewPermanentCallback(&TravelPlusServiceTime,
const_cast<const Coordinates*>(&coords),
const_cast<const std::vector<int64>*>(&service_times)),
NewPermanentCallback(
&TravelPlusServiceTime, const_cast<const Coordinates*>(&coords),
const_cast<const std::vector<int64>*>(&service_times)),
kScalingFactor * horizon, kScalingFactor * horizon,
/*fix_start_cumul_to_zero=*/true, "time");
const RoutingDimension& time_dimension = routing.GetDimensionOrDie("time");