data: Add vector_bin_packing
This commit is contained in:
126
ortools/data/vector_bin_packing.proto
Normal file
126
ortools/data/vector_bin_packing.proto
Normal file
@@ -0,0 +1,126 @@
|
||||
// Copyright 2010-2018 Google LLC
|
||||
// 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.
|
||||
|
||||
// Vector Bin Packing Problem.
|
||||
//
|
||||
// The problem description is as follows:
|
||||
//
|
||||
// Given:
|
||||
// - a fixed number of resources,
|
||||
// - a set of equivalent multidimentional bins with max capacity on each
|
||||
// resource.
|
||||
// - a set of items, with fixed usage for all resources, and a number of
|
||||
// copies for each item.
|
||||
//
|
||||
// The goal is either:
|
||||
// - optimization: minimizing the number of bins needed to fit all items, or
|
||||
// - feasibility: checking if all items can be packed using at most a given
|
||||
// number of bins.
|
||||
//
|
||||
// In both cases we must ensure that for each bin and each resource, the sum of
|
||||
// sizes of each assigned item is less than the capacity of the resource of the
|
||||
// bin.
|
||||
//
|
||||
// An optional integer imposes an upper bound on how many copies of the same
|
||||
// item are allowed in a single bin, regardless of resource utilization.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "com.google.ortools.data.vbp";
|
||||
option java_multiple_files = true;
|
||||
option csharp_namespace = "Google.OrTools.Data.Vbp";
|
||||
|
||||
package operations_research.data.vbp;
|
||||
|
||||
message Item {
|
||||
// Optional name. This is only used for display/debugging purposes.
|
||||
string name = 1;
|
||||
|
||||
// Resource usages for this item. All usages must be non-negative.
|
||||
// Should be the same size as resource_capacity in the
|
||||
// VectorBinPackingProblem.
|
||||
repeated int64 resource_usage = 2;
|
||||
|
||||
// Number of identical copies of this item.
|
||||
int32 num_copies = 3;
|
||||
|
||||
// An optional upper bound on how many copies of the same item are allowed in
|
||||
// a single bin, regardless of resource utilization. A value of 0 is
|
||||
// interpreted as no limit.
|
||||
int32 max_number_of_copies_per_bin = 4;
|
||||
}
|
||||
|
||||
message VectorBinPackingProblem {
|
||||
// Optional name.
|
||||
string name = 1;
|
||||
|
||||
// Max capacity of each resource.
|
||||
// All bins have the same resource capacities.
|
||||
repeated int64 resource_capacity = 2;
|
||||
|
||||
// Resources names. This can either be left empty or
|
||||
// must be of the same size as resource_capacity.
|
||||
repeated string resource_name = 3;
|
||||
|
||||
// The list of items which are to be assigned to bins.
|
||||
repeated Item item = 4;
|
||||
|
||||
// The maximum number of bins available. A value of 0 is interpreted as no
|
||||
// limit. Nonzero values are used to encode feasibility problems.
|
||||
int32 max_bins = 5;
|
||||
}
|
||||
|
||||
// Describe one filled bin in the solution.
|
||||
message VectorBinPackingOneBinInSolution {
|
||||
// Which items are in this bin. They are supposed to be unique.
|
||||
repeated int32 item_indices = 1;
|
||||
// How many of each items are in this bins.
|
||||
repeated int32 item_copies = 2;
|
||||
}
|
||||
|
||||
// Solve status
|
||||
enum VectorBinPackingSolveStatus {
|
||||
// Default state.
|
||||
VECTOR_BIN_PACKING_SOLVE_STATUS_UNSPECIFIED = 0;
|
||||
|
||||
// The optimal solution was found and proven.
|
||||
OPTIMAL = 1;
|
||||
|
||||
// A feasible solution has been found.
|
||||
FEASIBLE = 2;
|
||||
|
||||
// The problem is infeasible.
|
||||
INFEASIBLE = 3;
|
||||
}
|
||||
|
||||
message VectorBinPackingSolution {
|
||||
// Optional info from the solver.
|
||||
string solver_info = 1;
|
||||
|
||||
// Filled bins.
|
||||
repeated VectorBinPackingOneBinInSolution bins = 2;
|
||||
|
||||
// Solve status.
|
||||
VectorBinPackingSolveStatus status = 3;
|
||||
|
||||
// Objective value.
|
||||
double objective_value = 4;
|
||||
|
||||
// Solve time in seconds.
|
||||
double solve_time_in_seconds = 5;
|
||||
|
||||
// Time to create the Arc-Flow graph.
|
||||
double arc_flow_time_in_seconds = 6;
|
||||
|
||||
// TODO(user): Do we add copies of bins?
|
||||
}
|
||||
121
ortools/data/vector_bin_packing_parser.cc
Normal file
121
ortools/data/vector_bin_packing_parser.cc
Normal file
@@ -0,0 +1,121 @@
|
||||
// Copyright 2010-2018 Google LLC
|
||||
// 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 "ortools/data/vector_bin_packing_parser.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "absl/strings/numbers.h"
|
||||
#include "absl/strings/str_split.h"
|
||||
#include "ortools/base/filelineiter.h"
|
||||
#include "ortools/data/vector_bin_packing.pb.h"
|
||||
|
||||
namespace operations_research {
|
||||
namespace data {
|
||||
namespace vbp {
|
||||
|
||||
bool VbpParser::ParseFile(const std::string& data_filename) {
|
||||
vbp_.Clear();
|
||||
|
||||
load_status_ = DIMENSION_SECTION;
|
||||
for (const std::string& line : FileLines(data_filename)) {
|
||||
if (load_status_ == ERROR_FOUND) break;
|
||||
ProcessLine(line);
|
||||
}
|
||||
|
||||
// Checks status.
|
||||
if (load_status_ == ERROR_FOUND) {
|
||||
LOG(INFO) << vbp_.DebugString();
|
||||
return false;
|
||||
}
|
||||
return vbp_.item_size() == num_declared_items_;
|
||||
}
|
||||
|
||||
void VbpParser::ReportError(const std::string& line) {
|
||||
LOG(ERROR) << "Error: status = " << load_status_ << ", line = " << line;
|
||||
load_status_ = ERROR_FOUND;
|
||||
}
|
||||
|
||||
void VbpParser::ProcessLine(const std::string& line) {
|
||||
const std::vector<std::string> words =
|
||||
absl::StrSplit(line, absl::ByAnyChar(" :\t\r"), absl::SkipEmpty());
|
||||
|
||||
if (words.empty()) return;
|
||||
|
||||
switch (load_status_) {
|
||||
case NOT_STARTED: {
|
||||
LOG(FATAL) << "Should not be here";
|
||||
}
|
||||
case DIMENSION_SECTION: {
|
||||
if (words.size() != 1) {
|
||||
ReportError(line);
|
||||
return;
|
||||
}
|
||||
num_resources_ = strtoint32(words[0]);
|
||||
load_status_ = BIN_SECTION;
|
||||
break;
|
||||
}
|
||||
case BIN_SECTION: {
|
||||
if (words.size() != num_resources_) {
|
||||
ReportError(line);
|
||||
return;
|
||||
}
|
||||
for (const std::string& dim_str : words) {
|
||||
vbp_.add_resource_capacity(strtoint64(dim_str));
|
||||
}
|
||||
load_status_ = NUMBER_OF_ITEMS_SECTION;
|
||||
break;
|
||||
}
|
||||
case NUMBER_OF_ITEMS_SECTION: {
|
||||
if (words.size() != 1) {
|
||||
ReportError(line);
|
||||
return;
|
||||
}
|
||||
num_declared_items_ = strtoint32(words[0]);
|
||||
load_status_ = ITEM_SECTION;
|
||||
break;
|
||||
}
|
||||
case ITEM_SECTION: {
|
||||
if (words.size() != num_resources_ + 1) {
|
||||
ReportError(line);
|
||||
return;
|
||||
}
|
||||
Item* const item = vbp_.add_item();
|
||||
for (int i = 0; i < num_resources_; ++i) {
|
||||
item->add_resource_usage(strtoint64(words[i]));
|
||||
}
|
||||
item->set_num_copies(strtoint32(words[num_resources_]));
|
||||
item->set_max_number_of_copies_per_bin(item->num_copies());
|
||||
break;
|
||||
}
|
||||
case ERROR_FOUND: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int VbpParser::strtoint32(const std::string& word) {
|
||||
int result;
|
||||
CHECK(absl::SimpleAtoi(word, &result));
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t VbpParser::strtoint64(const std::string& word) {
|
||||
int64_t result;
|
||||
CHECK(absl::SimpleAtoi(word, &result));
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace vbp
|
||||
} // namespace data
|
||||
} // namespace operations_research
|
||||
71
ortools/data/vector_bin_packing_parser.h
Normal file
71
ortools/data/vector_bin_packing_parser.h
Normal file
@@ -0,0 +1,71 @@
|
||||
// Copyright 2010-2018 Google LLC
|
||||
// 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.
|
||||
|
||||
// Parses vector packing data files, and creates a VectorBinPackingProblem
|
||||
//
|
||||
// The supported file formats are:
|
||||
// - vector packing solver: (.vbp files)
|
||||
// http://www.dcc.fc.up.pt/~fdabrandao/Vector_Packing_Solver
|
||||
|
||||
#ifndef OR_TOOLS_DATA_VECTOR_BIN_PACKING_PARSER_H_
|
||||
#define OR_TOOLS_DATA_VECTOR_BIN_PACKING_PARSER_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "ortools/base/integral_types.h"
|
||||
#include "ortools/data/vector_bin_packing.pb.h"
|
||||
|
||||
namespace operations_research {
|
||||
namespace data {
|
||||
namespace vbp {
|
||||
|
||||
class VbpParser {
|
||||
public:
|
||||
// Return true iff there were no error, in which case problem() can be
|
||||
// called to retrieve the parsed problem.
|
||||
bool ParseFile(const std::string& data_filename);
|
||||
|
||||
// We keep the fully qualified name for SWIG.
|
||||
::operations_research::data::vbp::VectorBinPackingProblem problem() const {
|
||||
return vbp_;
|
||||
}
|
||||
|
||||
private:
|
||||
enum LoadStatus {
|
||||
NOT_STARTED,
|
||||
DIMENSION_SECTION,
|
||||
BIN_SECTION,
|
||||
NUMBER_OF_ITEMS_SECTION,
|
||||
ITEM_SECTION,
|
||||
ERROR_FOUND
|
||||
};
|
||||
|
||||
void ProcessLine(const std::string& line);
|
||||
void ReportError(const std::string& line);
|
||||
int strtoint32(const std::string& word);
|
||||
int64_t strtoint64(const std::string& word);
|
||||
|
||||
LoadStatus load_status_ = NOT_STARTED;
|
||||
int num_declared_items_ = -1;
|
||||
int num_resources_ = -1;
|
||||
|
||||
VectorBinPackingProblem vbp_;
|
||||
};
|
||||
|
||||
} // namespace vbp
|
||||
} // namespace data
|
||||
} // namespace operations_research
|
||||
|
||||
#endif // OR_TOOLS_DATA_VECTOR_BIN_PACKING_PARSER_H_
|
||||
Reference in New Issue
Block a user