Files
ortools-clone/documentation/tutorials/cplusplus/routing_common/routing_common.h
nikolaj.van.omme@gmail.com 7fc4c48e28 Doc automatic update
2015-02-10 19:24:05 +00:00

233 lines
6.5 KiB
C++

// Copyright 2011-2014 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.
//
//
// Common routing stuff.
#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_COMMON_H
#define OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_COMMON_H
#include <string>
#include <fstream>
#include <iostream>
#include <sstream>
#include <limits>
#include "base/random.h"
#include "constraint_solver/routing.h"
#include "routing_common/routing_common_flags.h"
#include "common/IO_helpers.h"
#include "common/constants.h"
namespace operations_research {
// Simple struct to contain points in the plane or in the space.
struct Point {
Point(const double x_, const double y_, const double z_ = 0.0):
x(x_), y(y_), z(z_){}
Point(): x(-1.0), y(-1.0), z(-1.0){}
double x;
double y;
double z;
};
// Simple container class to hold cost on arcs of a complete graph.
// This class doesn't compute the distances but only stores them.
// IsCreated(): the cost/distance matrix exists;
// IsInstanciated(): the matrix is filled.
//
// Distances/costs can be symetric or not.
class CompleteGraphArcCost {
public:
explicit CompleteGraphArcCost(int32 size = 0): size_(size), is_created_(false), is_instanciated_(false), is_symmetric_(false),
min_cost_(kPostiveInfinityInt64), max_cost_(-1) {
if (size_ > 0) {
CreateMatrix(size_);
}
}
int32 Size() const {
return size_;
}
void Create(int32 size) {
CHECK(!IsCreated()) << "Matrix already created!";
size_ = size;
CreateMatrix(size);
}
bool IsCreated() const {
return is_created_;
}
bool IsInstanciated() const {
return is_instanciated_;
}
void SetIsInstanciated(const bool instanciated = true) {
CHECK(IsCreated()) << "Instance is not created!";
is_instanciated_ = instanciated;
ComputeExtremeDistance();
ComputeIsSymmetric();
}
int64 Cost(RoutingModel::NodeIndex from,
RoutingModel::NodeIndex to) const {
return matrix_[MatrixIndex(from, to)];
}
int64& Cost(RoutingModel::NodeIndex from,
RoutingModel::NodeIndex to) {
return matrix_[MatrixIndex(from, to)];
}
int64 MaxCost() const {
CHECK(IsInstanciated()) << "Instance is not instanciated!";
return max_cost_;
}
int64 MinCost() const {
CHECK(IsInstanciated()) << "Instance is not instanciated!";
return min_cost_;
}
bool IsSymmetric() const {
CHECK(IsInstanciated()) << "Instance is not instanciated!";
return is_symmetric_;
}
void Print(std::ostream & out, const bool label = false, const int width = FLAGS_width_size) const;
private:
int64 MatrixIndex(RoutingModel::NodeIndex from,
RoutingModel::NodeIndex to) const {
return (from * size_ + to).value();
}
void CreateMatrix(const int size) {
CHECK_GT(size, 2) << "Size for matrix non consistent.";
int64 * p_array = NULL;
try {
p_array = new int64 [size_ * size_];
} catch (std::bad_alloc & e) {
p_array = NULL;
LOG(FATAL) << "Problems allocating ressource. Try with a smaller size.";
}
CHECK_NE(p_array, NULL) << "Not enough resources to create matrix";
matrix_.reset(p_array);
is_created_ = true;
}
void UpdateExtremeDistance(int64 dist) {
if (min_cost_ > dist) { min_cost_ = dist;}
if (max_cost_ < dist) { max_cost_ = dist;}
}
void ComputeExtremeDistance() {
CHECK(IsInstanciated()) << "Instance is not instanciated!";
min_cost_ = kPostiveInfinityInt64;
max_cost_ = -1;
for (RoutingModel::NodeIndex i(0); i < size_; ++i) {
for (RoutingModel::NodeIndex j(0); j < size_; ++j) {
if (i == j) {continue;}
UpdateExtremeDistance(Cost(i,j));
}
}
}
bool ComputeIsSymmetric() {
CHECK(IsInstanciated()) << "Instance is not instanciated!";
for (RoutingModel::NodeIndex i(0); i < Size(); ++i) {
for (RoutingModel::NodeIndex j(i + 1); j < Size(); ++j) {
if (matrix_[MatrixIndex(i,j)] != matrix_[MatrixIndex(j,i)]) {
return false;
}
}
}
return true;
}
int32 size_;
//scoped_array<int64> matrix_;
std::unique_ptr<int64[]> matrix_;
bool is_created_;
bool is_instanciated_;
bool is_symmetric_;
int64 min_cost_;
int64 max_cost_;
};
void CompleteGraphArcCost::Print(std::ostream& out, const bool label, const int width) const {
CHECK(IsInstanciated()) << "Instance is not instanciated!";
// titel
out.width(width);
if (label) {
out << std::left << " ";
for (RoutingModel::NodeIndex to = RoutingModel::kFirstNode; to < size_; ++to) {
out.width(width);
out << std::right << to.value() + 1 ;
}
out << std::endl;
}
// fill
for (RoutingModel::NodeIndex from = RoutingModel::kFirstNode; from < size_; ++from) {
if (label) {
out.width(width);
out << std::right << from.value() + 1;
}
for (RoutingModel::NodeIndex to = RoutingModel::kFirstNode; to < size_; ++to) {
out.width(width);
out << std::right << matrix_[MatrixIndex(from, to)];
}
out << std::endl;
}
}
struct BoundingBox {
BoundingBox(): min_x(std::numeric_limits<double>::max()),
max_x(std::numeric_limits<double>::min()),
min_y(std::numeric_limits<double>::max()),
max_y(std::numeric_limits<double>::min()),
min_z(std::numeric_limits<double>::max()),
max_z(std::numeric_limits<double>::min()) {}
BoundingBox(double min_x_, double max_x_, double min_y_, double max_y_, double min_z_, double max_z_):
min_x(min_x_), max_x(max_x_), min_y(min_y_), max_y(max_y_), min_z(min_z_), max_z(max_z_) {}
void Update(Point p) {
if (p.x < min_x) {min_x = p.x;}
if (p.x > max_x) {max_x = p.x;}
if (p.y < min_y) {min_y = p.y;}
if (p.y > max_y) {max_y = p.y;}
if (p.z < min_z) {min_z = p.z;}
if (p.z > max_z) {max_z = p.z;}
}
// Bounding box
double min_x;
double max_x;
double min_y;
double max_y;
double min_z;
double max_z;
};
} // namespace operations_research
#endif // OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_COMMON_H