edit multidim_knapsack to print assigned items + formatting the code
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user