diff --git a/documentation/changes_list.txt b/documentation/changes_list.txt
index 685f34edf2..b3dab0892e 100644
--- a/documentation/changes_list.txt
+++ b/documentation/changes_list.txt
@@ -1,4 +1,10 @@
+v.0.2.11: (2014-09-09 13:57:19)
+-------------------------------
+* Quick update of the tutorial codes in chapter 10 and one file for chap13: code adapted to the new API; the manual is NOT up to date!
+* Tutorial code for common and routing_common added.
+
+
v.0.2.10: (2014-09-04 16:09:13)
-------------------------------
* Quick update of the tutorial codes in chapters 2, 3 and 6: code adapted to the new API; the manual is NOT up to date!
diff --git a/documentation/documentation_hub.html b/documentation/documentation_hub.html
index fd9637c7e9..7a6e1d4855 100644
--- a/documentation/documentation_hub.html
+++ b/documentation/documentation_hub.html
@@ -84,10 +84,11 @@ Thank you very much.
What's new?
Here is a little summary:
-v.0.2.10: (2014-09-04 16:09:13)
+v.0.2.11: (2014-09-09 13:57:19)
-------------------------------
-* Quick update of the tutorial codes in chapters 2, 3 and 6: code adapted to the new API; the manual is NOT up to date!
-* Licenses updated;
+* Quick update of the tutorial codes in chapter 10 and one file for chap13: code adapted to the new API; the manual is NOT up to date!
+* Tutorial code for common and routing_common added.
+
This is the list of changes.
Legend:
@@ -341,6 +342,12 @@ to use these makefiles.
You can also overwrite this variable when invoking make:
make OR_TOOLS_TOP=/home/username/or-tools-read-only
+
+
If you want to play with the routing examples, the TUTORIAL variable must point to the C++ tutorial directory. By default, it is defined as:
+TUTORIAL=($OR_TOOLS_TOP)/documentation/tutorials/cplusplus
+If you deploy the tutorial examples somewhere else, update this variable accordingly.
+
+
If you want to compile all examples:
make all
@@ -354,11 +361,11 @@ You can also overwrite this variable when invoking make:
-To delete the created files:
+To delete all generated files:
make local_clean
-Don't use
+Don't use
make clean
-as you will erase the generated files for the whole library!
+as you will erase the generated files for the whole library!
@@ -394,7 +401,7 @@ as you will erase the generated files for the whole library!
-- C++: chapters 2, 3 and 6.
+- C++: chapters 2, 3, 6 and almost all of chapter 10.
- Python: chapter 2.
- Java: chapter 2.
- C#: chapter 2.
diff --git a/documentation/tutorials/cplusplus/chap10/A-n32-k5.vrp b/documentation/tutorials/cplusplus/chap10/A-n32-k5.vrp
new file mode 100644
index 0000000000..9cb5cd540b
--- /dev/null
+++ b/documentation/tutorials/cplusplus/chap10/A-n32-k5.vrp
@@ -0,0 +1,76 @@
+NAME : A-n32-k5
+COMMENT : (Augerat et al, Min no of trucks: 5, Optimal value: 784)
+TYPE : CVRP
+DIMENSION : 32
+EDGE_WEIGHT_TYPE : EUC_2D
+CAPACITY : 100
+NODE_COORD_SECTION
+ 1 82 76
+ 2 96 44
+ 3 50 5
+ 4 49 8
+ 5 13 7
+ 6 29 89
+ 7 58 30
+ 8 84 39
+ 9 14 24
+ 10 2 39
+ 11 3 82
+ 12 5 10
+ 13 98 52
+ 14 84 25
+ 15 61 59
+ 16 1 65
+ 17 88 51
+ 18 91 2
+ 19 19 32
+ 20 93 3
+ 21 50 93
+ 22 98 14
+ 23 5 42
+ 24 42 9
+ 25 61 62
+ 26 9 97
+ 27 80 55
+ 28 57 69
+ 29 23 15
+ 30 20 70
+ 31 85 60
+ 32 98 5
+DEMAND_SECTION
+1 0
+2 19
+3 21
+4 6
+5 19
+6 7
+7 12
+8 16
+9 6
+10 16
+11 8
+12 14
+13 21
+14 16
+15 3
+16 22
+17 18
+18 19
+19 1
+20 24
+21 8
+22 12
+23 4
+24 8
+25 24
+26 24
+27 2
+28 20
+29 15
+30 2
+31 14
+32 9
+DEPOT_SECTION
+ 1
+ -1
+EOF
diff --git a/documentation/tutorials/cplusplus/chap10/Makefile b/documentation/tutorials/cplusplus/chap10/Makefile
new file mode 100644
index 0000000000..4c14c95ce8
--- /dev/null
+++ b/documentation/tutorials/cplusplus/chap10/Makefile
@@ -0,0 +1,73 @@
+OR_TOOLS_TOP=/home/nikolaj/Documents/WORK/Google/or-tools-read-only
+OR_TOOLS_SOURCES=$(OR_TOOLS_TOP)/src
+
+TUTORIAL=/home/nikolaj/Documents/WORK/Google/OR_TOOLS_DOC/SOURCES/TUTORIALS/cplusplus
+
+SOURCES= cvrp_data_generator.cc check_vrp_solution.cc check_cvrp_solution.cc vrp cvrp_basic \
+ vrp_solution_to_epix cvrp_solution_to_epix
+
+OBJECTS=$(SOURCES:.cc=.o)
+
+EXE=$(SOURCES:.cc=)
+
+include $(OR_TOOLS_TOP)/Makefile
+
+.PHONY: all local_clean
+
+all: $(EXE)
+
+cvrp_data_generator.o: cvrp_data_generator.cc $(OR_TOOLS_SOURCES)/constraint_solver/routing.h \
+ $(TUTORIAL)/routing_common/routing_common.h $(TUTORIAL)/routing_common/routing_data_generator.h cvrp_data_generator.h
+ $(CCC) $(CFLAGS) -I $(TUTORIAL) -c cvrp_data_generator.cc -o cvrp_data_generator.o
+
+cvrp_data_generator: $(ROUTING_DEPS) cvrp_data_generator.o
+ $(CCC) $(CFLAGS) cvrp_data_generator.o $(DYNAMIC_ROUTING_LNK) $(DYNAMIC_LD_FLAGS) -o cvrp_data_generator
+
+check_vrp_solution.o: check_vrp_solution.cc $(OR_TOOLS_SOURCES)/constraint_solver/routing.h \
+ $(TUTORIAL)/routing_common/routing_common.h $(TUTORIAL)/routing_common/routing_data_generator.h cvrp_solution.h
+ $(CCC) $(CFLAGS) -I $(TUTORIAL) -c check_vrp_solution.cc -o check_vrp_solution.o
+
+check_vrp_solution: $(ROUTING_DEPS) check_vrp_solution.o
+ $(CCC) $(CFLAGS) check_vrp_solution.o $(DYNAMIC_ROUTING_LNK) $(DYNAMIC_LD_FLAGS) -o check_vrp_solution
+
+check_cvrp_solution.o: check_cvrp_solution.cc $(OR_TOOLS_SOURCES)/constraint_solver/routing.h \
+ $(TUTORIAL)/routing_common/routing_common.h $(TUTORIAL)/routing_common/routing_data_generator.h cvrp_solution.h
+ $(CCC) $(CFLAGS) -I $(TUTORIAL) -c check_cvrp_solution.cc -o check_cvrp_solution.o
+
+check_cvrp_solution: $(ROUTING_DEPS) check_cvrp_solution.o
+ $(CCC) $(CFLAGS) check_cvrp_solution.o $(DYNAMIC_ROUTING_LNK) $(DYNAMIC_LD_FLAGS) -o check_cvrp_solution
+
+vrp.o: vrp.cc $(TUTORIAL)/routing_common/routing_common.h $(TUTORIAL)/routing_common/routing_data.h \
+ $(TUTORIAL)/routing_common/routing_solution.h cvrp_data.h cvrp_solution.h
+ $(CCC) $(CFLAGS) -I $(TUTORIAL) -c vrp.cc -o vrp.o
+
+vrp: $(ROUTING_DEPS) vrp.o
+ $(CCC) $(CFLAGS) vrp.o $(DYNAMIC_ROUTING_LNK) $(DYNAMIC_LD_FLAGS) -o vrp
+
+cvrp_basic.o: cvrp_basic.cc $(OR_TOOLS_SOURCES)/constraint_solver/routing.h \
+ $(TUTORIAL)/routing_common/tsplib_reader.h
+ $(CCC) $(CFLAGS) -I $(TUTORIAL) -c cvrp_basic.cc -o cvrp_basic.o
+
+cvrp_basic: $(ROUTING_DEPS) cvrp_basic.o
+ $(CCC) $(CFLAGS) cvrp_basic.o $(DYNAMIC_ROUTING_LNK) $(DYNAMIC_LD_FLAGS) -o cvrp_basic
+
+vrp_solution_to_epix.o: vrp_solution_to_epix.cc $(TUTORIAL)/routing_common/routing_common.h $(TUTORIAL)/routing_common/routing_data.h \
+ $(TUTORIAL)/routing_common/routing_solution.h $(TUTORIAL)/routing_common/routing_epix_helper.h cvrp_data.h cvrp_solution.h \
+ cvrp_epix_data.h
+ $(CCC) $(CFLAGS) -I $(TUTORIAL) -c vrp_solution_to_epix.cc -o vrp_solution_to_epix.o
+
+vrp_solution_to_epix: $(ROUTING_DEPS) vrp_solution_to_epix.o
+ $(CCC) $(CFLAGS) vrp_solution_to_epix.o $(DYNAMIC_ROUTING_LNK) $(DYNAMIC_LD_FLAGS) -o vrp_solution_to_epix
+
+cvrp_solution_to_epix.o: cvrp_solution_to_epix.cc $(TUTORIAL)/routing_common/routing_common.h $(TUTORIAL)/routing_common/routing_data.h \
+ $(TUTORIAL)/routing_common/routing_solution.h $(TUTORIAL)/routing_common/routing_epix_helper.h cvrp_data.h cvrp_solution.h \
+ cvrp_epix_data.h
+ $(CCC) $(CFLAGS) -I $(TUTORIAL) -c cvrp_solution_to_epix.cc -o cvrp_solution_to_epix.o
+
+cvrp_solution_to_epix: $(ROUTING_DEPS) cvrp_solution_to_epix.o
+ $(CCC) $(CFLAGS) cvrp_solution_to_epix.o $(DYNAMIC_ROUTING_LNK) $(DYNAMIC_LD_FLAGS) -o cvrp_solution_to_epix
+
+
+local_clean:
+ rm $(OBJECTS) $(EXE)
+
diff --git a/documentation/tutorials/cplusplus/chap10/check_cvrp_solution.cc b/documentation/tutorials/cplusplus/chap10/check_cvrp_solution.cc
new file mode 100644
index 0000000000..6c9c7c4107
--- /dev/null
+++ b/documentation/tutorials/cplusplus/chap10/check_cvrp_solution.cc
@@ -0,0 +1,52 @@
+// 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.
+//
+//
+// Simple program to test a CVRP solution.
+#include
+
+#include "base/commandlineflags.h"
+
+#include "cvrp_data.h"
+#include "cvrp_solution.h"
+#include "routing_common/tsplib_reader.h"
+
+int main(int argc, char **argv) {
+ std::string usage("Checks the feasibility of a CVRP solution.\n"
+ "See Google or-tools tutorials\n"
+ "Sample usage:\n\n");
+ usage += argv[0];
+ usage += " -instance_file= -solution_file=<(C)VRP solution>\n";
+
+ google::SetUsageMessage(usage);
+ google::ParseCommandLineFlags(&argc, &argv, true);
+
+ if (FLAGS_instance_file != "" && FLAGS_solution_file != "") {
+ operations_research::TSPLIBReader tsp_data_reader(FLAGS_instance_file);
+ operations_research::CVRPData cvrp_data(tsp_data_reader);
+ operations_research::CVRPSolution cvrp_sol(cvrp_data, FLAGS_solution_file);
+ if (FLAGS_distance_file != "") {
+ cvrp_data.WriteDistanceMatrix(FLAGS_distance_file);
+ }
+ if (cvrp_sol.IsFeasibleSolution()) {
+ LG << "Solution is feasible!";
+ LG << "Obj value = " << cvrp_sol.ComputeObjectiveValue();
+ } else {
+ LG << "Solution is NOT feasible...";
+ }
+ } else {
+ std::cout << google::ProgramUsage();
+ exit(-1);
+ }
+ return 0;
+}
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/chap10/check_vrp_solution.cc b/documentation/tutorials/cplusplus/chap10/check_vrp_solution.cc
new file mode 100644
index 0000000000..e15f0e85bf
--- /dev/null
+++ b/documentation/tutorials/cplusplus/chap10/check_vrp_solution.cc
@@ -0,0 +1,56 @@
+// 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.
+//
+//
+// Simple program to test a VRP solution.
+#include
+
+#include "base/commandlineflags.h"
+
+#include "cvrp_data.h"
+#include "cvrp_solution.h"
+#include "routing_common/tsplib_reader.h"
+
+
+int main(int argc, char **argv) {
+ std::string usage("Checks the feasibility of a VRP solution.\n"
+ "See Google or-tools tutorials\n"
+ "Sample usage:\n\n");
+ usage += argv[0];
+ usage += " -instance_file= -solution_file=<(C)VRP solution>\n";
+
+ google::SetUsageMessage(usage);
+ google::ParseCommandLineFlags(&argc, &argv, true);
+
+ if (FLAGS_instance_file != "" && FLAGS_solution_file != "") {
+ operations_research::TSPLIBReader tsp_data_reader(FLAGS_instance_file);
+ operations_research::CVRPData cvrp_data(tsp_data_reader);
+ operations_research::CVRPSolution cvrp_sol(cvrp_data, FLAGS_solution_file);
+ if (FLAGS_distance_file != "") {
+ cvrp_data.WriteDistanceMatrix(FLAGS_distance_file);
+ }
+ if (cvrp_sol.IsSolution()) {
+ LG << "Solution is feasible!";
+ LG << "Obj value = " << cvrp_sol.ComputeObjectiveValue();
+ if (cvrp_sol.IsFeasibleSolution()) {
+ LG << "Solution is even CVRP feasible!!!";
+ }
+ } else {
+ LG << "Solution is NOT feasible...";
+ }
+ } else {
+ std::cout << google::ProgramUsage();
+ exit(-1);
+ }
+ return 0;
+}
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/chap10/cvrp_basic.cc b/documentation/tutorials/cplusplus/chap10/cvrp_basic.cc
new file mode 100644
index 0000000000..76a3fff76f
--- /dev/null
+++ b/documentation/tutorials/cplusplus/chap10/cvrp_basic.cc
@@ -0,0 +1,141 @@
+// 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.
+//
+//
+// Simple program to solve the CVRP with Local Search in or-tools.
+
+#include
+#include
+
+#include "base/commandlineflags.h"
+#include "constraint_solver/routing.h"
+#include "base/join.h"
+#include "base/timer.h"
+
+#include "constraint_solver/routing.h"
+
+#include "common/limits.h"
+
+#include "cvrp_data.h"
+#include "cvrp_solution.h"
+#include "routing_common/tsplib_reader.h"
+
+DEFINE_int32(depot, 1, "The starting node of the tour.");
+DEFINE_string(initial_solution_file, "", "Input file with a valid feasible solution.");
+DEFINE_int32(time_limit_in_ms, 0, "Time limit in ms. 0 means no limit.");
+DEFINE_int32(no_solution_improvement_limit, 200, "Number of allowed solutions without improving the objective value.");
+
+namespace operations_research {
+
+void CVRPBasicSolver (const CVRPData & data) {
+
+ const int size = data.Size();
+ const int64 capacity = data.Capacity();
+
+ CHECK_GT(FLAGS_number_vehicles, 0) << "We need at least one vehicle!";
+ // Little check to see if we have enough vehicles
+ CHECK_GT(capacity, data.TotalDemand()/FLAGS_number_vehicles) << "No enough vehicles to cover all the demands";
+ RoutingModel routing(size, FLAGS_number_vehicles);
+ routing.SetCost(NewPermanentCallback(&data, &CVRPData::Distance));
+
+ // Disabling Large Neighborhood Search, comment out to activate it.
+ //routing.SetCommandLineOption("routing_no_lns", "true");
+
+ if (FLAGS_time_limit_in_ms > 0) {
+ routing.UpdateTimeLimit(FLAGS_time_limit_in_ms);
+ }
+
+ // Setting depot
+ CHECK_GT(FLAGS_depot, 0) << " Because we use the" << " TSPLIB convention, the depot id must be > 0";
+ RoutingModel::NodeIndex depot(FLAGS_depot -1);
+ routing.SetDepot(depot);
+
+ // add capacities constraints
+ std::vector demands(size);
+ for (RoutingModel::NodeIndex i(RoutingModel::kFirstNode); i < size; ++i) {
+ demands[i.value()] = data.Demand(i);
+ }
+ routing.AddVectorDimension(&demands[0], capacity, true, "Demand");
+
+ routing.CloseModel();
+
+ // Use initial solution if provided
+ Assignment * initial_sol = NULL;
+ if (FLAGS_initial_solution_file != "") {
+ initial_sol = routing.solver()->MakeAssignment();//needed by RoutesToAssignment but actually doesn't do much... to detail
+ CVRPSolution cvrp_init_sol(data, FLAGS_initial_solution_file);
+
+ routing.RoutesToAssignment(cvrp_init_sol.Routes(), true, true, initial_sol);
+
+ if (routing.solver()->CheckAssignment(initial_sol)) {// just in case and to fill the complementary variables
+ CVRPSolution temp_sol(data, &routing, initial_sol);
+ LG << "Initial solution provided is feasible with obj = " << temp_sol.ComputeObjectiveValue();//
+ } else {
+ LG << "Initial solution provided is NOT feasible... exit!";
+ return;
+ }
+ }
+
+ NoImprovementLimit * const no_improvement_limit = MakeNoImprovementLimit(routing.solver(), FLAGS_no_solution_improvement_limit);
+
+ SearchLimit * const ctrl_break = MakeCatchCTRLBreakLimit(routing.solver());
+ routing.AddSearchMonitor(ctrl_break);
+ const Assignment* solution = routing.Solve(initial_sol);// if initial_sol == NULL, solves from scratch
+
+ // INSPECT SOLUTION
+ if (solution != NULL) {
+ CVRPSolution cvrp_sol(data, &routing, solution);
+ cvrp_sol.SetName(StrCat("Solution for instance ", data.Name(), " computed by vrp.cc"));
+ // test solution
+ if (!cvrp_sol.IsFeasibleSolution()) {
+ LOG(ERROR) << "Solution is NOT feasible!";
+ } else {
+ LG << "Solution is feasible and has an obj value of " << cvrp_sol.ComputeObjectiveValue();
+ // SAVE SOLUTION IN CVRP FORMAT
+ if (FLAGS_solution_file != "") {
+ cvrp_sol.Write(FLAGS_solution_file);
+ } else {
+ cvrp_sol.Print(std::cout);
+ }
+ }
+
+ } else {
+ LG << "No solution found.";
+ }
+
+} // void VRPSolver (CVRPData & data)
+
+
+} // namespace operations_research
+
+
+int main(int argc, char **argv) {
+ std::string usage("Computes a simple CVRP.\n"
+ "See Google or-tools tutorials\n"
+ "Sample usage:\n\n");
+ usage += argv[0];
+ usage += " -instance_file=\n";
+
+ google::SetUsageMessage(usage);
+ google::ParseCommandLineFlags(&argc, &argv, true);
+
+ if (FLAGS_instance_file == "") {
+ std::cout << google::ProgramUsage();
+ exit(-1);
+ }
+ operations_research::TSPLIBReader tsplib_reader(FLAGS_instance_file);
+ operations_research::CVRPData cvrp_data(tsplib_reader);
+ operations_research::CVRPBasicSolver(cvrp_data);
+
+ return 0;
+} // main
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/chap10/cvrp_data.h b/documentation/tutorials/cplusplus/chap10/cvrp_data.h
new file mode 100644
index 0000000000..fc6de8b713
--- /dev/null
+++ b/documentation/tutorials/cplusplus/chap10/cvrp_data.h
@@ -0,0 +1,203 @@
+// 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 base for (c)vrp data (instance) classes.
+
+#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_VRP_DATA_H
+#define OR_TOOLS_TUTORIALS_CPLUSPLUS_VRP_DATA_H
+
+#include
+#include
+
+#include "base/bitmap.h"
+#include "base/logging.h"
+#include "base/file.h"
+#include "base/split.h"
+#include "base/filelinereader.h"
+#include "base/join.h"
+#include "base/strtoint.h"
+
+#include "constraint_solver/routing.h"
+
+#include "routing_common/routing_common.h"
+#include "routing_common/routing_data.h"
+#include "routing_common/tsplib_reader.h"
+#include "routing_common/tsplib.h"
+#include "cvrp_data_generator.h"
+
+DECLARE_int32(width_size);
+
+namespace operations_research {
+
+class CVRPData : public RoutingData {
+public:
+ explicit CVRPData(CVRPDataGenerator & g) : RoutingData(g), depot_(g.Depot()), capacity_(g.Capacity()),
+ demands_(Size()),
+ node_coord_type_(g.NodeCoordinateType()),
+ display_data_type_(g.DisplayDataType()),
+ two_dimension_(g.HasDimensionTwo()),
+ total_demand_(0){
+
+ for (RoutingModel::NodeIndex i(RoutingModel::kFirstNode); i < Size(); ++i) {
+ demands_[i.value()] = g.Demand(i);
+ total_demand_ += g.Demand(i);
+ }
+ }
+ explicit CVRPData(const TSPLIBReader & reader) :
+ RoutingData(reader),
+ depot_(reader.Depot()),
+ capacity_(reader.Capacity()),
+ demands_(Size()),
+ node_coord_type_(reader.NodeCoordinateType()),
+ display_data_type_(reader.DisplayDataType()),
+ two_dimension_(reader.HasDimensionTwo()),
+ total_demand_(0) {
+ CHECK(reader.TSPLIBType() == CVRP);
+ for (RoutingModel::NodeIndex i(RoutingModel::kFirstNode); i < Size(); ++i) {
+ demands_[i.value()] = reader.Demand(i);
+ total_demand_ += reader.Demand(i);
+ }
+ if (node_coord_type_ == TWOD_COORDS || node_coord_type_ == THREED_COORDS) {
+ for (RoutingModel::NodeIndex i(RoutingModel::kFirstNode); i < Size(); ++i) {
+ Coordinate(i) = reader.Coordinate(i);
+ }
+ SetHasCoordinates();
+ }
+ if (display_data_type_ == TWOD_DISPLAY) {
+ for (RoutingModel::NodeIndex i(RoutingModel::kFirstNode); i < Size(); ++i) {
+ DisplayCoordinate(i) = reader.DisplayCoordinate(i);
+ }
+ SetHasDisplayCoordinates();
+ }
+ SetRoutingDataInstanciated();
+ }
+
+ void SetDepot(RoutingModel::NodeIndex d) {
+ CheckNodeIsValid(d);
+ depot_ = d;
+ }
+
+
+ RoutingModel::NodeIndex Depot() const {
+ return depot_;
+ }
+
+ void SetDemand(const RoutingModel::NodeIndex i, int64 demand) {
+ CheckNodeIsValid(i);
+ demands_[i.value()] = demand;
+ }
+
+ int64 Demand(const RoutingModel::NodeIndex i) const {
+ CheckNodeIsValid(i);
+ return demands_[i.value()];
+ }
+
+int64 TotalDemand() const {
+ return total_demand_;
+}
+
+ void PrintTSPLIBInstance(std::ostream & out) const;
+
+ void WriteTSPLIBInstance(const std::string & filename) const {
+ WriteToFile writer(this, filename);
+ writer.SetMember(&operations_research::CVRPData::PrintTSPLIBInstance);
+ writer.Run();
+ }
+
+void SetCapacity(int64 capacity) {
+ capacity_ = capacity;
+}
+
+int64 Capacity() const {
+ return capacity_;
+}
+
+ // Helper function
+ int64& SetDistance(RoutingModel::NodeIndex i, RoutingModel::NodeIndex j) {
+ return distances_.Cost(i, j);
+ }
+
+private:
+
+ RoutingModel::NodeIndex depot_;
+ std::vector demands_;
+ int64 total_demand_;
+ TSPLIB_NODE_COORD_TYPE_TYPES_enum node_coord_type_;
+ TSPLIB_DISPLAY_DATA_TYPE_TYPES_enum display_data_type_;
+ bool two_dimension_;
+ int64 capacity_;
+
+};
+
+void CVRPData::PrintTSPLIBInstance(std::ostream& out) const {
+ out << TSPLIB_STATES_KEYWORDS[NAME] << " : " << Name() << std::endl;
+ out << TSPLIB_STATES_KEYWORDS[COMMENT] << " : " << Comment() << std::endl;
+ out << TSPLIB_STATES_KEYWORDS[TYPE] << " : CVRP" << std::endl;
+ out << TSPLIB_STATES_KEYWORDS[DIMENSION] << " : " << Size() << std::endl;
+ out << TSPLIB_STATES_KEYWORDS[EDGE_WEIGHT_TYPE] << " : " << "EXPLICIT" << std::endl;
+ out << TSPLIB_STATES_KEYWORDS[EDGE_WEIGHT_FORMAT] << " : " << "FULL_MATRIX" << std::endl;
+ if (HasCoordinates()) {
+ out << TSPLIB_STATES_KEYWORDS[NODE_COORD_TYPE] << " : " << TSPLIB_NODE_COORD_TYPE_TYPES_KEYWORDS[node_coord_type_] << std::endl;
+ }
+ if (HasDisplayCoordinates()) {
+ out << TSPLIB_STATES_KEYWORDS[DISPLAY_DATA_TYPE] << " : " << TSPLIB_DISPLAY_DATA_TYPE_TYPES_KEYWORDS[display_data_type_] << std::endl;
+ }
+ if (Depot() != RoutingModel::kFirstNode) {
+ out << TSPLIB_STATES_KEYWORDS[DEPOT_SECTION] << std::endl;
+ out << Depot().value() + 1 << std::endl;
+ out << kTSPLIBDelimiter << std::endl;
+ }
+ out << TSPLIB_STATES_KEYWORDS[EDGE_WEIGHT_SECTION] << std::endl;
+ distances_.Print(out);
+ if (HasCoordinates()) {
+ out << TSPLIB_STATES_KEYWORDS[NODE_COORD_SECTION] << std::endl;
+ for (RoutingModel::NodeIndex i(RoutingModel::kFirstNode); i < Size(); ++i) {
+ out.width(FLAGS_width_size);
+ out << std::right << i.value() + 1;
+ out.width(FLAGS_width_size);
+ out << std::right << Coordinate(i).x;
+ out.width(FLAGS_width_size);
+ out << std::right << Coordinate(i).y;
+ if (!two_dimension_) { // 3D
+ out.width(FLAGS_width_size);
+ out << std::right << Coordinate(i).z;
+ }
+ out << std::endl;
+ }
+ }
+ if (HasDisplayCoordinates()) {
+ out << TSPLIB_STATES_KEYWORDS[DISPLAY_DATA_SECTION] << std::endl;
+ for (RoutingModel::NodeIndex i(RoutingModel::kFirstNode); i < Size(); ++i) {
+ out.width(FLAGS_width_size);
+ out << std::right << i.value() + 1;
+ out.width(FLAGS_width_size + 4);
+ out << std::setprecision(2) << std::fixed << std::right << DisplayCoordinate(i).x;
+ out.width(FLAGS_width_size + 4);
+ out << std::right << DisplayCoordinate(i).y << std::endl;
+ }
+ }
+ out << TSPLIB_STATES_KEYWORDS[DEMAND_SECTION] << std::endl;
+ for (RoutingModel::NodeIndex i(RoutingModel::kFirstNode); i < Size(); ++i) {
+ out.width(FLAGS_width_size);
+ out << std::right << i.value() + 1;
+ out.width(FLAGS_width_size);
+ out << std::right << Demand(i) << std::endl;
+ }
+ out << kTSPLIBEndFileDelimiter << std::endl;
+}
+
+} // namespace operations_research
+
+
+#endif // OR_TOOLS_TUTORIALS_CPLUSPLUS_VRP_DATA_H
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/chap10/cvrp_data_generator.cc b/documentation/tutorials/cplusplus/chap10/cvrp_data_generator.cc
new file mode 100644
index 0000000000..bfa0a23790
--- /dev/null
+++ b/documentation/tutorials/cplusplus/chap10/cvrp_data_generator.cc
@@ -0,0 +1,48 @@
+// 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.
+//
+//
+// Simple CVRP instance generator.
+
+#include "base/commandlineflags.h"
+
+#include "cvrp_data_generator.h"
+#include "cvrp_data.h"
+
+DEFINE_int32(depot, 1, "Depot of the CVRP instance. Must be greater of equal to 1.");
+
+int main(int argc, char **argv) {
+
+ google::ParseCommandLineFlags(&argc, &argv, true);
+ google::SetUsageMessage(operations_research::GeneratorUsage(argv[0], "CVRP"));
+
+ if (FLAGS_instance_name != "" && FLAGS_instance_size > 2) {
+ operations_research::CVRPDataGenerator cvrp_data_generator(FLAGS_instance_name, FLAGS_instance_size);
+ CHECK_GE(FLAGS_depot, 1) << "Because we use the TSPLIB format, the depot must be greater or equal to 1.";
+ CHECK_LE(FLAGS_depot, FLAGS_instance_size) << "The depot must be in range 1-" << FLAGS_instance_size << ".";
+ cvrp_data_generator.SetDepot(operations_research::RoutingModel::NodeIndex(FLAGS_depot - 1));
+ operations_research::CVRPData cvrp_data(cvrp_data_generator);
+ if (FLAGS_distance_file != "") {
+ cvrp_data.WriteDistanceMatrix(FLAGS_distance_file);
+ }
+ if (FLAGS_instance_file == "") {
+ cvrp_data.PrintTSPLIBInstance(std::cout);
+ } else {
+ cvrp_data.WriteTSPLIBInstance(FLAGS_instance_file);
+ }
+ } else {
+ std::cout << google::ProgramUsage();
+ exit(-1);
+ }
+ return 0;
+}
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/chap10/cvrp_data_generator.h b/documentation/tutorials/cplusplus/chap10/cvrp_data_generator.h
new file mode 100644
index 0000000000..910eac76ea
--- /dev/null
+++ b/documentation/tutorials/cplusplus/chap10/cvrp_data_generator.h
@@ -0,0 +1,147 @@
+// 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.
+//
+//
+// Very basic CVRPDataGenerator class.
+//
+// The demands are created by constructing a feasible solution.
+// The capacity if FULLY used on each route. i.e. the sum of all demands
+// along a route is equal to FLAGS_capacity.
+// A node can have a zero capacity. If you want to force each node to
+// have a capacity of at least 1, set FLAGS_allow_zero_capacity to false.
+//
+// We don't consider min and max capacities.
+
+#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_CVRP_GENERATOR_H
+#define OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_CVRP_GENERATOR_H
+
+#include "base/commandlineflags.h"
+#include "routing_common/routing_data_generator.h"
+#include "routing_common/tsplib.h"
+
+DEFINE_int32(number_vehicles, 2, "Number of vehicles.");
+DEFINE_int64(capacity, 100, "Capacity of all vehicles.");
+
+DEFINE_bool(allow_zero_capacity, true, "Allow node with zero capacity?");
+
+namespace operations_research {
+
+class CVRPDataGenerator : public RoutingDataGenerator {
+public:
+ CVRPDataGenerator(std::string instance_name, int32 size, std::string problem_name = "CVRP") : RoutingDataGenerator(problem_name, instance_name, size),
+ comment_("Generated by VRPDataGenerator."), capacity_corrector_(FLAGS_allow_zero_capacity ? 0 : 1), capacity_(FLAGS_capacity) {
+ CreateFeasibleSolution();
+ }
+
+ std::string Comment() const {
+ return comment_;
+ }
+
+ void SetComment(const std::string comment) {
+ comment_ = comment;
+ }
+
+ RoutingModel::NodeIndex Depot() const {
+ return depot_;
+ }
+
+ void SetDepot(const RoutingModel::NodeIndex d) {
+ depot_ = d;
+ }
+
+int64 Capacity() const {
+ return capacity_;
+}
+
+ int64 Demand(const RoutingModel::NodeIndex i) const {
+ return demands_[i.value()];
+ }
+
+ TSPLIB_NODE_COORD_TYPE_TYPES_enum NodeCoordinateType() const {
+ return TWOD_COORDS;
+ }
+
+ TSPLIB_DISPLAY_DATA_TYPE_TYPES_enum DisplayDataType() const {
+ return COORD_DISPLAY;
+ }
+
+ bool HasDimensionTwo() const {
+ return true;
+ }
+private:
+ void CreateFeasibleSolution() {
+ // first: shuffle nodes
+ std::vector nodes(Size());
+ for (RoutingModel::NodeIndex i(0); i < Size(); ++i) {
+ nodes[i.value()] = i;
+ }
+ // 0 must be the depot
+ std::random_shuffle(nodes.begin() + 1, nodes.end(), randomizer_);
+
+ // second: distribute nodes into routes of random length
+ sol_.resize(Size());
+ int number_of_nodes = 0;
+ int total_number_of_used_nodes = 0;
+ VLOG(1) << "Optimal solution used:\n";
+ for (int i = 0; i < FLAGS_number_vehicles; ++i) {
+ if (i == FLAGS_number_vehicles - 1) { // add the rest
+ number_of_nodes = Size() - 1 - total_number_of_used_nodes;
+ } else { // add random number of nodes
+ number_of_nodes = randomizer_.Uniform(Size() - 1 - total_number_of_used_nodes - FLAGS_number_vehicles + i) + 1;
+ }
+ sol_[i].resize(number_of_nodes);
+ VLOG(1) << "Vehicle: " << i;
+ for (int j = 0; j < number_of_nodes; ++j) {
+ sol_[i][j] = nodes[total_number_of_used_nodes + j + 1];
+ VLOG(1) << sol_[i][j] << " - ";
+ }
+ VLOG(1) << std::endl;
+ total_number_of_used_nodes += number_of_nodes;
+ }
+
+ // third: allocate the capacity for each route
+ demands_.resize(Size());
+ demands_[0] = 0;
+ int64 total_capacity_used = 0;
+ int64 total_nodes_with_capacity = 0;
+ int64 capacity = 0;
+ for (int i = 0; i < FLAGS_number_vehicles; ++i) {
+
+ number_of_nodes = sol_[i].size();
+ total_capacity_used = 0;
+ for (int j = 0; j < number_of_nodes; ++j) {
+ if (j == number_of_nodes - 1) { // add the rest
+ ++total_nodes_with_capacity;
+ capacity = FLAGS_capacity - total_capacity_used;
+ } else { // add random capacity
+ ++total_nodes_with_capacity;
+ capacity = randomizer_.Uniform(FLAGS_capacity - total_capacity_used - number_of_nodes + j - capacity_corrector_
+ - capacity_corrector_ * (Size() - total_nodes_with_capacity)) + capacity_corrector_;
+ }
+ demands_[sol_[i][j].value()] = capacity;
+ total_capacity_used += capacity;
+ }
+ }
+ }
+
+ std::string comment_;
+ RoutingModel::NodeIndex depot_;
+ std::vector > sol_;
+ std::vector demands_;
+ const int64 capacity_;
+ const int capacity_corrector_;
+};
+
+} // namespace operations_research
+
+#endif // OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_CVRP_GENERATOR_H
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/chap10/cvrp_epix_data.h b/documentation/tutorials/cplusplus/chap10/cvrp_epix_data.h
new file mode 100644
index 0000000000..4ad42d1457
--- /dev/null
+++ b/documentation/tutorials/cplusplus/chap10/cvrp_epix_data.h
@@ -0,0 +1,130 @@
+// 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 base to use the epix library to visualize
+// CVRP data (instance) and solutions.
+
+#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_CVRP_EPIX_DATA_H
+#define OR_TOOLS_TUTORIALS_CPLUSPLUS_CVRP_EPIX_DATA_H
+
+#include
+
+#include "routing_common/routing_common.h"
+#include "cvrp_data.h"
+#include "cvrp_solution.h"
+#include "routing_common/routing_epix_helper.h"
+
+namespace operations_research {
+
+class CVRPEpixData {
+public:
+ explicit CVRPEpixData(const CVRPData & data): data_(data) {}
+ void PrintInstance(std::ostream & out) const;
+ void WriteInstance(const std::string & filename) const;
+ void PrintSolution(std::ostream & out, const CVRPSolution & sol) const;
+ void WriteSolution(const std::string & filename, const CVRPSolution & sol) const;
+private:
+ const CVRPData & data_;
+};
+
+void CVRPEpixData::PrintInstance(std::ostream& out) const {
+ CHECK(data_.HasCoordinates());
+ PrintEpixBeginFile(out);
+ PrintEpixPreamble(out);
+ PrintEpixBoundingBox(out, data_.RawBoundingBox());
+
+ PrintEpixNewLine(out);
+ PrintEpixComment(out, "Points:");
+
+ for (RoutingModel::NodeIndex i(0); i < data_.Size(); ++i) {
+ Point p = data_.Coordinate(i);
+ PrintEpixPoint(out, p, i);
+ }
+
+ PrintEpixBeginFigure(out);
+ PrintEpixDrawMultiplePoints(out, data_.Size());
+ PrintEpixDepot(out, data_.Depot());
+
+ PrintEpixEndFigure(out);
+
+ PrintEpixEndFile(out);
+}
+
+void CVRPEpixData::WriteInstance(const std::string& filename) const {
+ WriteToFile writer(this, filename);
+ writer.SetMember(&operations_research::CVRPEpixData::PrintInstance);
+ writer.Run();
+}
+
+void CVRPEpixData::PrintSolution(std::ostream& out, const operations_research::CVRPSolution& sol) const {
+ CHECK(data_.HasCoordinates());
+ PrintEpixBeginFile(out);
+ PrintEpixPreamble(out);
+ PrintEpixBoundingBox(out, data_.RawBoundingBox());
+
+ PrintEpixNewLine(out);
+ PrintEpixComment(out, "Points:");
+
+ for (RoutingModel::NodeIndex i(0); i < data_.Size(); ++i) {
+ Point p = data_.Coordinate(i);
+ PrintEpixPoint(out, p, i);
+ }
+
+ PrintEpixComment(out, "Edges:");
+
+ RoutingModel::NodeIndex from_node, to_node;
+ RoutingModel::NodeIndex depot = data_.Depot();
+ int segment_nbr = 0;
+
+ for (CVRPSolution::const_vehicle_iterator v_iter = sol.vehicle_begin(); v_iter != sol.vehicle_end(); ++v_iter) {
+ from_node = depot;
+ for (CVRPSolution::const_node_iterator n_iter = sol.node_begin(v_iter); n_iter != sol.node_end(v_iter); ++n_iter ) {
+ to_node = *n_iter;
+ PrintEpixSegment(out, segment_nbr, from_node, to_node);
+ from_node = to_node;
+ ++segment_nbr;
+ }
+ // Last arc
+ PrintEpixSegment(out, segment_nbr, from_node, depot);
+ ++segment_nbr;
+ }
+
+
+ PrintEpixNewLine(out);
+
+ PrintEpixBeginFigure(out);
+
+
+ PrintEpixDrawMultipleSegments(out, segment_nbr);
+
+ PrintEpixRaw(out, " fill(White());");
+ PrintEpixDrawMultiplePoints(out, data_.Size());
+ PrintEpixDepot(out, data_.Depot());
+ PrintEpixEndFigure(out);
+
+ PrintEpixEndFile(out);
+}
+
+void CVRPEpixData::WriteSolution(const std::string& filename, const operations_research::CVRPSolution& sol) const {
+
+ WriteToFileP1 writer(this, filename);
+ writer.SetMember(&operations_research::CVRPEpixData::PrintSolution);
+ writer.Run(sol);
+
+}
+
+
+} // namespace operations_research
+
+#endif // OR_TOOLS_TUTORIALS_CPLUSPLUS_CVRP_EPIX_DATA_H
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/chap10/cvrp_solution.h b/documentation/tutorials/cplusplus/chap10/cvrp_solution.h
new file mode 100644
index 0000000000..f111b44fa3
--- /dev/null
+++ b/documentation/tutorials/cplusplus/chap10/cvrp_solution.h
@@ -0,0 +1,279 @@
+// 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 base for TSPTW solutions.
+
+#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_CVRP_SOLUTION_H
+#define OR_TOOLS_TUTORIALS_CPLUSPLUS_CVRP_SOLUTION_H
+
+#include
+
+#include "constraint_solver/routing.h"
+#include "base/split.h"
+#include "base/filelinereader.h"
+#include "base/join.h"
+#include "base/bitmap.h"
+
+#include "routing_common/routing_solution.h"
+#include "cvrp_data.h"
+
+DEFINE_bool(numbering_solution_nodes_from_zero, true, "Number the nodes in the solution starting from 0?");
+
+namespace operations_research {
+
+ class CVRPSolution : public RoutingSolution {
+ public:
+ typedef std::vector >::iterator vehicle_iterator;
+ typedef std::vector >::const_iterator const_vehicle_iterator;
+ typedef std::vector::iterator node_iterator;
+ typedef std::vector::const_iterator const_node_iterator;
+ CVRPSolution(const CVRPData & data, std::string filename): RoutingSolution(data), data_(data), depot_(data.Depot()),
+ loaded_solution_obj_(-1) {
+ LoadInstance(filename);
+ }
+ // We could have used RoutingModel::AssignmentToRoutes()
+ CVRPSolution(const CVRPData & data, const RoutingModel * const routing, const Assignment * const sol): RoutingSolution(data), data_(data),
+ depot_(data.Depot()), loaded_solution_obj_(-1) {
+ CHECK_NOTNULL(routing);
+ CHECK_NOTNULL(sol);
+ depot_ = routing->IndexToNode(routing->GetDepot());
+ for (int32 vehicle = 0; vehicle < routing->vehicles(); ++vehicle) {
+ int64 start_node = routing->Start(vehicle);
+ // first node after depot
+ int64 node = sol->Value(routing->NextVar(start_node));
+ for (; !routing->IsEnd(node);
+ node = sol->Value(routing->NextVar(node))) {
+ RoutingModel::NodeIndex node_id = routing->IndexToNode(node);
+ Add(node_id,vehicle);
+ }
+ }
+ }
+
+ virtual ~CVRPSolution() {}
+
+ RoutingModel::NodeIndex Depot() const {
+ return depot_;
+ }
+
+ std::string Name() const {
+ return name_;
+ }
+
+ void SetName(const std::string & name) {
+ name_ = name;
+ }
+
+ // We only consider complete solutions.
+ virtual void LoadInstance(std::string filename);
+ virtual bool IsSolution() const;
+ virtual bool IsFeasibleSolution() const;
+ virtual int64 ComputeObjectiveValue() const;
+ int NumberOfVehicles() const {
+ return number_of_vehicles_;
+ }
+ virtual bool Add(RoutingModel::NodeIndex i, int route_number) {
+ if (sol_.size() == route_number) {
+ std::vector v;
+ sol_.push_back(v);
+ }
+ sol_[route_number].push_back(i);
+ return true;
+ }
+
+ void WriteAssignment(const RoutingModel * routing, Assignment * const sol) {
+ CHECK_NOTNULL(routing);
+ CHECK_NOTNULL(sol);
+ routing->RoutesToAssignment(sol_,
+ true,
+ true,
+ sol);
+ }
+
+std::vector > const & Routes() const {
+ return sol_;
+}
+
+ //iterators
+ vehicle_iterator vehicle_begin() { return sol_.begin(); }
+ const_vehicle_iterator vehicle_begin() const { return sol_.begin(); }
+ vehicle_iterator vehicle_end() { return sol_.end(); }
+ const_vehicle_iterator vehicle_end() const { return sol_.end(); }
+
+ node_iterator node_begin(vehicle_iterator v_iter) {return v_iter->begin();}
+ const_node_iterator node_begin(const_vehicle_iterator v_iter) const {return v_iter->begin();}
+ node_iterator node_end(vehicle_iterator v_iter) {return v_iter->end();}
+ const_node_iterator node_end(const_vehicle_iterator v_iter) const {return v_iter->end();}
+
+ virtual void Print(std::ostream & out) const;
+ virtual void Write(const std::string & filename) const ;
+ protected:
+ std::vector > sol_;
+ std::vector capacities_;
+ private:
+ const CVRPData & data_;
+ RoutingModel::NodeIndex depot_;
+ int line_number_;
+ void ProcessNewLine(char* const line);
+ void InitLoadInstance() {
+ line_number_ = 0;
+ number_of_vehicles_ = 0;
+ sol_.clear();
+ name_ = "";
+ comment_ = "";
+ }
+
+ std::string name_;
+ std::string comment_;
+ int64 loaded_solution_obj_;
+ int number_of_vehicles_;
+ };
+
+ void CVRPSolution::LoadInstance(std::string filename) {
+ InitLoadInstance();
+ FileLineReader reader(filename.c_str());
+ reader.set_line_callback(NewPermanentCallback(
+ this,
+ &CVRPSolution::ProcessNewLine));
+ reader.Reload();
+ if (!reader.loaded_successfully()) {
+ LOG(FATAL) << "Could not open TSPTW solution file: " << filename;
+ }
+ }
+
+ // Test if all nodes are serviced once and only once
+ bool CVRPSolution::IsSolution() const {
+ // Test if same number of nodes
+ if (data_.Size() != Size()) {
+ return false;
+ }
+
+ // Test if all nodes are used
+ Bitmap used(Size());
+
+ for (int i = 0; i < sol_.size(); ++i) {
+ for (int j = 0; j < sol_[i].size(); ++j) {
+ int index = sol_[i][j].value();
+ if (used.Get(index)) {
+ LG << "already used index = " << index;
+ return false;
+ } else {
+ used.Set(index,true);
+ }
+ }
+ }
+
+ // Test if depot was not used in the solution
+ return !used.Get(depot_.value());
+ }
+
+ // Test if capacities are respected.
+ bool CVRPSolution::IsFeasibleSolution() const {
+ if (!IsSolution()) {
+ return false;
+ }
+
+ const int64 vehicle_capacity = data_.Capacity();
+ RoutingModel::NodeIndex node;
+ int64 route_capacity_left = vehicle_capacity;
+ int vehicle_index = 1;
+
+ for (const_vehicle_iterator v_iter = vehicle_begin(); v_iter != vehicle_end(); ++v_iter) {
+ route_capacity_left = vehicle_capacity;
+ VLOG(1) << "Route " << vehicle_index << " with capacity " << route_capacity_left;
+ for (const_node_iterator n_iter = node_begin(v_iter); n_iter != node_end(v_iter); ++n_iter ) {
+ node = *n_iter;
+
+ route_capacity_left -= data_.Demand(node);
+ VLOG(1) << "Servicing node " << node.value() + 1 << " with demand " << data_.Demand(node) << " (capacity left: " << route_capacity_left << ")";
+ if (route_capacity_left < 0) {
+ return false;
+ }
+ }
+ ++vehicle_index;
+ }
+
+ return true;
+ }
+
+
+
+ int64 CVRPSolution::ComputeObjectiveValue() const {
+ int64 obj = 0;
+ RoutingModel::NodeIndex from_node, to_node;
+
+ for (const_vehicle_iterator v_iter = vehicle_begin(); v_iter != vehicle_end(); ++v_iter) {
+ from_node = depot_;
+ for (const_node_iterator n_iter = node_begin(v_iter); n_iter != node_end(v_iter); ++n_iter ) {
+ to_node = *n_iter;
+ obj += data_.Distance(from_node, to_node);
+ from_node = to_node;
+ }
+ // Last arc
+ obj += data_.Distance(to_node, depot_);
+ }
+
+ return obj;
+ }
+
+ void CVRPSolution::Print(std::ostream& out) const {
+ int32 vehicle_index = 0;
+ for (const_vehicle_iterator v_iter = vehicle_begin(); v_iter != vehicle_end(); ++v_iter) {
+ out << "Route " << StrCat("#", vehicle_index + 1, ":");
+ for (const_node_iterator n_iter = node_begin(v_iter); n_iter != node_end(v_iter); ++n_iter ) {
+ out << " " << (*n_iter).value() + (FLAGS_numbering_solution_nodes_from_zero? 0 : 1);
+ }
+ out << std::endl;
+ ++vehicle_index;
+ }
+ out << "cost " << ComputeObjectiveValue() << std::endl;
+
+ }
+
+ void CVRPSolution::Write(const std::string & filename) const {
+ WriteToFile writer(this, filename);
+ writer.SetMember(&operations_research::CVRPSolution::Print);
+ writer.Run();
+ }
+
+void CVRPSolution::ProcessNewLine(char*const line) {
+ ++line_number_;
+ static const char kWordDelimiters[] = " #:";
+ std::vector words;
+ words = strings::Split(line, kWordDelimiters, strings::SkipEmpty());
+
+ if (words[0] == "Route") {
+ const int number_of_served_nodes = words.size() - 2;
+ CHECK_GE(number_of_served_nodes, 1);
+ for (int node = 0; node < number_of_served_nodes; ++node) {
+ int32 node_id = atoi32(words[node + 2]) + (FLAGS_numbering_solution_nodes_from_zero? 0 : -1);
+ CHECK_LE(node_id, size_) << "Node " << node_id << " is greater than size " << size_ << " of solution.";
+ Add(RoutingModel::NodeIndex(node_id ), number_of_vehicles_);
+ }
+ ++number_of_vehicles_;
+
+ return;
+ }
+
+ if (words[0] == "cost") {
+ CHECK_EQ(words.size(), 2) << "Only objective value allowed on cost line of CVRP solution file at line " << line_number_;
+ loaded_solution_obj_ = atoi64(words[1]);
+ return;
+ }
+ LOG(FATAL) << "Unrecognized line in CVRP solution file at line: " << line_number_;
+} // void ProcessNewLine(char* const line)
+
+
+} // namespace operations_research
+
+#endif // OR_TOOLS_TUTORIALS_CPLUSPLUS_CVRP_SOLUTION_H
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/chap10/cvrp_solution_to_epix.cc b/documentation/tutorials/cplusplus/chap10/cvrp_solution_to_epix.cc
new file mode 100644
index 0000000000..9ff25db2aa
--- /dev/null
+++ b/documentation/tutorials/cplusplus/chap10/cvrp_solution_to_epix.cc
@@ -0,0 +1,56 @@
+// 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.
+//
+//
+// Simple program to visualize a CVRP solution.
+
+#include
+
+#include "base/commandlineflags.h"
+
+#include "cvrp_data.h"
+#include "cvrp_solution.h"
+#include "routing_common/tsplib_reader.h"
+#include "cvrp_epix_data.h"
+
+int main(int argc, char **argv) {
+ std::string usage("Prints a CVRP solution in ePiX format.\n"
+ "See Google or-tools tutorials\n"
+ "Sample usage:\n\n");
+ usage += argv[0];
+ usage += " -instance_file= -solution_file= > epix_file.xp\n\n";
+ usage += " ./elaps -pdf epix_file.xp\n";
+
+ google::SetUsageMessage(usage);
+ google::ParseCommandLineFlags(&argc, &argv, true);
+
+ if (FLAGS_instance_file != "" && FLAGS_solution_file != "") {
+ operations_research::TSPLIBReader tsplib_reader(FLAGS_instance_file);
+ operations_research::CVRPData cvrp_data(tsplib_reader);
+ operations_research::CVRPSolution cvrp_sol(cvrp_data, FLAGS_solution_file);
+ if (cvrp_sol.IsFeasibleSolution()) {
+ if (cvrp_data.IsVisualizable()) {
+ operations_research::CVRPEpixData epix_data(cvrp_data);
+ epix_data.PrintSolution(std::cout, cvrp_sol);
+ } else {
+ LG << "Solution is not visualizable!";
+ }
+ } else {
+ LG << "Solution is NOT feasible...";
+ }
+ } else {
+ std::cout << google::ProgramUsage();
+ exit(-1);
+ }
+ return 0;
+}
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/chap10/opt-A-n32-k5 b/documentation/tutorials/cplusplus/chap10/opt-A-n32-k5
new file mode 100644
index 0000000000..5ab166c239
--- /dev/null
+++ b/documentation/tutorials/cplusplus/chap10/opt-A-n32-k5
@@ -0,0 +1,6 @@
+Route #1: 21 31 19 17 13 7 26
+Route #2: 12 1 16 30
+Route #3: 27 24
+Route #4: 29 18 8 9 22 15 10 25 5 20
+Route #5: 14 28 11 4 23 3 2 6
+cost 784
diff --git a/documentation/tutorials/cplusplus/chap10/opt-A-n32-k5.eepic b/documentation/tutorials/cplusplus/chap10/opt-A-n32-k5.eepic
new file mode 100644
index 0000000000..ae197b4d4f
--- /dev/null
+++ b/documentation/tutorials/cplusplus/chap10/opt-A-n32-k5.eepic
@@ -0,0 +1,1578 @@
+%% Generated from opt-A-n32-k5.xp on Tue Sep 9 13:33:21 EDT 2014 by
+%% ePiX-1.2.11
+%%
+%% Cartesian bounding box: [-1,98] x [-1,97]
+%% Actual size: 10 x 10cm
+%% Figure offset: left by 0cm, down by 0cm
+%%
+%% usepackages epic,eepic,xcolor
+%%
+\xdefinecolor{rgb_000000}{rgb}{0,0,0}%
+\xdefinecolor{rgb_ff0000}{rgb}{1,0,0}%
+\xdefinecolor{rgb_ffffff}{rgb}{1,1,1}%
+\setlength{\unitlength}{1cm}%
+\begin{picture}(10,10)(0,0)%
+\path(8.38384,7.85714)(10,1.53061)
+\path(10,1.53061)(10,0.612245)
+\path(10,0.612245)(9.49495,0.408163)
+\path(9.49495,0.408163)(9.29293,0.306122)
+\path(9.29293,0.306122)(8.58586,2.65306)
+\path(8.58586,2.65306)(8.58586,4.08163)
+\path(8.58586,4.08163)(8.18182,5.71429)
+\path(8.18182,5.71429)(8.38384,7.85714)
+\path(8.38384,7.85714)(10,5.40816)
+\path(10,5.40816)(9.79798,4.59184)
+\path(9.79798,4.59184)(8.9899,5.30612)
+\path(8.9899,5.30612)(8.68687,6.22449)
+\path(8.68687,6.22449)(8.38384,7.85714)
+\path(8.38384,7.85714)(5.85859,7.14286)
+\path(5.85859,7.14286)(6.26263,6.42857)
+\path(6.26263,6.42857)(8.38384,7.85714)
+\path(8.38384,7.85714)(2.12121,7.2449)
+\path(2.12121,7.2449)(2.0202,3.36735)
+\path(2.0202,3.36735)(1.51515,2.55102)
+\path(1.51515,2.55102)(0.30303,4.08163)
+\path(0.30303,4.08163)(0.606061,4.38776)
+\path(0.606061,4.38776)(0.20202,6.73469)
+\path(0.20202,6.73469)(0.40404,8.46939)
+\path(0.40404,8.46939)(1.0101,10)
+\path(1.0101,10)(3.0303,9.18367)
+\path(3.0303,9.18367)(5.15152,9.59184)
+\path(5.15152,9.59184)(8.38384,7.85714)
+\path(8.38384,7.85714)(6.26263,6.12245)
+\path(6.26263,6.12245)(2.42424,1.63265)
+\path(2.42424,1.63265)(0.606061,1.12245)
+\path(0.606061,1.12245)(1.41414,0.816327)
+\path(1.41414,0.816327)(4.34343,1.02041)
+\path(4.34343,1.02041)(5.05051,0.918367)
+\path(5.05051,0.918367)(5.15152,0.612245)
+\path(5.15152,0.612245)(5.9596,3.16327)
+\path(5.9596,3.16327)(8.38384,7.85714)
+\color{rgb_ffffff}%
+\path(8.35961,7.83878)(8.40807,7.83878)
+\path(8.35415,7.85102)(8.41352,7.85102)
+\path(8.35415,7.86327)(8.41352,7.86327)
+\path(8.35961,7.87551)(8.40807,7.87551)
+\path(8.40202,7.83266)(8.40202,7.88162)
+\path(8.3899,7.82715)(8.3899,7.88713)
+\path(8.37778,7.82715)(8.37778,7.88713)
+\path(8.36566,7.83266)(8.36566,7.88162)
+\color{rgb_000000}%
+\path(8.41414,7.85714)(8.4141,7.85874)(8.41398,7.86034)
+ (8.41377,7.86193)(8.41348,7.86351)(8.41311,7.86507)(8.41266,7.8666)
+ (8.41213,7.86811)(8.41152,7.86959)(8.41084,7.87104)
+ (8.41008,7.87245)(8.40925,7.87382)(8.40835,7.87514)
+ (8.40739,7.87641)(8.40636,7.87763)(8.40527,7.87879)
+ (8.40412,7.87989)(8.40291,7.88093)(8.40165,7.88191)
+ (8.40034,7.88282)(8.39899,7.88365)(8.3976,7.88442)(8.39616,7.88511)
+ (8.3947,7.88572)(8.3932,7.88626)(8.39168,7.88671)(8.39014,7.88709)
+ (8.38858,7.88738)(8.38701,7.88759)(8.38542,7.88771)
+ (8.38384,7.88776)(8.38225,7.88771)(8.38067,7.88759)(8.3791,7.88738)
+ (8.37754,7.88709)(8.376,7.88671)(8.37447,7.88626)(8.37298,7.88572)
+ (8.37151,7.88511)(8.37008,7.88442)(8.36869,7.88365)
+ (8.36733,7.88282)(8.36603,7.88191)(8.36477,7.88093)
+ (8.36356,7.87989)(8.36241,7.87879)(8.36132,7.87763)
+ (8.36029,7.87641)(8.35932,7.87514)(8.35842,7.87382)(8.3576,7.87245)
+ (8.35684,7.87104)(8.35616,7.86959)(8.35555,7.86811)(8.35502,7.8666)
+ (8.35457,7.86507)(8.3542,7.86351)(8.35391,7.86193)(8.3537,7.86034)
+ (8.35358,7.85874)(8.35354,7.85714)(8.35358,7.85554)(8.3537,7.85394)
+ (8.35391,7.85235)(8.3542,7.85078)(8.35457,7.84922)(8.35502,7.84768)
+ (8.35555,7.84617)(8.35616,7.84469)(8.35684,7.84325)(8.3576,7.84184)
+ (8.35842,7.84047)(8.35932,7.83915)(8.36029,7.83788)
+ (8.36132,7.83666)(8.36241,7.8355)(8.36356,7.83439)(8.36477,7.83335)
+ (8.36603,7.83238)(8.36733,7.83147)(8.36869,7.83063)
+ (8.37008,7.82987)(8.37151,7.82918)(8.37298,7.82856)
+ (8.37447,7.82803)(8.376,7.82757)(8.37754,7.8272)(8.3791,7.82691)
+ (8.38067,7.8267)(8.38225,7.82657)(8.38384,7.82653)(8.38542,7.82657)
+ (8.38701,7.8267)(8.38858,7.82691)(8.39014,7.8272)(8.39168,7.82757)
+ (8.3932,7.82803)(8.3947,7.82856)(8.39616,7.82918)(8.3976,7.82987)
+ (8.39899,7.83063)(8.40034,7.83147)(8.40165,7.83238)
+ (8.40291,7.83335)(8.40412,7.83439)(8.40527,7.8355)(8.40636,7.83666)
+ (8.40739,7.83788)(8.40835,7.83915)(8.40925,7.84047)
+ (8.41008,7.84184)(8.41084,7.84325)(8.41152,7.84469)
+ (8.41213,7.84617)(8.41266,7.84768)(8.41311,7.84922)
+ (8.41348,7.85078)(8.41377,7.85235)(8.41398,7.85394)(8.4141,7.85554)(8.41414,7.85714)
+\color{rgb_ffffff}%
+\path(9.82376,4.57577)(9.80604,4.62134)
+\path(9.81448,4.56616)(9.79277,4.62198)
+\path(9.80319,4.56169)(9.78148,4.61752)
+\path(9.78992,4.56233)(9.7722,4.60791)
+\path(9.81406,4.61777)(9.76883,4.60019)
+\path(9.82351,4.60832)(9.7681,4.58678)
+\path(9.82786,4.59689)(9.77245,4.57535)
+\path(9.82713,4.58349)(9.7819,4.5659)
+\color{rgb_000000}%
+\path(9.82828,4.59184)(9.82824,4.59344)(9.82812,4.59504)
+ (9.82791,4.59663)(9.82762,4.5982)(9.82725,4.59976)(9.8268,4.6013)
+ (9.82627,4.60281)(9.82566,4.60429)(9.82498,4.60573)
+ (9.82422,4.60714)(9.82339,4.60851)(9.8225,4.60983)(9.82153,4.6111)
+ (9.8205,4.61232)(9.81941,4.61348)(9.81826,4.61459)(9.81705,4.61563)
+ (9.81579,4.6166)(9.81448,4.61751)(9.81313,4.61835)(9.81174,4.61911)
+ (9.81031,4.6198)(9.80884,4.62042)(9.80734,4.62095)(9.80582,4.62141)
+ (9.80428,4.62178)(9.80272,4.62207)(9.80115,4.62228)
+ (9.79957,4.62241)(9.79798,4.62245)(9.79639,4.62241)
+ (9.79481,4.62228)(9.79324,4.62207)(9.79168,4.62178)
+ (9.79014,4.62141)(9.78862,4.62095)(9.78712,4.62042)(9.78565,4.6198)
+ (9.78422,4.61911)(9.78283,4.61835)(9.78148,4.61751)(9.78017,4.6166)
+ (9.77891,4.61563)(9.7777,4.61459)(9.77655,4.61348)(9.77546,4.61232)
+ (9.77443,4.6111)(9.77346,4.60983)(9.77257,4.60851)(9.77174,4.60714)
+ (9.77098,4.60573)(9.7703,4.60429)(9.76969,4.60281)(9.76916,4.6013)
+ (9.76871,4.59976)(9.76834,4.5982)(9.76805,4.59663)(9.76784,4.59504)
+ (9.76772,4.59344)(9.76768,4.59184)(9.76772,4.59023)
+ (9.76784,4.58864)(9.76805,4.58705)(9.76834,4.58547)
+ (9.76871,4.58391)(9.76916,4.58238)(9.76969,4.58087)(9.7703,4.57939)
+ (9.77098,4.57794)(9.77174,4.57653)(9.77257,4.57516)
+ (9.77346,4.57384)(9.77443,4.57257)(9.77546,4.57135)
+ (9.77655,4.57019)(9.7777,4.56909)(9.77891,4.56805)(9.78017,4.56707)
+ (9.78148,4.56616)(9.78283,4.56533)(9.78422,4.56456)
+ (9.78565,4.56387)(9.78712,4.56326)(9.78862,4.56272)
+ (9.79014,4.56227)(9.79168,4.56189)(9.79324,4.5616)(9.79481,4.56139)
+ (9.79639,4.56127)(9.79798,4.56122)(9.79957,4.56127)
+ (9.80115,4.56139)(9.80272,4.5616)(9.80428,4.56189)(9.80582,4.56227)
+ (9.80734,4.56272)(9.80884,4.56326)(9.81031,4.56387)
+ (9.81174,4.56456)(9.81313,4.56533)(9.81448,4.56616)
+ (9.81579,4.56707)(9.81705,4.56805)(9.81826,4.56909)
+ (9.81941,4.57019)(9.8205,4.57135)(9.82153,4.57257)(9.8225,4.57384)
+ (9.82339,4.57516)(9.82422,4.57653)(9.82498,4.57794)
+ (9.82566,4.57939)(9.82627,4.58087)(9.8268,4.58238)(9.82725,4.58391)
+ (9.82762,4.58547)(9.82791,4.58705)(9.82812,4.58864)
+ (9.82824,4.59023)(9.82828,4.59184)
+\color{rgb_ffffff}%
+\path(5.15725,0.642294)(5.12135,0.609406)
+\path(5.16944,0.636926)(5.12546,0.596637)
+\path(5.17758,0.627853)(5.13359,0.587563)
+\path(5.18168,0.615084)(5.14578,0.582196)
+\path(5.12171,0.617736)(5.15464,0.581797)
+\path(5.1269,0.630098)(5.16723,0.586081)
+\path(5.1358,0.638409)(5.17613,0.594392)
+\path(5.14839,0.642693)(5.18132,0.606754)
+\color{rgb_000000}%
+\path(5.18182,0.612245)(5.18178,0.613847)(5.18165,0.615445)
+ (5.18145,0.617034)(5.18116,0.61861)(5.18079,0.620168)
+ (5.18034,0.621705)(5.17981,0.623215)(5.1792,0.624696)
+ (5.17852,0.626143)(5.17776,0.627551)(5.17693,0.628918)
+ (5.17603,0.630238)(5.17507,0.63151)(5.17403,0.632728)
+ (5.17294,0.633891)(5.17179,0.634994)(5.17059,0.636035)
+ (5.16933,0.637011)(5.16802,0.637918)(5.16667,0.638756)
+ (5.16527,0.639521)(5.16384,0.640211)(5.16237,0.640824)
+ (5.16088,0.641359)(5.15936,0.641814)(5.15782,0.642188)
+ (5.15626,0.64248)(5.15468,0.642689)(5.1531,0.642815)
+ (5.15152,0.642857)(5.14993,0.642815)(5.14835,0.642689)
+ (5.14677,0.64248)(5.14521,0.642188)(5.14367,0.641814)
+ (5.14215,0.641359)(5.14066,0.640824)(5.13919,0.640211)
+ (5.13776,0.639521)(5.13636,0.638756)(5.13501,0.637918)
+ (5.1337,0.637011)(5.13244,0.636035)(5.13124,0.634994)
+ (5.13009,0.633891)(5.129,0.632728)(5.12797,0.63151)(5.127,0.630238)
+ (5.1261,0.628918)(5.12527,0.627551)(5.12451,0.626143)
+ (5.12383,0.624696)(5.12322,0.623215)(5.1227,0.621705)
+ (5.12224,0.620168)(5.12187,0.61861)(5.12159,0.617034)
+ (5.12138,0.615445)(5.12125,0.613847)(5.12121,0.612245)
+ (5.12125,0.610643)(5.12138,0.609045)(5.12159,0.607456)
+ (5.12187,0.60588)(5.12224,0.604322)(5.1227,0.602785)
+ (5.12322,0.601274)(5.12383,0.599794)(5.12451,0.598347)
+ (5.12527,0.596939)(5.1261,0.595572)(5.127,0.594251)
+ (5.12797,0.59298)(5.129,0.591761)(5.13009,0.590599)
+ (5.13124,0.589496)(5.13244,0.588455)(5.1337,0.587479)
+ (5.13501,0.586571)(5.13636,0.585734)(5.13776,0.584969)
+ (5.13919,0.584279)(5.14066,0.583666)(5.14215,0.583131)
+ (5.14367,0.582676)(5.14521,0.582302)(5.14677,0.58201)
+ (5.14835,0.5818)(5.14993,0.581675)(5.15152,0.581633)
+ (5.1531,0.581675)(5.15468,0.5818)(5.15626,0.58201)
+ (5.15782,0.582302)(5.15936,0.582676)(5.16088,0.583131)
+ (5.16237,0.583666)(5.16384,0.584279)(5.16527,0.584969)
+ (5.16667,0.585734)(5.16802,0.586571)(5.16933,0.587479)
+ (5.17059,0.588455)(5.17179,0.589496)(5.17294,0.590599)
+ (5.17403,0.591761)(5.17507,0.59298)(5.17603,0.594251)
+ (5.17693,0.595572)(5.17776,0.596939)(5.17852,0.598347)
+ (5.1792,0.599794)(5.17981,0.601274)(5.18034,0.602785)
+ (5.18079,0.604322)(5.18116,0.60588)(5.18145,0.607456)
+ (5.18165,0.609045)(5.18178,0.610643)(5.18182,0.612245)
+\color{rgb_ffffff}%
+\path(5.02075,0.912609)(5.06431,0.891118)
+\path(5.02117,0.926027)(5.07452,0.899708)
+\path(5.0265,0.937027)(5.07984,0.910707)
+\path(5.0367,0.945617)(5.08026,0.924126)
+\path(5.05597,0.888267)(5.07759,0.932088)
+\path(5.04268,0.888793)(5.06917,0.942472)
+\path(5.03184,0.894263)(5.05833,0.947942)
+\path(5.02342,0.904647)(5.04504,0.948467)
+\color{rgb_000000}%
+\path(5.08081,0.918367)(5.08077,0.919969)(5.08064,0.921567)
+ (5.08044,0.923156)(5.08015,0.924732)(5.07978,0.92629)
+ (5.07932,0.927827)(5.0788,0.929338)(5.07819,0.930818)
+ (5.07751,0.932265)(5.07675,0.933673)(5.07592,0.93504)
+ (5.07502,0.936361)(5.07405,0.937632)(5.07302,0.938851)
+ (5.07193,0.940013)(5.07078,0.941117)(5.06958,0.942158)
+ (5.06832,0.943133)(5.06701,0.944041)(5.06566,0.944878)
+ (5.06426,0.945643)(5.06283,0.946333)(5.06136,0.946946)
+ (5.05987,0.947481)(5.05835,0.947937)(5.05681,0.948311)
+ (5.05525,0.948603)(5.05367,0.948812)(5.05209,0.948938)
+ (5.05051,0.94898)(5.04892,0.948938)(5.04734,0.948812)
+ (5.04576,0.948603)(5.0442,0.948311)(5.04266,0.947937)
+ (5.04114,0.947481)(5.03965,0.946946)(5.03818,0.946333)
+ (5.03675,0.945643)(5.03535,0.944878)(5.034,0.944041)
+ (5.03269,0.943133)(5.03143,0.942158)(5.03023,0.941117)
+ (5.02908,0.940013)(5.02799,0.938851)(5.02696,0.937632)
+ (5.02599,0.936361)(5.02509,0.93504)(5.02426,0.933673)
+ (5.0235,0.932265)(5.02282,0.930818)(5.02221,0.929338)
+ (5.02169,0.927827)(5.02123,0.92629)(5.02086,0.924732)
+ (5.02058,0.923156)(5.02037,0.921567)(5.02024,0.919969)
+ (5.0202,0.918367)(5.02024,0.916765)(5.02037,0.915167)
+ (5.02058,0.913579)(5.02086,0.912003)(5.02123,0.910444)
+ (5.02169,0.908908)(5.02221,0.907397)(5.02282,0.905916)
+ (5.0235,0.90447)(5.02426,0.903061)(5.02509,0.901695)
+ (5.02599,0.900374)(5.02696,0.899102)(5.02799,0.897884)
+ (5.02908,0.896721)(5.03023,0.895618)(5.03143,0.894577)
+ (5.03269,0.893602)(5.034,0.892694)(5.03535,0.891856)
+ (5.03675,0.891092)(5.03818,0.890402)(5.03965,0.889788)
+ (5.04114,0.889253)(5.04266,0.888798)(5.0442,0.888424)
+ (5.04576,0.888132)(5.04734,0.887923)(5.04892,0.887797)
+ (5.05051,0.887755)(5.05209,0.887797)(5.05367,0.887923)
+ (5.05525,0.888132)(5.05681,0.888424)(5.05835,0.888798)
+ (5.05987,0.889253)(5.06136,0.889788)(5.06283,0.890402)
+ (5.06426,0.891092)(5.06566,0.891856)(5.06701,0.892694)
+ (5.06832,0.893602)(5.06958,0.894577)(5.07078,0.895618)
+ (5.07193,0.896721)(5.07302,0.897884)(5.07405,0.899102)
+ (5.07502,0.900374)(5.07592,0.901695)(5.07675,0.903061)
+ (5.07751,0.90447)(5.07819,0.905916)(5.0788,0.907397)
+ (5.07932,0.908908)(5.07978,0.910444)(5.08015,0.912003)
+ (5.08044,0.913579)(5.08064,0.915167)(5.08077,0.916765)(5.08081,0.918367)
+\color{rgb_ffffff}%
+\path(1.43011,0.790321)(1.43439,0.839099)
+\path(1.41756,0.785915)(1.4228,0.845652)
+\path(1.40548,0.787001)(1.41073,0.846738)
+\path(1.39389,0.793554)(1.39817,0.842332)
+\path(1.43986,0.832503)(1.39156,0.836741)
+\path(1.44424,0.81983)(1.3851,0.82502)
+\path(1.44319,0.807633)(1.38404,0.812823)
+\path(1.43672,0.795912)(1.38843,0.80015)
+\color{rgb_000000}%
+\path(1.44444,0.816327)(1.4444,0.817929)(1.44428,0.819526)
+ (1.44407,0.821115)(1.44378,0.822691)(1.44341,0.82425)
+ (1.44296,0.825786)(1.44243,0.827297)(1.44182,0.828778)
+ (1.44114,0.830224)(1.44038,0.831633)(1.43956,0.832999)
+ (1.43866,0.83432)(1.43769,0.835591)(1.43666,0.83681)
+ (1.43557,0.837973)(1.43442,0.839076)(1.43321,0.840117)
+ (1.43195,0.841092)(1.43065,0.842)(1.42929,0.842838)
+ (1.4279,0.843602)(1.42647,0.844292)(1.425,0.844906)
+ (1.42351,0.845441)(1.42198,0.845896)(1.42044,0.84627)
+ (1.41888,0.846562)(1.41731,0.846771)(1.41573,0.846897)
+ (1.41414,0.846939)(1.41256,0.846897)(1.41097,0.846771)
+ (1.4094,0.846562)(1.40784,0.84627)(1.4063,0.845896)
+ (1.40478,0.845441)(1.40328,0.844906)(1.40182,0.844292)
+ (1.40038,0.843602)(1.39899,0.842838)(1.39764,0.842)
+ (1.39633,0.841092)(1.39507,0.840117)(1.39386,0.839076)
+ (1.39271,0.837973)(1.39162,0.83681)(1.39059,0.835591)
+ (1.38963,0.83432)(1.38873,0.832999)(1.3879,0.831633)
+ (1.38714,0.830224)(1.38646,0.828778)(1.38585,0.827297)
+ (1.38532,0.825786)(1.38487,0.82425)(1.3845,0.822691)
+ (1.38421,0.821115)(1.384,0.819526)(1.38388,0.817929)
+ (1.38384,0.816327)(1.38388,0.814724)(1.384,0.813127)
+ (1.38421,0.811538)(1.3845,0.809962)(1.38487,0.808403)
+ (1.38532,0.806867)(1.38585,0.805356)(1.38646,0.803875)
+ (1.38714,0.802429)(1.3879,0.80102)(1.38873,0.799654)
+ (1.38963,0.798333)(1.39059,0.797062)(1.39162,0.795843)
+ (1.39271,0.79468)(1.39386,0.793577)(1.39507,0.792536)
+ (1.39633,0.791561)(1.39764,0.790653)(1.39899,0.789816)
+ (1.40038,0.789051)(1.40182,0.788361)(1.40328,0.787748)
+ (1.40478,0.787213)(1.4063,0.786757)(1.40784,0.786383)
+ (1.4094,0.786091)(1.41097,0.785882)(1.41256,0.785756)
+ (1.41414,0.785714)(1.41573,0.785756)(1.41731,0.785882)
+ (1.41888,0.786091)(1.42044,0.786383)(1.42198,0.786757)
+ (1.42351,0.787213)(1.425,0.787748)(1.42647,0.788361)
+ (1.4279,0.789051)(1.42929,0.789816)(1.43065,0.790653)
+ (1.43195,0.791561)(1.43321,0.792536)(1.43442,0.793577)
+ (1.43557,0.79468)(1.43666,0.795843)(1.43769,0.797062)
+ (1.43866,0.798333)(1.43956,0.799654)(1.44038,0.80102)
+ (1.44114,0.802429)(1.44182,0.803875)(1.44243,0.805356)
+ (1.44296,0.806867)(1.44341,0.808403)(1.44378,0.809962)
+ (1.44407,0.811538)(1.44428,0.813127)(1.4444,0.814724)(1.44444,0.816327)
+\color{rgb_ffffff}%
+\path(3.04855,9.2081)(3.00198,9.19454)
+\path(3.05715,9.19786)(3.00011,9.18125)
+\path(3.0605,9.18609)(3.00346,9.16949)
+\path(3.05863,9.17281)(3.01205,9.15925)
+\path(3.00603,9.20198)(3.0197,9.155)
+\path(3.01612,9.21071)(3.03286,9.15318)
+\path(3.02774,9.21417)(3.04449,9.15663)
+\path(3.0409,9.21235)(3.05458,9.16536)
+\color{rgb_000000}%
+\path(3.06061,9.18367)(3.06056,9.18528)(3.06044,9.18687)
+ (3.06023,9.18846)(3.05994,9.19004)(3.05957,9.1916)(3.05912,9.19313)
+ (3.05859,9.19464)(3.05799,9.19612)(3.0573,9.19757)(3.05655,9.19898)
+ (3.05572,9.20035)(3.05482,9.20167)(3.05385,9.20294)
+ (3.05282,9.20416)(3.05173,9.20532)(3.05058,9.20642)
+ (3.04937,9.20746)(3.04811,9.20844)(3.04681,9.20935)
+ (3.04545,9.21018)(3.04406,9.21095)(3.04263,9.21164)
+ (3.04116,9.21225)(3.03967,9.21279)(3.03815,9.21324)(3.0366,9.21362)
+ (3.03504,9.21391)(3.03347,9.21412)(3.03189,9.21424)(3.0303,9.21429)
+ (3.02872,9.21424)(3.02714,9.21412)(3.02556,9.21391)(3.024,9.21362)
+ (3.02246,9.21324)(3.02094,9.21279)(3.01944,9.21225)
+ (3.01798,9.21164)(3.01655,9.21095)(3.01515,9.21018)(3.0138,9.20935)
+ (3.01249,9.20844)(3.01123,9.20746)(3.01003,9.20642)
+ (3.00888,9.20532)(3.00778,9.20416)(3.00675,9.20294)
+ (3.00579,9.20167)(3.00489,9.20035)(3.00406,9.19898)(3.0033,9.19757)
+ (3.00262,9.19612)(3.00201,9.19464)(3.00148,9.19313)(3.00103,9.1916)
+ (3.00066,9.19004)(3.00037,9.18846)(3.00017,9.18687)
+ (3.00004,9.18528)(3,9.18367)(3.00004,9.18207)(3.00017,9.18047)
+ (3.00037,9.17888)(3.00066,9.17731)(3.00103,9.17575)
+ (3.00148,9.17421)(3.00201,9.1727)(3.00262,9.17122)(3.0033,9.16978)
+ (3.00406,9.16837)(3.00489,9.167)(3.00579,9.16568)(3.00675,9.16441)
+ (3.00778,9.16319)(3.00888,9.16203)(3.01003,9.16092)
+ (3.01123,9.15988)(3.01249,9.15891)(3.0138,9.158)(3.01515,9.15716)
+ (3.01655,9.1564)(3.01798,9.15571)(3.01944,9.15509)(3.02094,9.15456)
+ (3.02246,9.1541)(3.024,9.15373)(3.02556,9.15344)(3.02714,9.15323)
+ (3.02872,9.1531)(3.0303,9.15306)(3.03189,9.1531)(3.03347,9.15323)
+ (3.03504,9.15344)(3.0366,9.15373)(3.03815,9.1541)(3.03967,9.15456)
+ (3.04116,9.15509)(3.04263,9.15571)(3.04406,9.1564)(3.04545,9.15716)
+ (3.04681,9.158)(3.04811,9.15891)(3.04937,9.15988)(3.05058,9.16092)
+ (3.05173,9.16203)(3.05282,9.16319)(3.05385,9.16441)
+ (3.05482,9.16568)(3.05572,9.167)(3.05655,9.16837)(3.0573,9.16978)
+ (3.05799,9.17122)(3.05859,9.1727)(3.05912,9.17421)(3.05957,9.17575)
+ (3.05994,9.17731)(3.06023,9.17888)(3.06044,9.18047)
+ (3.06056,9.18207)(3.06061,9.18367)
+\color{rgb_ffffff}%
+\path(5.93038,3.17138)(5.96006,3.13267)
+\path(5.93663,3.18322)(5.97298,3.13581)
+\path(5.94621,3.19072)(5.98256,3.14331)
+\path(5.95913,3.19387)(5.98881,3.15515)
+\path(5.95128,3.13384)(5.98989,3.16344)
+\path(5.93961,3.14026)(5.9869,3.17652)
+\path(5.93229,3.15001)(5.97958,3.18627)
+\path(5.9293,3.16309)(5.96791,3.19269)
+\color{rgb_000000}%
+\path(5.9899,3.16327)(5.98986,3.16487)(5.98973,3.16647)
+ (5.98953,3.16805)(5.98924,3.16963)(5.98887,3.17119)
+ (5.98842,3.17273)(5.98789,3.17424)(5.98728,3.17572)(5.9866,3.17716)
+ (5.98584,3.17857)(5.98501,3.17994)(5.98411,3.18126)
+ (5.98315,3.18253)(5.98212,3.18375)(5.98102,3.18491)
+ (5.97987,3.18601)(5.97867,3.18706)(5.97741,3.18803)(5.9761,3.18894)
+ (5.97475,3.18978)(5.97335,3.19054)(5.97192,3.19123)
+ (5.97046,3.19184)(5.96896,3.19238)(5.96744,3.19283)(5.9659,3.19321)
+ (5.96434,3.1935)(5.96276,3.19371)(5.96118,3.19384)(5.9596,3.19388)
+ (5.95801,3.19384)(5.95643,3.19371)(5.95486,3.1935)(5.9533,3.19321)
+ (5.95175,3.19283)(5.95023,3.19238)(5.94874,3.19184)
+ (5.94727,3.19123)(5.94584,3.19054)(5.94444,3.18978)
+ (5.94309,3.18894)(5.94178,3.18803)(5.94053,3.18706)
+ (5.93932,3.18601)(5.93817,3.18491)(5.93708,3.18375)
+ (5.93605,3.18253)(5.93508,3.18126)(5.93418,3.17994)
+ (5.93335,3.17857)(5.9326,3.17716)(5.93191,3.17572)(5.93131,3.17424)
+ (5.93078,3.17273)(5.93033,3.17119)(5.92996,3.16963)
+ (5.92967,3.16805)(5.92946,3.16647)(5.92933,3.16487)
+ (5.92929,3.16327)(5.92933,3.16166)(5.92946,3.16007)
+ (5.92967,3.15848)(5.92996,3.1569)(5.93033,3.15534)(5.93078,3.15381)
+ (5.93131,3.15229)(5.93191,3.15081)(5.9326,3.14937)(5.93335,3.14796)
+ (5.93418,3.14659)(5.93508,3.14527)(5.93605,3.144)(5.93708,3.14278)
+ (5.93817,3.14162)(5.93932,3.14052)(5.94053,3.13948)(5.94178,3.1385)
+ (5.94309,3.13759)(5.94444,3.13675)(5.94584,3.13599)(5.94727,3.1353)
+ (5.94874,3.13469)(5.95023,3.13415)(5.95175,3.1337)(5.9533,3.13332)
+ (5.95486,3.13303)(5.95643,3.13282)(5.95801,3.1327)(5.9596,3.13265)
+ (5.96118,3.1327)(5.96276,3.13282)(5.96434,3.13303)(5.9659,3.13332)
+ (5.96744,3.1337)(5.96896,3.13415)(5.97046,3.13469)(5.97192,3.1353)
+ (5.97335,3.13599)(5.97475,3.13675)(5.9761,3.13759)(5.97741,3.1385)
+ (5.97867,3.13948)(5.97987,3.14052)(5.98102,3.14162)
+ (5.98212,3.14278)(5.98315,3.144)(5.98411,3.14527)(5.98501,3.14659)
+ (5.98584,3.14796)(5.9866,3.14937)(5.98728,3.15081)(5.98789,3.15229)
+ (5.98842,3.15381)(5.98887,3.15534)(5.98924,3.1569)(5.98953,3.15848)
+ (5.98973,3.16007)(5.98986,3.16166)(5.9899,3.16327)
+\color{rgb_ffffff}%
+\path(8.58867,4.05116)(8.61403,4.0929)
+\path(8.5755,4.05288)(8.60655,4.10399)
+\path(8.56517,4.05928)(8.59622,4.11039)
+\path(8.55769,4.07037)(8.58304,4.11211)
+\path(8.616,4.08475)(8.57446,4.10999)
+\path(8.61442,4.07143)(8.56354,4.10233)
+\path(8.60818,4.06093)(8.5573,4.09184)
+\path(8.59726,4.05328)(8.55572,4.07851)
+\color{rgb_000000}%
+\path(8.61616,4.08163)(8.61612,4.08323)(8.616,4.08483)
+ (8.61579,4.08642)(8.6155,4.088)(8.61513,4.08956)(8.61468,4.09109)
+ (8.61415,4.0926)(8.61354,4.09408)(8.61286,4.09553)(8.6121,4.09694)
+ (8.61127,4.09831)(8.61037,4.09963)(8.60941,4.1009)(8.60838,4.10212)
+ (8.60729,4.10328)(8.60614,4.10438)(8.60493,4.10542)(8.60367,4.1064)
+ (8.60236,4.10731)(8.60101,4.10814)(8.59962,4.10891)(8.59818,4.1096)
+ (8.59672,4.11021)(8.59522,4.11075)(8.5937,4.1112)(8.59216,4.11158)
+ (8.5906,4.11187)(8.58903,4.11208)(8.58744,4.1122)(8.58586,4.11224)
+ (8.58427,4.1122)(8.58269,4.11208)(8.58112,4.11187)(8.57956,4.11158)
+ (8.57802,4.1112)(8.57649,4.11075)(8.575,4.11021)(8.57353,4.1096)
+ (8.5721,4.10891)(8.57071,4.10814)(8.56935,4.10731)(8.56805,4.1064)
+ (8.56679,4.10542)(8.56558,4.10438)(8.56443,4.10328)
+ (8.56334,4.10212)(8.56231,4.1009)(8.56134,4.09963)(8.56044,4.09831)
+ (8.55962,4.09694)(8.55886,4.09553)(8.55818,4.09408)(8.55757,4.0926)
+ (8.55704,4.09109)(8.55659,4.08956)(8.55622,4.088)(8.55593,4.08642)
+ (8.55572,4.08483)(8.5556,4.08323)(8.55556,4.08163)(8.5556,4.08003)
+ (8.55572,4.07843)(8.55593,4.07684)(8.55622,4.07527)
+ (8.55659,4.07371)(8.55704,4.07217)(8.55757,4.07066)
+ (8.55818,4.06918)(8.55886,4.06773)(8.55962,4.06633)
+ (8.56044,4.06496)(8.56134,4.06364)(8.56231,4.06237)
+ (8.56334,4.06115)(8.56443,4.05999)(8.56558,4.05888)
+ (8.56679,4.05784)(8.56805,4.05687)(8.56935,4.05596)
+ (8.57071,4.05512)(8.5721,4.05436)(8.57353,4.05367)(8.575,4.05305)
+ (8.57649,4.05252)(8.57802,4.05206)(8.57956,4.05169)(8.58112,4.0514)
+ (8.58269,4.05119)(8.58427,4.05106)(8.58586,4.05102)
+ (8.58744,4.05106)(8.58903,4.05119)(8.5906,4.0514)(8.59216,4.05169)
+ (8.5937,4.05206)(8.59522,4.05252)(8.59672,4.05305)(8.59818,4.05367)
+ (8.59962,4.05436)(8.60101,4.05512)(8.60236,4.05596)
+ (8.60367,4.05687)(8.60493,4.05784)(8.60614,4.05888)
+ (8.60729,4.05999)(8.60838,4.06115)(8.60941,4.06237)
+ (8.61037,4.06364)(8.61127,4.06496)(8.6121,4.06633)(8.61286,4.06773)
+ (8.61354,4.06918)(8.61415,4.07066)(8.61468,4.07217)
+ (8.61513,4.07371)(8.6155,4.07527)(8.61579,4.07684)(8.616,4.07843)
+ (8.61612,4.08003)(8.61616,4.08163)
+\color{rgb_ffffff}%
+\path(1.54217,2.56489)(1.49442,2.57333)
+\path(1.54543,2.55188)(1.48696,2.56222)
+\path(1.54335,2.53982)(1.48487,2.55016)
+\path(1.53588,2.52871)(1.48814,2.53715)
+\path(1.50152,2.57836)(1.49299,2.53015)
+\path(1.51441,2.58161)(1.50397,2.52258)
+\path(1.52634,2.57946)(1.5159,2.52043)
+\path(1.53731,2.57189)(1.52878,2.52368)
+\color{rgb_000000}%
+\path(1.54545,2.55102)(1.54541,2.55262)(1.54529,2.55422)
+ (1.54508,2.55581)(1.54479,2.55739)(1.54442,2.55894)
+ (1.54397,2.56048)(1.54344,2.56199)(1.54283,2.56347)
+ (1.54215,2.56492)(1.54139,2.56633)(1.54057,2.56769)
+ (1.53967,2.56901)(1.5387,2.57029)(1.53767,2.5715)(1.53658,2.57267)
+ (1.53543,2.57377)(1.53422,2.57481)(1.53296,2.57579)
+ (1.53166,2.57669)(1.5303,2.57753)(1.52891,2.5783)(1.52748,2.57899)
+ (1.52601,2.5796)(1.52452,2.58013)(1.52299,2.58059)(1.52145,2.58096)
+ (1.51989,2.58126)(1.51832,2.58146)(1.51674,2.58159)
+ (1.51515,2.58163)(1.51357,2.58159)(1.51198,2.58146)
+ (1.51041,2.58126)(1.50885,2.58096)(1.50731,2.58059)
+ (1.50579,2.58013)(1.50429,2.5796)(1.50283,2.57899)(1.50139,2.5783)
+ (1.5,2.57753)(1.49865,2.57669)(1.49734,2.57579)(1.49608,2.57481)
+ (1.49487,2.57377)(1.49372,2.57267)(1.49263,2.5715)(1.4916,2.57029)
+ (1.49064,2.56901)(1.48974,2.56769)(1.48891,2.56633)
+ (1.48815,2.56492)(1.48747,2.56347)(1.48686,2.56199)
+ (1.48633,2.56048)(1.48588,2.55894)(1.48551,2.55739)
+ (1.48522,2.55581)(1.48501,2.55422)(1.48489,2.55262)
+ (1.48485,2.55102)(1.48489,2.54942)(1.48501,2.54782)
+ (1.48522,2.54623)(1.48551,2.54466)(1.48588,2.5431)(1.48633,2.54156)
+ (1.48686,2.54005)(1.48747,2.53857)(1.48815,2.53712)
+ (1.48891,2.53571)(1.48974,2.53435)(1.49064,2.53303)(1.4916,2.53176)
+ (1.49263,2.53054)(1.49372,2.52937)(1.49487,2.52827)
+ (1.49608,2.52723)(1.49734,2.52625)(1.49865,2.52535)(1.5,2.52451)
+ (1.50139,2.52374)(1.50283,2.52305)(1.50429,2.52244)
+ (1.50579,2.52191)(1.50731,2.52145)(1.50885,2.52108)
+ (1.51041,2.52079)(1.51198,2.52058)(1.51357,2.52045)
+ (1.51515,2.52041)(1.51674,2.52045)(1.51832,2.52058)
+ (1.51989,2.52079)(1.52145,2.52108)(1.52299,2.52145)
+ (1.52452,2.52191)(1.52601,2.52244)(1.52748,2.52305)
+ (1.52891,2.52374)(1.5303,2.52451)(1.53166,2.52535)(1.53296,2.52625)
+ (1.53422,2.52723)(1.53543,2.52827)(1.53658,2.52937)
+ (1.53767,2.53054)(1.5387,2.53176)(1.53967,2.53303)(1.54057,2.53435)
+ (1.54139,2.53571)(1.54215,2.53712)(1.54283,2.53857)
+ (1.54344,2.54005)(1.54397,2.54156)(1.54442,2.5431)(1.54479,2.54466)
+ (1.54508,2.54623)(1.54529,2.54782)(1.54541,2.54942)(1.54545,2.55102)
+\color{rgb_ffffff}%
+\path(0.280443,4.10204)(0.289963,4.05402)
+\path(0.291259,4.10983)(0.302919,4.05102)
+\path(0.303142,4.11224)(0.314802,4.05344)
+\path(0.316098,4.10924)(0.325618,4.06123)
+\path(0.282742,4.05889)(0.33031,4.06833)
+\path(0.275073,4.06985)(0.333327,4.0814)
+\path(0.272733,4.08186)(0.330988,4.09341)
+\path(0.275751,4.09494)(0.323319,4.10437)
+\color{rgb_000000}%
+\path(0.333333,4.08163)(0.333292,4.08323)(0.333167,4.08483)
+ (0.33296,4.08642)(0.332671,4.088)(0.332301,4.08956)
+ (0.33185,4.09109)(0.331321,4.0926)(0.330713,4.09408)
+ (0.330031,4.09553)(0.329273,4.09694)(0.328445,4.09831)
+ (0.327546,4.09963)(0.32658,4.1009)(0.32555,4.10212)
+ (0.324458,4.10328)(0.323307,4.10438)(0.322101,4.10542)
+ (0.320842,4.1064)(0.319535,4.10731)(0.318182,4.10814)
+ (0.316788,4.10891)(0.315356,4.1096)(0.31389,4.11021)
+ (0.312394,4.11075)(0.310873,4.1112)(0.309331,4.11158)
+ (0.307771,4.11187)(0.306198,4.11208)(0.304616,4.1122)
+ (0.30303,4.11224)(0.301444,4.1122)(0.299863,4.11208)
+ (0.29829,4.11187)(0.29673,4.11158)(0.295187,4.1112)
+ (0.293666,4.11075)(0.292171,4.11021)(0.290705,4.1096)
+ (0.289273,4.10891)(0.287879,4.10814)(0.286526,4.10731)
+ (0.285219,4.1064)(0.28396,4.10542)(0.282754,4.10438)
+ (0.281603,4.10328)(0.280511,4.10212)(0.27948,4.1009)
+ (0.278515,4.09963)(0.277616,4.09831)(0.276787,4.09694)
+ (0.27603,4.09553)(0.275347,4.09408)(0.27474,4.0926)
+ (0.27421,4.09109)(0.27376,4.08956)(0.273389,4.088)(0.2731,4.08642)
+ (0.272893,4.08483)(0.272769,4.08323)(0.272727,4.08163)
+ (0.272769,4.08003)(0.272893,4.07843)(0.2731,4.07684)
+ (0.273389,4.07527)(0.27376,4.07371)(0.27421,4.07217)
+ (0.27474,4.07066)(0.275347,4.06918)(0.27603,4.06773)
+ (0.276787,4.06633)(0.277616,4.06496)(0.278515,4.06364)
+ (0.27948,4.06237)(0.280511,4.06115)(0.281603,4.05999)
+ (0.282754,4.05888)(0.28396,4.05784)(0.285219,4.05687)
+ (0.286526,4.05596)(0.287879,4.05512)(0.289273,4.05436)
+ (0.290705,4.05367)(0.292171,4.05305)(0.293666,4.05252)
+ (0.295187,4.05206)(0.29673,4.05169)(0.29829,4.0514)
+ (0.299863,4.05119)(0.301444,4.05106)(0.30303,4.05102)
+ (0.304616,4.05106)(0.306198,4.05119)(0.307771,4.0514)
+ (0.309331,4.05169)(0.310873,4.05206)(0.312394,4.05252)
+ (0.31389,4.05305)(0.315356,4.05367)(0.316788,4.05436)
+ (0.318182,4.05512)(0.319535,4.05596)(0.320842,4.05687)
+ (0.322101,4.05784)(0.323307,4.05888)(0.324458,4.05999)
+ (0.32555,4.06115)(0.32658,4.06237)(0.327546,4.06364)
+ (0.328445,4.06496)(0.329273,4.06633)(0.330031,4.06773)
+ (0.330713,4.06918)(0.331321,4.07066)(0.33185,4.07217)
+ (0.332301,4.07371)(0.332671,4.07527)(0.33296,4.07684)
+ (0.333167,4.07843)(0.333292,4.08003)(0.333333,4.08163)
+\color{rgb_ffffff}%
+\path(0.393213,8.4408)(0.434232,8.46689)
+\path(0.382154,8.44823)(0.432391,8.48019)
+\path(0.37569,8.45859)(0.425927,8.49054)
+\path(0.373849,8.47189)(0.414867,8.49798)
+\path(0.432437,8.45872)(0.406237,8.49991)
+\path(0.425186,8.44747)(0.393089,8.49793)
+\path(0.414992,8.44085)(0.382895,8.4913)
+\path(0.401844,8.43887)(0.375643,8.48005)
+\color{rgb_000000}%
+\path(0.434343,8.46939)(0.434302,8.47099)(0.434177,8.47259)
+ (0.43397,8.47418)(0.433681,8.47575)(0.433311,8.47731)
+ (0.43286,8.47885)(0.432331,8.48036)(0.431724,8.48184)
+ (0.431041,8.48329)(0.430284,8.48469)(0.429455,8.48606)
+ (0.428556,8.48738)(0.42759,8.48865)(0.42656,8.48987)
+ (0.425468,8.49103)(0.424317,8.49214)(0.423111,8.49318)
+ (0.421852,8.49415)(0.420545,8.49506)(0.419192,8.4959)
+ (0.417798,8.49666)(0.416366,8.49735)(0.4149,8.49797)
+ (0.413405,8.4985)(0.411883,8.49896)(0.410341,8.49933)
+ (0.408781,8.49962)(0.407208,8.49983)(0.405626,8.49996)(0.40404,8.5)
+ (0.402454,8.49996)(0.400873,8.49983)(0.3993,8.49962)
+ (0.39774,8.49933)(0.396197,8.49896)(0.394676,8.4985)
+ (0.393181,8.49797)(0.391715,8.49735)(0.390283,8.49666)
+ (0.388889,8.4959)(0.387536,8.49506)(0.386229,8.49415)
+ (0.38497,8.49318)(0.383764,8.49214)(0.382613,8.49103)
+ (0.381521,8.48987)(0.380491,8.48865)(0.379525,8.48738)
+ (0.378626,8.48606)(0.377797,8.48469)(0.37704,8.48329)
+ (0.376357,8.48184)(0.37575,8.48036)(0.375221,8.47885)
+ (0.37477,8.47731)(0.3744,8.47575)(0.37411,8.47418)
+ (0.373903,8.47259)(0.373779,8.47099)(0.373737,8.46939)
+ (0.373779,8.46779)(0.373903,8.46619)(0.37411,8.4646)
+ (0.3744,8.46302)(0.37477,8.46146)(0.375221,8.45993)
+ (0.37575,8.45842)(0.376357,8.45694)(0.37704,8.45549)
+ (0.377797,8.45408)(0.378626,8.45272)(0.379525,8.45139)
+ (0.380491,8.45012)(0.381521,8.4489)(0.382613,8.44774)
+ (0.383764,8.44664)(0.38497,8.4456)(0.386229,8.44462)
+ (0.387536,8.44371)(0.388889,8.44288)(0.390283,8.44211)
+ (0.391715,8.44142)(0.393181,8.44081)(0.394676,8.44027)
+ (0.396197,8.43982)(0.39774,8.43944)(0.3993,8.43915)
+ (0.400873,8.43894)(0.402454,8.43882)(0.40404,8.43878)
+ (0.405626,8.43882)(0.407208,8.43894)(0.408781,8.43915)
+ (0.410341,8.43944)(0.411883,8.43982)(0.413405,8.44027)
+ (0.4149,8.44081)(0.416366,8.44142)(0.417798,8.44211)
+ (0.419192,8.44288)(0.420545,8.44371)(0.421852,8.44462)
+ (0.423111,8.4456)(0.424317,8.44664)(0.425468,8.44774)
+ (0.42656,8.4489)(0.42759,8.45012)(0.428556,8.45139)
+ (0.429455,8.45272)(0.430284,8.45408)(0.431041,8.45549)
+ (0.431724,8.45694)(0.432331,8.45842)(0.43286,8.45993)
+ (0.433311,8.46146)(0.433681,8.46302)(0.43397,8.4646)
+ (0.434177,8.46619)(0.434302,8.46779)(0.434343,8.46939)
+\color{rgb_ffffff}%
+\path(0.636352,1.12291)(0.597152,1.1517)
+\path(0.633635,1.10977)(0.585613,1.14503)
+\path(0.626508,1.09986)(0.578486,1.13513)
+\path(0.614969,1.0932)(0.57577,1.12199)
+\path(0.605901,1.15306)(0.577022,1.11373)
+\path(0.618878,1.15018)(0.583504,1.10201)
+\path(0.628617,1.14289)(0.593243,1.09472)
+\path(0.635099,1.13116)(0.606221,1.09184)
+\color{rgb_000000}%
+\path(0.636364,1.12245)(0.636322,1.12405)(0.636198,1.12565)
+ (0.635991,1.12724)(0.635701,1.12881)(0.635331,1.13037)
+ (0.634881,1.13191)(0.634351,1.13342)(0.633744,1.1349)
+ (0.633061,1.13635)(0.632304,1.13776)(0.631475,1.13912)
+ (0.630576,1.14044)(0.62961,1.14171)(0.62858,1.14293)
+ (0.627488,1.1441)(0.626337,1.1452)(0.625131,1.14624)
+ (0.623872,1.14721)(0.622565,1.14812)(0.621212,1.14896)
+ (0.619818,1.14972)(0.618386,1.15041)(0.61692,1.15103)
+ (0.615425,1.15156)(0.613904,1.15202)(0.612361,1.15239)
+ (0.610801,1.15268)(0.609228,1.15289)(0.607647,1.15302)
+ (0.606061,1.15306)(0.604475,1.15302)(0.602893,1.15289)
+ (0.60132,1.15268)(0.59976,1.15239)(0.598218,1.15202)
+ (0.596696,1.15156)(0.595201,1.15103)(0.593735,1.15041)
+ (0.592303,1.14972)(0.590909,1.14896)(0.589556,1.14812)
+ (0.588249,1.14721)(0.58699,1.14624)(0.585784,1.1452)
+ (0.584633,1.1441)(0.583541,1.14293)(0.582511,1.14171)
+ (0.581545,1.14044)(0.580646,1.13912)(0.579817,1.13776)
+ (0.57906,1.13635)(0.578377,1.1349)(0.57777,1.13342)
+ (0.577241,1.13191)(0.57679,1.13037)(0.57642,1.12881)
+ (0.576131,1.12724)(0.575924,1.12565)(0.575799,1.12405)
+ (0.575758,1.12245)(0.575799,1.12085)(0.575924,1.11925)
+ (0.576131,1.11766)(0.57642,1.11608)(0.57679,1.11453)
+ (0.577241,1.11299)(0.57777,1.11148)(0.578377,1.11)(0.57906,1.10855)
+ (0.579817,1.10714)(0.580646,1.10578)(0.581545,1.10446)
+ (0.582511,1.10318)(0.583541,1.10197)(0.584633,1.1008)
+ (0.585784,1.0997)(0.58699,1.09866)(0.588249,1.09768)
+ (0.589556,1.09678)(0.590909,1.09594)(0.592303,1.09517)
+ (0.593735,1.09448)(0.595201,1.09387)(0.596696,1.09334)
+ (0.598218,1.09288)(0.59976,1.09251)(0.60132,1.09221)
+ (0.602893,1.092)(0.604475,1.09188)(0.606061,1.09184)
+ (0.607647,1.09188)(0.609228,1.092)(0.610801,1.09221)
+ (0.612361,1.09251)(0.613904,1.09288)(0.615425,1.09334)
+ (0.61692,1.09387)(0.618386,1.09448)(0.619818,1.09517)
+ (0.621212,1.09594)(0.622565,1.09678)(0.623872,1.09768)
+ (0.625131,1.09866)(0.626337,1.0997)(0.627488,1.1008)
+ (0.62858,1.10197)(0.62961,1.10318)(0.630576,1.10446)
+ (0.631475,1.10578)(0.632304,1.10714)(0.633061,1.10855)
+ (0.633744,1.11)(0.634351,1.11148)(0.634881,1.11299)
+ (0.635331,1.11453)(0.635701,1.11608)(0.635991,1.11766)
+ (0.636198,1.11925)(0.636322,1.12085)(0.636364,1.12245)
+\color{rgb_ffffff}%
+\path(9.9888,5.4366)(9.9761,5.38935)
+\path(10.0019,5.43871)(9.98637,5.38083)
+\path(10.0136,5.4355)(9.99807,5.37762)
+\path(10.0239,5.42697)(10.0112,5.37972)
+\path(9.97191,5.39671)(10.0187,5.38412)
+\path(9.96975,5.40996)(10.0271,5.39454)
+\path(9.97287,5.42179)(10.0302,5.40637)
+\path(9.98126,5.43221)(10.0281,5.41962)
+\color{rgb_000000}%
+\path(10.0303,5.40816)(10.0303,5.40977)(10.0301,5.41136)
+ (10.0299,5.41295)(10.0296,5.41453)(10.0293,5.41609)
+ (10.0288,5.41762)(10.0283,5.41913)(10.0277,5.42061)(10.027,5.42206)
+ (10.0262,5.42347)(10.0254,5.42484)(10.0245,5.42616)
+ (10.0235,5.42743)(10.0225,5.42865)(10.0214,5.42981)
+ (10.0203,5.43091)(10.0191,5.43195)(10.0178,5.43293)
+ (10.0165,5.43384)(10.0152,5.43467)(10.0138,5.43544)
+ (10.0123,5.43613)(10.0109,5.43674)(10.0094,5.43728)
+ (10.0078,5.43773)(10.0063,5.43811)(10.0047,5.4384)(10.0032,5.43861)
+ (10.0016,5.43873)(10,5.43878)(9.99841,5.43873)(9.99683,5.43861)
+ (9.99526,5.4384)(9.9937,5.43811)(9.99216,5.43773)(9.99064,5.43728)
+ (9.98914,5.43674)(9.98767,5.43613)(9.98624,5.43544)
+ (9.98485,5.43467)(9.9835,5.43384)(9.98219,5.43293)(9.98093,5.43195)
+ (9.97972,5.43091)(9.97857,5.42981)(9.97748,5.42865)
+ (9.97645,5.42743)(9.97548,5.42616)(9.97459,5.42484)
+ (9.97376,5.42347)(9.973,5.42206)(9.97232,5.42061)(9.97171,5.41913)
+ (9.97118,5.41762)(9.97073,5.41609)(9.97036,5.41453)
+ (9.97007,5.41295)(9.96986,5.41136)(9.96974,5.40977)(9.9697,5.40816)
+ (9.96974,5.40656)(9.96986,5.40496)(9.97007,5.40337)(9.97036,5.4018)
+ (9.97073,5.40024)(9.97118,5.3987)(9.97171,5.39719)(9.97232,5.39571)
+ (9.973,5.39427)(9.97376,5.39286)(9.97459,5.39149)(9.97548,5.39017)
+ (9.97645,5.3889)(9.97748,5.38768)(9.97857,5.38652)(9.97972,5.38541)
+ (9.98093,5.38437)(9.98219,5.3834)(9.9835,5.38249)(9.98485,5.38165)
+ (9.98624,5.38089)(9.98767,5.3802)(9.98914,5.37958)(9.99064,5.37905)
+ (9.99216,5.37859)(9.9937,5.37822)(9.99526,5.37793)(9.99683,5.37772)
+ (9.99841,5.37759)(10,5.37755)(10.0016,5.37759)(10.0032,5.37772)
+ (10.0047,5.37793)(10.0063,5.37822)(10.0078,5.37859)
+ (10.0094,5.37905)(10.0109,5.37958)(10.0123,5.3802)(10.0138,5.38089)
+ (10.0152,5.38165)(10.0165,5.38249)(10.0178,5.3834)(10.0191,5.38437)
+ (10.0203,5.38541)(10.0214,5.38652)(10.0225,5.38768)(10.0235,5.3889)
+ (10.0245,5.39017)(10.0254,5.39149)(10.0262,5.39286)(10.027,5.39427)
+ (10.0277,5.39571)(10.0283,5.39719)(10.0288,5.3987)(10.0293,5.40024)
+ (10.0296,5.4018)(10.0299,5.40337)(10.0301,5.40496)(10.0303,5.40656)(10.0303,5.40816)
+\color{rgb_ffffff}%
+\path(8.56371,2.63218)(8.6119,2.63742)
+\path(8.55699,2.64377)(8.61602,2.65018)
+\path(8.5557,2.65594)(8.61473,2.66235)
+\path(8.55982,2.66871)(8.60801,2.67394)
+\path(8.60657,2.63073)(8.60129,2.6794)
+\path(8.59512,2.62392)(8.58865,2.68354)
+\path(8.58307,2.62259)(8.5766,2.68221)
+\path(8.57043,2.62672)(8.56514,2.67539)
+\color{rgb_000000}%
+\path(8.61616,2.65306)(8.61612,2.65466)(8.616,2.65626)
+ (8.61579,2.65785)(8.6155,2.65943)(8.61513,2.66098)(8.61468,2.66252)
+ (8.61415,2.66403)(8.61354,2.66551)(8.61286,2.66696)(8.6121,2.66837)
+ (8.61127,2.66973)(8.61037,2.67105)(8.60941,2.67233)
+ (8.60838,2.67354)(8.60729,2.67471)(8.60614,2.67581)
+ (8.60493,2.67685)(8.60367,2.67783)(8.60236,2.67873)
+ (8.60101,2.67957)(8.59962,2.68034)(8.59818,2.68103)
+ (8.59672,2.68164)(8.59522,2.68218)(8.5937,2.68263)(8.59216,2.683)
+ (8.5906,2.6833)(8.58903,2.68351)(8.58744,2.68363)(8.58586,2.68367)
+ (8.58427,2.68363)(8.58269,2.68351)(8.58112,2.6833)(8.57956,2.683)
+ (8.57802,2.68263)(8.57649,2.68218)(8.575,2.68164)(8.57353,2.68103)
+ (8.5721,2.68034)(8.57071,2.67957)(8.56935,2.67873)(8.56805,2.67783)
+ (8.56679,2.67685)(8.56558,2.67581)(8.56443,2.67471)
+ (8.56334,2.67354)(8.56231,2.67233)(8.56134,2.67105)
+ (8.56044,2.66973)(8.55962,2.66837)(8.55886,2.66696)
+ (8.55818,2.66551)(8.55757,2.66403)(8.55704,2.66252)
+ (8.55659,2.66098)(8.55622,2.65943)(8.55593,2.65785)
+ (8.55572,2.65626)(8.5556,2.65466)(8.55556,2.65306)(8.5556,2.65146)
+ (8.55572,2.64986)(8.55593,2.64827)(8.55622,2.6467)(8.55659,2.64514)
+ (8.55704,2.6436)(8.55757,2.64209)(8.55818,2.64061)(8.55886,2.63916)
+ (8.55962,2.63776)(8.56044,2.63639)(8.56134,2.63507)(8.56231,2.6338)
+ (8.56334,2.63258)(8.56443,2.63142)(8.56558,2.63031)
+ (8.56679,2.62927)(8.56805,2.6283)(8.56935,2.62739)(8.57071,2.62655)
+ (8.5721,2.62579)(8.57353,2.6251)(8.575,2.62448)(8.57649,2.62395)
+ (8.57802,2.62349)(8.57956,2.62312)(8.58112,2.62283)
+ (8.58269,2.62262)(8.58427,2.62249)(8.58586,2.62245)
+ (8.58744,2.62249)(8.58903,2.62262)(8.5906,2.62283)(8.59216,2.62312)
+ (8.5937,2.62349)(8.59522,2.62395)(8.59672,2.62448)(8.59818,2.6251)
+ (8.59962,2.62579)(8.60101,2.62655)(8.60236,2.62739)(8.60367,2.6283)
+ (8.60493,2.62927)(8.60614,2.63031)(8.60729,2.63142)
+ (8.60838,2.63258)(8.60941,2.6338)(8.61037,2.63507)(8.61127,2.63639)
+ (8.6121,2.63776)(8.61286,2.63916)(8.61354,2.64061)(8.61415,2.64209)
+ (8.61468,2.6436)(8.61513,2.64514)(8.6155,2.6467)(8.61579,2.64827)
+ (8.616,2.64986)(8.61612,2.65146)(8.61616,2.65306)
+\color{rgb_ffffff}%
+\path(6.28998,6.10931)(6.26746,6.15267)
+\path(6.28179,6.09874)(6.2542,6.15184)
+\path(6.27105,6.09305)(6.24347,6.14616)
+\path(6.25779,6.09223)(6.23527,6.13559)
+\path(6.27586,6.14998)(6.23276,6.12759)
+\path(6.28626,6.14161)(6.23346,6.11418)
+\path(6.2918,6.13071)(6.23899,6.10329)
+\path(6.29249,6.11731)(6.24939,6.09492)
+\color{rgb_000000}%
+\path(6.29293,6.12245)(6.29289,6.12405)(6.29276,6.12565)
+ (6.29256,6.12724)(6.29227,6.12881)(6.2919,6.13037)(6.29145,6.13191)
+ (6.29092,6.13342)(6.29031,6.1349)(6.28963,6.13635)(6.28887,6.13776)
+ (6.28804,6.13912)(6.28714,6.14044)(6.28618,6.14171)
+ (6.28515,6.14293)(6.28405,6.1441)(6.2829,6.1452)(6.2817,6.14624)
+ (6.28044,6.14721)(6.27913,6.14812)(6.27778,6.14896)
+ (6.27638,6.14972)(6.27495,6.15041)(6.27349,6.15103)
+ (6.27199,6.15156)(6.27047,6.15202)(6.26893,6.15239)
+ (6.26737,6.15268)(6.26579,6.15289)(6.26421,6.15302)
+ (6.26263,6.15306)(6.26104,6.15302)(6.25946,6.15289)
+ (6.25789,6.15268)(6.25633,6.15239)(6.25478,6.15202)
+ (6.25326,6.15156)(6.25177,6.15103)(6.2503,6.15041)(6.24887,6.14972)
+ (6.24747,6.14896)(6.24612,6.14812)(6.24481,6.14721)
+ (6.24356,6.14624)(6.24235,6.1452)(6.2412,6.1441)(6.24011,6.14293)
+ (6.23908,6.14171)(6.23811,6.14044)(6.23721,6.13912)
+ (6.23638,6.13776)(6.23563,6.13635)(6.23494,6.1349)(6.23434,6.13342)
+ (6.23381,6.13191)(6.23336,6.13037)(6.23299,6.12881)(6.2327,6.12724)
+ (6.23249,6.12565)(6.23236,6.12405)(6.23232,6.12245)
+ (6.23236,6.12085)(6.23249,6.11925)(6.2327,6.11766)(6.23299,6.11608)
+ (6.23336,6.11453)(6.23381,6.11299)(6.23434,6.11148)(6.23494,6.11)
+ (6.23563,6.10855)(6.23638,6.10714)(6.23721,6.10578)
+ (6.23811,6.10446)(6.23908,6.10318)(6.24011,6.10197)(6.2412,6.1008)
+ (6.24235,6.0997)(6.24356,6.09866)(6.24481,6.09768)(6.24612,6.09678)
+ (6.24747,6.09594)(6.24887,6.09517)(6.2503,6.09448)(6.25177,6.09387)
+ (6.25326,6.09334)(6.25478,6.09288)(6.25633,6.09251)
+ (6.25789,6.09221)(6.25946,6.092)(6.26104,6.09188)(6.26263,6.09184)
+ (6.26421,6.09188)(6.26579,6.092)(6.26737,6.09221)(6.26893,6.09251)
+ (6.27047,6.09288)(6.27199,6.09334)(6.27349,6.09387)
+ (6.27495,6.09448)(6.27638,6.09517)(6.27778,6.09594)
+ (6.27913,6.09678)(6.28044,6.09768)(6.2817,6.09866)(6.2829,6.0997)
+ (6.28405,6.1008)(6.28515,6.10197)(6.28618,6.10318)(6.28714,6.10446)
+ (6.28804,6.10578)(6.28887,6.10714)(6.28963,6.10855)(6.29031,6.11)
+ (6.29092,6.11148)(6.29145,6.11299)(6.2919,6.11453)(6.29227,6.11608)
+ (6.29256,6.11766)(6.29276,6.11925)(6.29289,6.12085)(6.29293,6.12245)
+\color{rgb_ffffff}%
+\path(0.204509,6.76519)(0.172334,6.72858)
+\path(0.217199,6.76119)(0.177782,6.71633)
+\path(0.226258,6.75305)(0.186842,6.7082)
+\path(0.231707,6.74081)(0.199531,6.7042)
+\path(0.171806,6.7369)(0.208379,6.70476)
+\path(0.175646,6.74976)(0.220436,6.7104)
+\path(0.183604,6.75899)(0.228394,6.71963)
+\path(0.195661,6.76462)(0.232234,6.73248)
+\color{rgb_000000}%
+\path(0.232323,6.73469)(0.232282,6.7363)(0.232157,6.73789)
+ (0.23195,6.73948)(0.231661,6.74106)(0.231291,6.74262)
+ (0.23084,6.74415)(0.230311,6.74566)(0.229703,6.74714)
+ (0.22902,6.74859)(0.228263,6.75)(0.227434,6.75137)
+ (0.226536,6.75269)(0.22557,6.75396)(0.22454,6.75518)
+ (0.223448,6.75634)(0.222297,6.75744)(0.221091,6.75848)
+ (0.219832,6.75946)(0.218524,6.76037)(0.217172,6.7612)
+ (0.215777,6.76197)(0.214346,6.76266)(0.21288,6.76327)
+ (0.211384,6.76381)(0.209863,6.76426)(0.208321,6.76464)
+ (0.206761,6.76493)(0.205188,6.76514)(0.203606,6.76526)
+ (0.20202,6.76531)(0.200434,6.76526)(0.198853,6.76514)
+ (0.19728,6.76493)(0.19572,6.76464)(0.194177,6.76426)
+ (0.192656,6.76381)(0.191161,6.76327)(0.189695,6.76266)
+ (0.188263,6.76197)(0.186869,6.7612)(0.185516,6.76037)
+ (0.184209,6.75946)(0.18295,6.75848)(0.181744,6.75744)
+ (0.180593,6.75634)(0.179501,6.75518)(0.17847,6.75396)
+ (0.177505,6.75269)(0.176606,6.75137)(0.175777,6.75)
+ (0.17502,6.74859)(0.174337,6.74714)(0.17373,6.74566)
+ (0.1732,6.74415)(0.17275,6.74262)(0.172379,6.74106)
+ (0.17209,6.73948)(0.171883,6.73789)(0.171759,6.7363)
+ (0.171717,6.73469)(0.171759,6.73309)(0.171883,6.73149)
+ (0.17209,6.72991)(0.172379,6.72833)(0.17275,6.72677)
+ (0.1732,6.72523)(0.17373,6.72372)(0.174337,6.72224)(0.17502,6.7208)
+ (0.175777,6.71939)(0.176606,6.71802)(0.177505,6.7167)
+ (0.17847,6.71543)(0.179501,6.71421)(0.180593,6.71305)
+ (0.181744,6.71194)(0.18295,6.7109)(0.184209,6.70993)
+ (0.185516,6.70902)(0.186869,6.70818)(0.188263,6.70742)
+ (0.189695,6.70673)(0.191161,6.70611)(0.192656,6.70558)
+ (0.194177,6.70512)(0.19572,6.70475)(0.19728,6.70446)
+ (0.198853,6.70425)(0.200434,6.70412)(0.20202,6.70408)
+ (0.203606,6.70412)(0.205188,6.70425)(0.206761,6.70446)
+ (0.208321,6.70475)(0.209863,6.70512)(0.211384,6.70558)
+ (0.21288,6.70611)(0.214346,6.70673)(0.215777,6.70742)
+ (0.217172,6.70818)(0.218524,6.70902)(0.219832,6.70993)
+ (0.221091,6.7109)(0.222297,6.71194)(0.223448,6.71305)
+ (0.22454,6.71421)(0.22557,6.71543)(0.226536,6.7167)
+ (0.227434,6.71802)(0.228263,6.71939)(0.22902,6.7208)
+ (0.229703,6.72224)(0.230311,6.72372)(0.23084,6.72523)
+ (0.231291,6.72677)(0.231661,6.72833)(0.23195,6.72991)
+ (0.232157,6.73149)(0.232282,6.73309)(0.232323,6.73469)
+\color{rgb_ffffff}%
+\path(8.96093,5.29718)(9.00652,5.28053)
+\path(8.95992,5.31056)(9.01575,5.29017)
+\path(8.96405,5.32207)(9.01987,5.30168)
+\path(8.97328,5.33172)(9.01887,5.31507)
+\path(8.99857,5.2768)(9.01535,5.32274)
+\path(8.98531,5.27587)(9.00586,5.33213)
+\path(8.97394,5.28011)(8.99449,5.33638)
+\path(8.96445,5.2895)(8.98123,5.33544)
+\color{rgb_000000}%
+\path(9.0202,5.30612)(9.02016,5.30772)(9.02004,5.30932)
+ (9.01983,5.31091)(9.01954,5.31249)(9.01917,5.31405)
+ (9.01872,5.31558)(9.01819,5.31709)(9.01758,5.31857)(9.0169,5.32002)
+ (9.01614,5.32143)(9.01531,5.3228)(9.01441,5.32412)(9.01345,5.32539)
+ (9.01242,5.32661)(9.01133,5.32777)(9.01018,5.32887)
+ (9.00897,5.32991)(9.00771,5.33089)(9.0064,5.3318)(9.00505,5.33263)
+ (9.00366,5.3334)(9.00222,5.33409)(9.00076,5.3347)(8.99926,5.33524)
+ (8.99774,5.33569)(8.9962,5.33607)(8.99464,5.33636)(8.99307,5.33657)
+ (8.99148,5.33669)(8.9899,5.33673)(8.98831,5.33669)(8.98673,5.33657)
+ (8.98516,5.33636)(8.9836,5.33607)(8.98206,5.33569)(8.98053,5.33524)
+ (8.97904,5.3347)(8.97757,5.33409)(8.97614,5.3334)(8.97475,5.33263)
+ (8.97339,5.3318)(8.97209,5.33089)(8.97083,5.32991)(8.96962,5.32887)
+ (8.96847,5.32777)(8.96738,5.32661)(8.96635,5.32539)
+ (8.96538,5.32412)(8.96448,5.3228)(8.96366,5.32143)(8.9629,5.32002)
+ (8.96222,5.31857)(8.96161,5.31709)(8.96108,5.31558)
+ (8.96063,5.31405)(8.96026,5.31249)(8.95997,5.31091)
+ (8.95976,5.30932)(8.95964,5.30772)(8.9596,5.30612)(8.95964,5.30452)
+ (8.95976,5.30292)(8.95997,5.30133)(8.96026,5.29976)(8.96063,5.2982)
+ (8.96108,5.29666)(8.96161,5.29515)(8.96222,5.29367)(8.9629,5.29222)
+ (8.96366,5.29082)(8.96448,5.28945)(8.96538,5.28813)
+ (8.96635,5.28686)(8.96738,5.28564)(8.96847,5.28448)
+ (8.96962,5.28337)(8.97083,5.28233)(8.97209,5.28136)
+ (8.97339,5.28045)(8.97475,5.27961)(8.97614,5.27885)
+ (8.97757,5.27816)(8.97904,5.27754)(8.98053,5.27701)
+ (8.98206,5.27655)(8.9836,5.27618)(8.98516,5.27589)(8.98673,5.27568)
+ (8.98831,5.27555)(8.9899,5.27551)(8.99148,5.27555)(8.99307,5.27568)
+ (8.99464,5.27589)(8.9962,5.27618)(8.99774,5.27655)(8.99926,5.27701)
+ (9.00076,5.27754)(9.00222,5.27816)(9.00366,5.27885)
+ (9.00505,5.27961)(9.0064,5.28045)(9.00771,5.28136)(9.00897,5.28233)
+ (9.01018,5.28337)(9.01133,5.28448)(9.01242,5.28564)
+ (9.01345,5.28686)(9.01441,5.28813)(9.01531,5.28945)
+ (9.01614,5.29082)(9.0169,5.29222)(9.01758,5.29367)(9.01819,5.29515)
+ (9.01872,5.29666)(9.01917,5.2982)(9.01954,5.29976)(9.01983,5.30133)
+ (9.02004,5.30292)(9.02016,5.30452)(9.0202,5.30612)
+\color{rgb_ffffff}%
+\path(9.31161,0.28203)(9.3106,0.330988)
+\path(9.29961,0.276271)(9.29837,0.336227)
+\path(9.28749,0.276018)(9.28625,0.335974)
+\path(9.27526,0.281257)(9.27425,0.330215)
+\path(9.31679,0.324983)(9.26832,0.323981)
+\path(9.32248,0.312856)(9.26313,0.311629)
+\path(9.32273,0.300616)(9.26338,0.299389)
+\path(9.31754,0.288264)(9.26907,0.287262)
+\color{rgb_000000}%
+\path(9.32323,0.306122)(9.32319,0.307725)(9.32307,0.309322)
+ (9.32286,0.310911)(9.32257,0.312487)(9.3222,0.314045)
+ (9.32175,0.315582)(9.32122,0.317093)(9.32061,0.318574)
+ (9.31993,0.32002)(9.31917,0.321429)(9.31834,0.322795)
+ (9.31744,0.324116)(9.31648,0.325387)(9.31545,0.326606)
+ (9.31436,0.327769)(9.31321,0.328872)(9.312,0.329913)
+ (9.31074,0.330888)(9.30943,0.331796)(9.30808,0.332633)
+ (9.30669,0.333398)(9.30525,0.334088)(9.30379,0.334701)
+ (9.30229,0.335236)(9.30077,0.335692)(9.29923,0.336066)
+ (9.29767,0.336358)(9.2961,0.336567)(9.29452,0.336693)
+ (9.29293,0.336735)(9.29134,0.336693)(9.28976,0.336567)
+ (9.28819,0.336358)(9.28663,0.336066)(9.28509,0.335692)
+ (9.28357,0.335236)(9.28207,0.334701)(9.2806,0.334088)
+ (9.27917,0.333398)(9.27778,0.332633)(9.27643,0.331796)
+ (9.27512,0.330888)(9.27386,0.329913)(9.27265,0.328872)
+ (9.2715,0.327769)(9.27041,0.326606)(9.26938,0.325387)
+ (9.26841,0.324116)(9.26752,0.322795)(9.26669,0.321429)
+ (9.26593,0.32002)(9.26525,0.318574)(9.26464,0.317093)
+ (9.26411,0.315582)(9.26366,0.314045)(9.26329,0.312487)
+ (9.263,0.310911)(9.26279,0.309322)(9.26267,0.307725)
+ (9.26263,0.306122)(9.26267,0.30452)(9.26279,0.302923)
+ (9.263,0.301334)(9.26329,0.299758)(9.26366,0.298199)
+ (9.26411,0.296663)(9.26464,0.295152)(9.26525,0.293671)
+ (9.26593,0.292225)(9.26669,0.290816)(9.26752,0.28945)
+ (9.26841,0.288129)(9.26938,0.286858)(9.27041,0.285639)
+ (9.2715,0.284476)(9.27265,0.283373)(9.27386,0.282332)
+ (9.27512,0.281357)(9.27643,0.280449)(9.27778,0.279611)
+ (9.27917,0.278847)(9.2806,0.278157)(9.28207,0.277543)
+ (9.28357,0.277008)(9.28509,0.276553)(9.28663,0.276179)
+ (9.28819,0.275887)(9.28976,0.275678)(9.29134,0.275552)
+ (9.29293,0.27551)(9.29452,0.275552)(9.2961,0.275678)
+ (9.29767,0.275887)(9.29923,0.276179)(9.30077,0.276553)
+ (9.30229,0.277008)(9.30379,0.277543)(9.30525,0.278157)
+ (9.30669,0.278847)(9.30808,0.279611)(9.30943,0.280449)
+ (9.31074,0.281357)(9.312,0.282332)(9.31321,0.283373)
+ (9.31436,0.284476)(9.31545,0.285639)(9.31648,0.286858)
+ (9.31744,0.288129)(9.31834,0.28945)(9.31917,0.290816)
+ (9.31993,0.292225)(9.32061,0.293671)(9.32122,0.295152)
+ (9.32175,0.296663)(9.3222,0.298199)(9.32257,0.299758)
+ (9.32286,0.301334)(9.32307,0.302923)(9.32319,0.30452)(9.32323,0.306122)
+\color{rgb_ffffff}%
+\path(2.03576,3.39361)(1.99089,3.37508)
+\path(2.04539,3.38436)(1.99043,3.36167)
+\path(2.04997,3.37302)(1.99502,3.35034)
+\path(2.04952,3.35961)(2.00464,3.34109)
+\path(1.9941,3.38288)(2.01275,3.33768)
+\path(2.00319,3.39267)(2.02603,3.33732)
+\path(2.01437,3.39738)(2.03722,3.34203)
+\path(2.02765,3.39701)(2.04631,3.35181)
+\color{rgb_000000}%
+\path(2.05051,3.36735)(2.05046,3.36895)(2.05034,3.37055)
+ (2.05013,3.37214)(2.04984,3.37371)(2.04947,3.37527)
+ (2.04902,3.37681)(2.04849,3.37832)(2.04789,3.3798)(2.0472,3.38124)
+ (2.04645,3.38265)(2.04562,3.38402)(2.04472,3.38534)
+ (2.04375,3.38661)(2.04272,3.38783)(2.04163,3.38899)(2.04048,3.3901)
+ (2.03927,3.39114)(2.03801,3.39211)(2.03671,3.39302)
+ (2.03535,3.39386)(2.03396,3.39462)(2.03253,3.39531)
+ (2.03106,3.39593)(2.02957,3.39646)(2.02805,3.39692)(2.0265,3.39729)
+ (2.02494,3.39758)(2.02337,3.39779)(2.02179,3.39792)(2.0202,3.39796)
+ (2.01862,3.39792)(2.01703,3.39779)(2.01546,3.39758)(2.0139,3.39729)
+ (2.01236,3.39692)(2.01084,3.39646)(2.00934,3.39593)
+ (2.00788,3.39531)(2.00644,3.39462)(2.00505,3.39386)(2.0037,3.39302)
+ (2.00239,3.39211)(2.00113,3.39114)(1.99993,3.3901)(1.99877,3.38899)
+ (1.99768,3.38783)(1.99665,3.38661)(1.99569,3.38534)
+ (1.99479,3.38402)(1.99396,3.38265)(1.9932,3.38124)(1.99252,3.3798)
+ (1.99191,3.37832)(1.99138,3.37681)(1.99093,3.37527)
+ (1.99056,3.37371)(1.99027,3.37214)(1.99006,3.37055)
+ (1.98994,3.36895)(1.9899,3.36735)(1.98994,3.36574)(1.99006,3.36415)
+ (1.99027,3.36256)(1.99056,3.36098)(1.99093,3.35942)
+ (1.99138,3.35789)(1.99191,3.35638)(1.99252,3.3549)(1.9932,3.35345)
+ (1.99396,3.35204)(1.99479,3.35067)(1.99569,3.34935)
+ (1.99665,3.34808)(1.99768,3.34686)(1.99877,3.3457)(1.99993,3.3446)
+ (2.00113,3.34356)(2.00239,3.34258)(2.0037,3.34167)(2.00505,3.34084)
+ (2.00644,3.34007)(2.00788,3.33938)(2.00934,3.33877)
+ (2.01084,3.33823)(2.01236,3.33778)(2.0139,3.3374)(2.01546,3.33711)
+ (2.01703,3.3369)(2.01862,3.33678)(2.0202,3.33673)(2.02179,3.33678)
+ (2.02337,3.3369)(2.02494,3.33711)(2.0265,3.3374)(2.02805,3.33778)
+ (2.02957,3.33823)(2.03106,3.33877)(2.03253,3.33938)
+ (2.03396,3.34007)(2.03535,3.34084)(2.03671,3.34167)
+ (2.03801,3.34258)(2.03927,3.34356)(2.04048,3.3446)(2.04163,3.3457)
+ (2.04272,3.34686)(2.04375,3.34808)(2.04472,3.34935)
+ (2.04562,3.35067)(2.04645,3.35204)(2.0472,3.35345)(2.04789,3.3549)
+ (2.04849,3.35638)(2.04902,3.35789)(2.04947,3.35942)
+ (2.04984,3.36098)(2.05013,3.36256)(2.05034,3.36415)
+ (2.05046,3.36574)(2.05051,3.36735)
+\color{rgb_ffffff}%
+\path(9.46504,0.41304)(9.49869,0.377795)
+\path(9.46998,0.425494)(9.5112,0.38233)
+\path(9.4787,0.433996)(9.51992,0.390833)
+\path(9.49121,0.438532)(9.52486,0.403287)
+\path(9.48982,0.378001)(9.52505,0.411639)
+\path(9.47754,0.383118)(9.52068,0.424311)
+\path(9.46922,0.392015)(9.51236,0.433208)
+\path(9.46485,0.404688)(9.50008,0.438326)
+\color{rgb_000000}%
+\path(9.52525,0.408163)(9.52521,0.409765)(9.52509,0.411363)
+ (9.52488,0.412952)(9.52459,0.414528)(9.52422,0.416086)
+ (9.52377,0.417623)(9.52324,0.419134)(9.52263,0.420614)
+ (9.52195,0.422061)(9.52119,0.423469)(9.52036,0.424836)
+ (9.51947,0.426157)(9.5185,0.427428)(9.51747,0.428647)
+ (9.51638,0.429809)(9.51523,0.430913)(9.51402,0.431953)
+ (9.51276,0.432929)(9.51145,0.433837)(9.5101,0.434674)
+ (9.50871,0.435439)(9.50727,0.436129)(9.50581,0.436742)
+ (9.50431,0.437277)(9.50279,0.437732)(9.50125,0.438107)
+ (9.49969,0.438399)(9.49812,0.438608)(9.49654,0.438734)
+ (9.49495,0.438776)(9.49336,0.438734)(9.49178,0.438608)
+ (9.49021,0.438399)(9.48865,0.438107)(9.48711,0.437732)
+ (9.48559,0.437277)(9.48409,0.436742)(9.48262,0.436129)
+ (9.48119,0.435439)(9.4798,0.434674)(9.47845,0.433837)
+ (9.47714,0.432929)(9.47588,0.431953)(9.47467,0.430913)
+ (9.47352,0.429809)(9.47243,0.428647)(9.4714,0.427428)
+ (9.47043,0.426157)(9.46954,0.424836)(9.46871,0.423469)
+ (9.46795,0.422061)(9.46727,0.420614)(9.46666,0.419134)
+ (9.46613,0.417623)(9.46568,0.416086)(9.46531,0.414528)
+ (9.46502,0.412952)(9.46481,0.411363)(9.46469,0.409765)
+ (9.46465,0.408163)(9.46469,0.406561)(9.46481,0.404963)
+ (9.46502,0.403374)(9.46531,0.401799)(9.46568,0.40024)
+ (9.46613,0.398704)(9.46666,0.397193)(9.46727,0.395712)
+ (9.46795,0.394266)(9.46871,0.392857)(9.46954,0.391491)
+ (9.47043,0.39017)(9.4714,0.388898)(9.47243,0.38768)
+ (9.47352,0.386517)(9.47467,0.385414)(9.47588,0.384373)
+ (9.47714,0.383397)(9.47845,0.38249)(9.4798,0.381652)
+ (9.48119,0.380888)(9.48262,0.380198)(9.48409,0.379584)
+ (9.48559,0.379049)(9.48711,0.378594)(9.48865,0.37822)
+ (9.49021,0.377928)(9.49178,0.377719)(9.49336,0.377593)
+ (9.49495,0.377551)(9.49654,0.377593)(9.49812,0.377719)
+ (9.49969,0.377928)(9.50125,0.37822)(9.50279,0.378594)
+ (9.50431,0.379049)(9.50581,0.379584)(9.50727,0.380198)
+ (9.50871,0.380888)(9.5101,0.381652)(9.51145,0.38249)
+ (9.51276,0.383397)(9.51402,0.384373)(9.51523,0.385414)
+ (9.51638,0.386517)(9.51747,0.38768)(9.5185,0.388898)
+ (9.51947,0.39017)(9.52036,0.391491)(9.52119,0.392857)
+ (9.52195,0.394266)(9.52263,0.395712)(9.52324,0.397193)
+ (9.52377,0.398704)(9.52422,0.40024)(9.52459,0.401799)
+ (9.52488,0.403374)(9.52509,0.404963)(9.52521,0.406561)(9.52525,0.408163)
+\color{rgb_ffffff}%
+\path(5.15759,9.56185)(5.17831,9.60612)
+\path(5.14431,9.56211)(5.16968,9.61633)
+\path(5.13335,9.56734)(5.15872,9.62156)
+\path(5.12472,9.57755)(5.14544,9.62182)
+\path(5.18115,9.59821)(5.13717,9.61879)
+\path(5.18099,9.58479)(5.12713,9.61)
+\path(5.1759,9.57368)(5.12204,9.59888)
+\path(5.16586,9.56488)(5.12188,9.58547)
+\color{rgb_000000}%
+\path(5.18182,9.59184)(5.18178,9.59344)(5.18165,9.59504)
+ (5.18145,9.59663)(5.18116,9.5982)(5.18079,9.59976)(5.18034,9.6013)
+ (5.17981,9.60281)(5.1792,9.60429)(5.17852,9.60573)(5.17776,9.60714)
+ (5.17693,9.60851)(5.17603,9.60983)(5.17507,9.6111)(5.17403,9.61232)
+ (5.17294,9.61348)(5.17179,9.61459)(5.17059,9.61563)(5.16933,9.6166)
+ (5.16802,9.61751)(5.16667,9.61835)(5.16527,9.61911)(5.16384,9.6198)
+ (5.16237,9.62042)(5.16088,9.62095)(5.15936,9.62141)
+ (5.15782,9.62178)(5.15626,9.62207)(5.15468,9.62228)(5.1531,9.62241)
+ (5.15152,9.62245)(5.14993,9.62241)(5.14835,9.62228)
+ (5.14677,9.62207)(5.14521,9.62178)(5.14367,9.62141)
+ (5.14215,9.62095)(5.14066,9.62042)(5.13919,9.6198)(5.13776,9.61911)
+ (5.13636,9.61835)(5.13501,9.61751)(5.1337,9.6166)(5.13244,9.61563)
+ (5.13124,9.61459)(5.13009,9.61348)(5.129,9.61232)(5.12797,9.6111)
+ (5.127,9.60983)(5.1261,9.60851)(5.12527,9.60714)(5.12451,9.60573)
+ (5.12383,9.60429)(5.12322,9.60281)(5.1227,9.6013)(5.12224,9.59976)
+ (5.12187,9.5982)(5.12159,9.59663)(5.12138,9.59504)(5.12125,9.59344)
+ (5.12121,9.59184)(5.12125,9.59023)(5.12138,9.58864)
+ (5.12159,9.58705)(5.12187,9.58547)(5.12224,9.58391)(5.1227,9.58238)
+ (5.12322,9.58087)(5.12383,9.57939)(5.12451,9.57794)
+ (5.12527,9.57653)(5.1261,9.57516)(5.127,9.57384)(5.12797,9.57257)
+ (5.129,9.57135)(5.13009,9.57019)(5.13124,9.56909)(5.13244,9.56805)
+ (5.1337,9.56707)(5.13501,9.56616)(5.13636,9.56533)(5.13776,9.56456)
+ (5.13919,9.56387)(5.14066,9.56326)(5.14215,9.56272)
+ (5.14367,9.56227)(5.14521,9.56189)(5.14677,9.5616)(5.14835,9.56139)
+ (5.14993,9.56127)(5.15152,9.56122)(5.1531,9.56127)(5.15468,9.56139)
+ (5.15626,9.5616)(5.15782,9.56189)(5.15936,9.56227)(5.16088,9.56272)
+ (5.16237,9.56326)(5.16384,9.56387)(5.16527,9.56456)
+ (5.16667,9.56533)(5.16802,9.56616)(5.16933,9.56707)
+ (5.17059,9.56805)(5.17179,9.56909)(5.17294,9.57019)
+ (5.17403,9.57135)(5.17507,9.57257)(5.17603,9.57384)
+ (5.17693,9.57516)(5.17776,9.57653)(5.17852,9.57794)(5.1792,9.57939)
+ (5.17981,9.58087)(5.18034,9.58238)(5.18079,9.58391)
+ (5.18116,9.58547)(5.18145,9.58705)(5.18165,9.58864)
+ (5.18178,9.59023)(5.18182,9.59184)
+\color{rgb_ffffff}%
+\path(10.0254,1.54732)(9.97702,1.55056)
+\path(10.03,1.53474)(9.97078,1.5387)
+\path(10.0292,1.52252)(9.96998,1.52649)
+\path(10.023,1.51067)(9.97461,1.51391)
+\path(9.9835,1.55629)(9.98023,1.50743)
+\path(9.99596,1.56094)(9.99195,1.50111)
+\path(10.008,1.56012)(10.004,1.50028)
+\path(10.0198,1.5538)(10.0165,1.50494)
+\color{rgb_000000}%
+\path(10.0303,1.53061)(10.0303,1.53221)(10.0301,1.53381)
+ (10.0299,1.5354)(10.0296,1.53698)(10.0293,1.53854)(10.0288,1.54007)
+ (10.0283,1.54158)(10.0277,1.54306)(10.027,1.54451)(10.0262,1.54592)
+ (10.0254,1.54728)(10.0245,1.54861)(10.0235,1.54988)(10.0225,1.5511)
+ (10.0214,1.55226)(10.0203,1.55336)(10.0191,1.5544)(10.0178,1.55538)
+ (10.0165,1.55629)(10.0152,1.55712)(10.0138,1.55789)
+ (10.0123,1.55858)(10.0109,1.55919)(10.0094,1.55973)
+ (10.0078,1.56018)(10.0063,1.56056)(10.0047,1.56085)
+ (10.0032,1.56106)(10.0016,1.56118)(10,1.56122)(9.99841,1.56118)
+ (9.99683,1.56106)(9.99526,1.56085)(9.9937,1.56056)(9.99216,1.56018)
+ (9.99064,1.55973)(9.98914,1.55919)(9.98767,1.55858)
+ (9.98624,1.55789)(9.98485,1.55712)(9.9835,1.55629)(9.98219,1.55538)
+ (9.98093,1.5544)(9.97972,1.55336)(9.97857,1.55226)(9.97748,1.5511)
+ (9.97645,1.54988)(9.97548,1.54861)(9.97459,1.54728)
+ (9.97376,1.54592)(9.973,1.54451)(9.97232,1.54306)(9.97171,1.54158)
+ (9.97118,1.54007)(9.97073,1.53854)(9.97036,1.53698)(9.97007,1.5354)
+ (9.96986,1.53381)(9.96974,1.53221)(9.9697,1.53061)(9.96974,1.52901)
+ (9.96986,1.52741)(9.97007,1.52582)(9.97036,1.52425)
+ (9.97073,1.52269)(9.97118,1.52115)(9.97171,1.51964)
+ (9.97232,1.51816)(9.973,1.51671)(9.97376,1.51531)(9.97459,1.51394)
+ (9.97548,1.51262)(9.97645,1.51135)(9.97748,1.51013)
+ (9.97857,1.50897)(9.97972,1.50786)(9.98093,1.50682)
+ (9.98219,1.50585)(9.9835,1.50494)(9.98485,1.5041)(9.98624,1.50334)
+ (9.98767,1.50265)(9.98914,1.50203)(9.99064,1.5015)(9.99216,1.50104)
+ (9.9937,1.50067)(9.99526,1.50038)(9.99683,1.50017)(9.99841,1.50004)
+ (10,1.5)(10.0016,1.50004)(10.0032,1.50017)(10.0047,1.50038)
+ (10.0063,1.50067)(10.0078,1.50104)(10.0094,1.5015)(10.0109,1.50203)
+ (10.0123,1.50265)(10.0138,1.50334)(10.0152,1.5041)(10.0165,1.50494)
+ (10.0178,1.50585)(10.0191,1.50682)(10.0203,1.50786)
+ (10.0214,1.50897)(10.0225,1.51013)(10.0235,1.51135)
+ (10.0245,1.51262)(10.0254,1.51394)(10.0262,1.51531)(10.027,1.51671)
+ (10.0277,1.51816)(10.0283,1.51964)(10.0288,1.52115)
+ (10.0293,1.52269)(10.0296,1.52425)(10.0299,1.52582)
+ (10.0301,1.52741)(10.0303,1.52901)(10.0303,1.53061)
+\color{rgb_ffffff}%
+\path(0.581408,4.40555)(0.596048,4.35887)
+\path(0.591317,4.41449)(0.609252,4.35731)
+\path(0.60287,4.4182)(0.620804,4.36102)
+\path(0.616074,4.41664)(0.630713,4.36996)
+\path(0.5883,4.36295)(0.634592,4.37747)
+\path(0.579512,4.37302)(0.63621,4.3908)
+\path(0.575912,4.38471)(0.632609,4.40249)
+\path(0.577529,4.39804)(0.623821,4.41256)
+\color{rgb_000000}%
+\path(0.636364,4.38776)(0.636322,4.38936)(0.636198,4.39095)
+ (0.635991,4.39254)(0.635701,4.39412)(0.635331,4.39568)
+ (0.634881,4.39721)(0.634351,4.39873)(0.633744,4.40021)
+ (0.633061,4.40165)(0.632304,4.40306)(0.631475,4.40443)
+ (0.630576,4.40575)(0.62961,4.40702)(0.62858,4.40824)
+ (0.627488,4.4094)(0.626337,4.4105)(0.625131,4.41155)
+ (0.623872,4.41252)(0.622565,4.41343)(0.621212,4.41427)
+ (0.619818,4.41503)(0.618386,4.41572)(0.61692,4.41633)
+ (0.615425,4.41687)(0.613904,4.41732)(0.612361,4.4177)
+ (0.610801,4.41799)(0.609228,4.4182)(0.607647,4.41833)
+ (0.606061,4.41837)(0.604475,4.41833)(0.602893,4.4182)
+ (0.60132,4.41799)(0.59976,4.4177)(0.598218,4.41732)
+ (0.596696,4.41687)(0.595201,4.41633)(0.593735,4.41572)
+ (0.592303,4.41503)(0.590909,4.41427)(0.589556,4.41343)
+ (0.588249,4.41252)(0.58699,4.41155)(0.585784,4.4105)
+ (0.584633,4.4094)(0.583541,4.40824)(0.582511,4.40702)
+ (0.581545,4.40575)(0.580646,4.40443)(0.579817,4.40306)
+ (0.57906,4.40165)(0.578377,4.40021)(0.57777,4.39873)
+ (0.577241,4.39721)(0.57679,4.39568)(0.57642,4.39412)
+ (0.576131,4.39254)(0.575924,4.39095)(0.575799,4.38936)
+ (0.575758,4.38776)(0.575799,4.38615)(0.575924,4.38456)
+ (0.576131,4.38297)(0.57642,4.38139)(0.57679,4.37983)
+ (0.577241,4.3783)(0.57777,4.37678)(0.578377,4.3753)
+ (0.57906,4.37386)(0.579817,4.37245)(0.580646,4.37108)
+ (0.581545,4.36976)(0.582511,4.36849)(0.583541,4.36727)
+ (0.584633,4.36611)(0.585784,4.36501)(0.58699,4.36396)
+ (0.588249,4.36299)(0.589556,4.36208)(0.590909,4.36124)
+ (0.592303,4.36048)(0.593735,4.35979)(0.595201,4.35918)
+ (0.596696,4.35864)(0.598218,4.35819)(0.59976,4.35781)
+ (0.60132,4.35752)(0.602893,4.35731)(0.604475,4.35718)
+ (0.606061,4.35714)(0.607647,4.35718)(0.609228,4.35731)
+ (0.610801,4.35752)(0.612361,4.35781)(0.613904,4.35819)
+ (0.615425,4.35864)(0.61692,4.35918)(0.618386,4.35979)
+ (0.619818,4.36048)(0.621212,4.36124)(0.622565,4.36208)
+ (0.623872,4.36299)(0.625131,4.36396)(0.626337,4.36501)
+ (0.627488,4.36611)(0.62858,4.36727)(0.62961,4.36849)
+ (0.630576,4.36976)(0.631475,4.37108)(0.632304,4.37245)
+ (0.633061,4.37386)(0.633744,4.3753)(0.634351,4.37678)
+ (0.634881,4.3783)(0.635331,4.37983)(0.635701,4.38139)
+ (0.635991,4.38297)(0.636198,4.38456)(0.636322,4.38615)(0.636364,4.38776)
+\color{rgb_ffffff}%
+\path(4.33572,0.990808)(4.37372,1.02121)
+\path(4.32393,0.996994)(4.37047,1.03423)
+\path(4.3164,1.00659)(4.36294,1.04382)
+\path(4.31315,1.01961)(4.35115,1.05001)
+\path(4.37281,1.01291)(4.34234,1.05099)
+\path(4.36681,1.00093)(4.32949,1.04758)
+\path(4.35738,0.993236)(4.32006,1.03988)
+\path(4.34452,0.989825)(4.31406,1.0279)
+\color{rgb_000000}%
+\path(4.37374,1.02041)(4.3737,1.02201)(4.37357,1.02361)
+ (4.37336,1.0252)(4.37308,1.02677)(4.3727,1.02833)(4.37225,1.02987)
+ (4.37172,1.03138)(4.37112,1.03286)(4.37043,1.03431)
+ (4.36968,1.03571)(4.36885,1.03708)(4.36795,1.0384)(4.36698,1.03967)
+ (4.36595,1.04089)(4.36486,1.04205)(4.36371,1.04316)(4.3625,1.0442)
+ (4.36125,1.04517)(4.35994,1.04608)(4.35859,1.04692)
+ (4.35719,1.04768)(4.35576,1.04837)(4.35429,1.04899)(4.3528,1.04952)
+ (4.35128,1.04998)(4.34973,1.05035)(4.34817,1.05064)(4.3466,1.05085)
+ (4.34502,1.05098)(4.34343,1.05102)(4.34185,1.05098)
+ (4.34027,1.05085)(4.33869,1.05064)(4.33713,1.05035)
+ (4.33559,1.04998)(4.33407,1.04952)(4.33257,1.04899)
+ (4.33111,1.04837)(4.32968,1.04768)(4.32828,1.04692)
+ (4.32693,1.04608)(4.32562,1.04517)(4.32436,1.0442)(4.32316,1.04316)
+ (4.32201,1.04205)(4.32091,1.04089)(4.31988,1.03967)(4.31892,1.0384)
+ (4.31802,1.03708)(4.31719,1.03571)(4.31643,1.03431)
+ (4.31575,1.03286)(4.31514,1.03138)(4.31461,1.02987)
+ (4.31416,1.02833)(4.31379,1.02677)(4.3135,1.0252)(4.3133,1.02361)
+ (4.31317,1.02201)(4.31313,1.02041)(4.31317,1.01881)(4.3133,1.01721)
+ (4.3135,1.01562)(4.31379,1.01404)(4.31416,1.01249)(4.31461,1.01095)
+ (4.31514,1.00944)(4.31575,1.00796)(4.31643,1.00651)(4.31719,1.0051)
+ (4.31802,1.00374)(4.31892,1.00241)(4.31988,1.00114)
+ (4.32091,0.999925)(4.32201,0.998762)(4.32316,0.997659)
+ (4.32436,0.996618)(4.32562,0.995642)(4.32693,0.994735)
+ (4.32828,0.993897)(4.32968,0.993132)(4.33111,0.992442)
+ (4.33257,0.991829)(4.33407,0.991294)(4.33559,0.990839)
+ (4.33713,0.990465)(4.33869,0.990173)(4.34027,0.989964)
+ (4.34185,0.989838)(4.34343,0.989796)(4.34502,0.989838)
+ (4.3466,0.989964)(4.34817,0.990173)(4.34973,0.990465)
+ (4.35128,0.990839)(4.3528,0.991294)(4.35429,0.991829)
+ (4.35576,0.992442)(4.35719,0.993132)(4.35859,0.993897)
+ (4.35994,0.994735)(4.36125,0.995642)(4.3625,0.996618)
+ (4.36371,0.997659)(4.36486,0.998762)(4.36595,0.999925)
+ (4.36698,1.00114)(4.36795,1.00241)(4.36885,1.00374)(4.36968,1.0051)
+ (4.37043,1.00651)(4.37112,1.00796)(4.37172,1.00944)
+ (4.37225,1.01095)(4.3727,1.01249)(4.37308,1.01404)(4.37336,1.01562)
+ (4.37357,1.01721)(4.3737,1.01881)(4.37374,1.02041)
+\color{rgb_ffffff}%
+\path(6.29269,6.43232)(6.25065,6.45668)
+\path(6.29139,6.41896)(6.23989,6.4488)
+\path(6.28536,6.40834)(6.23386,6.43818)
+\path(6.2746,6.40046)(6.23256,6.42482)
+\path(6.25918,6.45898)(6.23469,6.41673)
+\path(6.27239,6.45754)(6.2424,6.40578)
+\path(6.28286,6.45136)(6.25286,6.3996)
+\path(6.29056,6.44042)(6.26607,6.39816)
+\color{rgb_000000}%
+\path(6.29293,6.42857)(6.29289,6.43017)(6.29276,6.43177)
+ (6.29256,6.43336)(6.29227,6.43494)(6.2919,6.43649)(6.29145,6.43803)
+ (6.29092,6.43954)(6.29031,6.44102)(6.28963,6.44247)
+ (6.28887,6.44388)(6.28804,6.44524)(6.28714,6.44656)
+ (6.28618,6.44784)(6.28515,6.44906)(6.28405,6.45022)(6.2829,6.45132)
+ (6.2817,6.45236)(6.28044,6.45334)(6.27913,6.45425)(6.27778,6.45508)
+ (6.27638,6.45585)(6.27495,6.45654)(6.27349,6.45715)
+ (6.27199,6.45769)(6.27047,6.45814)(6.26893,6.45851)
+ (6.26737,6.45881)(6.26579,6.45902)(6.26421,6.45914)
+ (6.26263,6.45918)(6.26104,6.45914)(6.25946,6.45902)
+ (6.25789,6.45881)(6.25633,6.45851)(6.25478,6.45814)
+ (6.25326,6.45769)(6.25177,6.45715)(6.2503,6.45654)(6.24887,6.45585)
+ (6.24747,6.45508)(6.24612,6.45425)(6.24481,6.45334)
+ (6.24356,6.45236)(6.24235,6.45132)(6.2412,6.45022)(6.24011,6.44906)
+ (6.23908,6.44784)(6.23811,6.44656)(6.23721,6.44524)
+ (6.23638,6.44388)(6.23563,6.44247)(6.23494,6.44102)
+ (6.23434,6.43954)(6.23381,6.43803)(6.23336,6.43649)
+ (6.23299,6.43494)(6.2327,6.43336)(6.23249,6.43177)(6.23236,6.43017)
+ (6.23232,6.42857)(6.23236,6.42697)(6.23249,6.42537)(6.2327,6.42378)
+ (6.23299,6.42221)(6.23336,6.42065)(6.23381,6.41911)(6.23434,6.4176)
+ (6.23494,6.41612)(6.23563,6.41467)(6.23638,6.41327)(6.23721,6.4119)
+ (6.23811,6.41058)(6.23908,6.40931)(6.24011,6.40809)(6.2412,6.40693)
+ (6.24235,6.40582)(6.24356,6.40478)(6.24481,6.40381)(6.24612,6.4029)
+ (6.24747,6.40206)(6.24887,6.4013)(6.2503,6.40061)(6.25177,6.39999)
+ (6.25326,6.39946)(6.25478,6.399)(6.25633,6.39863)(6.25789,6.39834)
+ (6.25946,6.39813)(6.26104,6.398)(6.26263,6.39796)(6.26421,6.398)
+ (6.26579,6.39813)(6.26737,6.39834)(6.26893,6.39863)(6.27047,6.399)
+ (6.27199,6.39946)(6.27349,6.39999)(6.27495,6.40061)(6.27638,6.4013)
+ (6.27778,6.40206)(6.27913,6.4029)(6.28044,6.40381)(6.2817,6.40478)
+ (6.2829,6.40582)(6.28405,6.40693)(6.28515,6.40809)(6.28618,6.40931)
+ (6.28714,6.41058)(6.28804,6.4119)(6.28887,6.41327)(6.28963,6.41467)
+ (6.29031,6.41612)(6.29092,6.4176)(6.29145,6.41911)(6.2919,6.42065)
+ (6.29227,6.42221)(6.29256,6.42378)(6.29276,6.42537)
+ (6.29289,6.42697)(6.29293,6.42857)
+\color{rgb_ffffff}%
+\path(0.995904,10.027)(0.988376,9.97867)
+\path(1.00873,10.0306)(0.999503,9.97133)
+\path(1.0207,10.0287)(1.01148,9.96942)
+\path(1.03183,10.0213)(1.0243,9.97297)
+\path(0.983385,9.98557)(1.03128,9.97812)
+\path(0.979836,9.99852)(1.03852,9.98938)
+\path(0.981687,10.0106)(1.04037,10.0015)
+\path(0.988918,10.0219)(1.03682,10.0144)
+\color{rgb_000000}%
+\path(1.0404,10)(1.04036,10.0016)(1.04024,10.0032)(1.04003,10.0048)
+ (1.03974,10.0064)(1.03937,10.0079)(1.03892,10.0095)(1.03839,10.011)
+ (1.03778,10.0125)(1.0371,10.0139)(1.03634,10.0153)(1.03552,10.0167)
+ (1.03462,10.018)(1.03365,10.0193)(1.03262,10.0205)(1.03153,10.0216)
+ (1.03038,10.0227)(1.02917,10.0238)(1.02791,10.0248)
+ (1.02661,10.0257)(1.02525,10.0265)(1.02386,10.0273)(1.02243,10.028)
+ (1.02096,10.0286)(1.01947,10.0291)(1.01794,10.0296)(1.0164,10.0299)
+ (1.01484,10.0302)(1.01327,10.0304)(1.01169,10.0306)(1.0101,10.0306)
+ (1.00852,10.0306)(1.00693,10.0304)(1.00536,10.0302)(1.0038,10.0299)
+ (1.00226,10.0296)(1.00074,10.0291)(0.999241,10.0286)
+ (0.997776,10.028)(0.996344,10.0273)(0.994949,10.0265)
+ (0.993597,10.0257)(0.992289,10.0248)(0.991031,10.0238)
+ (0.989824,10.0227)(0.988674,10.0216)(0.987581,10.0205)
+ (0.986551,10.0193)(0.985585,10.018)(0.984687,10.0167)
+ (0.983858,10.0153)(0.983101,10.0139)(0.982418,10.0125)
+ (0.981811,10.011)(0.981281,10.0095)(0.980831,10.0079)
+ (0.98046,10.0064)(0.980171,10.0048)(0.979964,10.0032)
+ (0.97984,10.0016)(0.979798,10)(0.97984,9.9984)(0.979964,9.9968)
+ (0.980171,9.99521)(0.98046,9.99364)(0.980831,9.99208)
+ (0.981281,9.99054)(0.981811,9.98903)(0.982418,9.98755)
+ (0.983101,9.9861)(0.983858,9.98469)(0.984687,9.98333)
+ (0.985585,9.98201)(0.986551,9.98074)(0.987581,9.97952)
+ (0.988674,9.97835)(0.989824,9.97725)(0.991031,9.97621)
+ (0.992289,9.97523)(0.993597,9.97433)(0.994949,9.97349)
+ (0.996344,9.97272)(0.997776,9.97203)(0.999241,9.97142)
+ (1.00074,9.97089)(1.00226,9.97043)(1.0038,9.97006)(1.00536,9.96976)
+ (1.00693,9.96956)(1.00852,9.96943)(1.0101,9.96939)(1.01169,9.96943)
+ (1.01327,9.96956)(1.01484,9.96976)(1.0164,9.97006)(1.01794,9.97043)
+ (1.01947,9.97089)(1.02096,9.97142)(1.02243,9.97203)
+ (1.02386,9.97272)(1.02525,9.97349)(1.02661,9.97433)
+ (1.02791,9.97523)(1.02917,9.97621)(1.03038,9.97725)
+ (1.03153,9.97835)(1.03262,9.97952)(1.03365,9.98074)
+ (1.03462,9.98201)(1.03552,9.98333)(1.03634,9.98469)(1.0371,9.9861)
+ (1.03778,9.98755)(1.03839,9.98903)(1.03892,9.99054)
+ (1.03937,9.99208)(1.03974,9.99364)(1.04003,9.99521)(1.04024,9.9968)
+ (1.04036,9.9984)(1.0404,10)
+\color{rgb_ffffff}%
+\path(8.16201,5.69113)(8.20936,5.70154)
+\path(8.1541,5.70193)(8.21211,5.71468)
+\path(8.15153,5.71389)(8.20954,5.72665)
+\path(8.15427,5.72703)(8.20163,5.73744)
+\path(8.20482,5.69437)(8.19431,5.74217)
+\path(8.19417,5.68633)(8.1813,5.74488)
+\path(8.18234,5.68369)(8.16946,5.74224)
+\path(8.16932,5.6864)(8.15882,5.7342)
+\color{rgb_000000}%
+\path(8.21212,5.71429)(8.21208,5.71589)(8.21196,5.71749)
+ (8.21175,5.71907)(8.21146,5.72065)(8.21109,5.72221)
+ (8.21064,5.72375)(8.21011,5.72526)(8.2095,5.72674)(8.20882,5.72818)
+ (8.20806,5.72959)(8.20723,5.73096)(8.20633,5.73228)
+ (8.20537,5.73355)(8.20434,5.73477)(8.20325,5.73593)
+ (8.20209,5.73704)(8.20089,5.73808)(8.19963,5.73905)
+ (8.19832,5.73996)(8.19697,5.7408)(8.19558,5.74156)(8.19414,5.74225)
+ (8.19268,5.74286)(8.19118,5.7434)(8.18966,5.74385)(8.18812,5.74423)
+ (8.18656,5.74452)(8.18499,5.74473)(8.1834,5.74486)(8.18182,5.7449)
+ (8.18023,5.74486)(8.17865,5.74473)(8.17708,5.74452)
+ (8.17552,5.74423)(8.17398,5.74385)(8.17245,5.7434)(8.17096,5.74286)
+ (8.16949,5.74225)(8.16806,5.74156)(8.16667,5.7408)(8.16531,5.73996)
+ (8.16401,5.73905)(8.16275,5.73808)(8.16154,5.73704)
+ (8.16039,5.73593)(8.1593,5.73477)(8.15827,5.73355)(8.1573,5.73228)
+ (8.1564,5.73096)(8.15557,5.72959)(8.15482,5.72818)(8.15413,5.72674)
+ (8.15353,5.72526)(8.153,5.72375)(8.15255,5.72221)(8.15218,5.72065)
+ (8.15189,5.71907)(8.15168,5.71749)(8.15156,5.71589)
+ (8.15152,5.71429)(8.15156,5.71268)(8.15168,5.71109)(8.15189,5.7095)
+ (8.15218,5.70792)(8.15255,5.70636)(8.153,5.70483)(8.15353,5.70332)
+ (8.15413,5.70183)(8.15482,5.70039)(8.15557,5.69898)(8.1564,5.69761)
+ (8.1573,5.69629)(8.15827,5.69502)(8.1593,5.6938)(8.16039,5.69264)
+ (8.16154,5.69154)(8.16275,5.6905)(8.16401,5.68952)(8.16531,5.68861)
+ (8.16667,5.68777)(8.16806,5.68701)(8.16949,5.68632)
+ (8.17096,5.68571)(8.17245,5.68517)(8.17398,5.68472)
+ (8.17552,5.68434)(8.17708,5.68405)(8.17865,5.68384)
+ (8.18023,5.68372)(8.18182,5.68367)(8.1834,5.68372)(8.18499,5.68384)
+ (8.18656,5.68405)(8.18812,5.68434)(8.18966,5.68472)
+ (8.19118,5.68517)(8.19268,5.68571)(8.19414,5.68632)
+ (8.19558,5.68701)(8.19697,5.68777)(8.19832,5.68861)
+ (8.19963,5.68952)(8.20089,5.6905)(8.20209,5.69154)(8.20325,5.69264)
+ (8.20434,5.6938)(8.20537,5.69502)(8.20633,5.69629)(8.20723,5.69761)
+ (8.20806,5.69898)(8.20882,5.70039)(8.2095,5.70183)(8.21011,5.70332)
+ (8.21064,5.70483)(8.21109,5.70636)(8.21146,5.70792)(8.21175,5.7095)
+ (8.21196,5.71109)(8.21208,5.71268)(8.21212,5.71429)
+\color{rgb_ffffff}%
+\path(5.88719,7.13279)(5.86015,7.17343)
+\path(5.88018,7.12139)(5.84705,7.17116)
+\path(5.87012,7.11456)(5.83699,7.16433)
+\path(5.85703,7.11229)(5.82998,7.15292)
+\path(5.86882,7.17166)(5.82835,7.14473)
+\path(5.88004,7.16447)(5.83047,7.13147)
+\path(5.88671,7.15424)(5.83713,7.12124)
+\path(5.88883,7.14099)(5.84835,7.11405)
+\color{rgb_000000}%
+\path(5.88889,7.14286)(5.88885,7.14446)(5.88872,7.14606)
+ (5.88852,7.14765)(5.88823,7.14922)(5.88786,7.15078)
+ (5.88741,7.15232)(5.88688,7.15383)(5.88627,7.15531)
+ (5.88559,7.15675)(5.88483,7.15816)(5.884,7.15953)(5.8831,7.16085)
+ (5.88214,7.16212)(5.88111,7.16334)(5.88001,7.1645)(5.87886,7.16561)
+ (5.87766,7.16665)(5.8764,7.16762)(5.87509,7.16853)(5.87374,7.16937)
+ (5.87234,7.17013)(5.87091,7.17082)(5.86945,7.17144)
+ (5.86795,7.17197)(5.86643,7.17243)(5.86489,7.1728)(5.86333,7.17309)
+ (5.86175,7.1733)(5.86017,7.17343)(5.85859,7.17347)(5.857,7.17343)
+ (5.85542,7.1733)(5.85385,7.17309)(5.85229,7.1728)(5.85074,7.17243)
+ (5.84922,7.17197)(5.84773,7.17144)(5.84626,7.17082)
+ (5.84483,7.17013)(5.84343,7.16937)(5.84208,7.16853)
+ (5.84077,7.16762)(5.83952,7.16665)(5.83831,7.16561)(5.83716,7.1645)
+ (5.83607,7.16334)(5.83504,7.16212)(5.83407,7.16085)
+ (5.83317,7.15953)(5.83234,7.15816)(5.83159,7.15675)(5.8309,7.15531)
+ (5.8303,7.15383)(5.82977,7.15232)(5.82932,7.15078)(5.82895,7.14922)
+ (5.82866,7.14765)(5.82845,7.14606)(5.82832,7.14446)
+ (5.82828,7.14286)(5.82832,7.14126)(5.82845,7.13966)
+ (5.82866,7.13807)(5.82895,7.13649)(5.82932,7.13493)(5.82977,7.1334)
+ (5.8303,7.13189)(5.8309,7.13041)(5.83159,7.12896)(5.83234,7.12755)
+ (5.83317,7.12618)(5.83407,7.12486)(5.83504,7.12359)
+ (5.83607,7.12237)(5.83716,7.12121)(5.83831,7.12011)
+ (5.83952,7.11907)(5.84077,7.11809)(5.84208,7.11718)
+ (5.84343,7.11635)(5.84483,7.11558)(5.84626,7.11489)
+ (5.84773,7.11428)(5.84922,7.11374)(5.85074,7.11329)
+ (5.85229,7.11291)(5.85385,7.11262)(5.85542,7.11241)(5.857,7.11229)
+ (5.85859,7.11224)(5.86017,7.11229)(5.86175,7.11241)
+ (5.86333,7.11262)(5.86489,7.11291)(5.86643,7.11329)
+ (5.86795,7.11374)(5.86945,7.11428)(5.87091,7.11489)
+ (5.87234,7.11558)(5.87374,7.11635)(5.87509,7.11718)(5.8764,7.11809)
+ (5.87766,7.11907)(5.87886,7.12011)(5.88001,7.12121)
+ (5.88111,7.12237)(5.88214,7.12359)(5.8831,7.12486)(5.884,7.12618)
+ (5.88483,7.12755)(5.88559,7.12896)(5.88627,7.13041)
+ (5.88688,7.13189)(5.88741,7.1334)(5.88786,7.13493)(5.88823,7.13649)
+ (5.88852,7.13807)(5.88872,7.13966)(5.88885,7.14126)(5.88889,7.14286)
+\color{rgb_ffffff}%
+\path(2.42345,1.66324)(2.39538,1.62332)
+\path(2.43649,1.66065)(2.40212,1.61175)
+\path(2.44637,1.65355)(2.41199,1.60466)
+\path(2.4531,1.64198)(2.42504,1.60206)
+\path(2.39397,1.63156)(2.43376,1.60359)
+\path(2.39642,1.64476)(2.44514,1.6105)
+\path(2.40334,1.6548)(2.45207,1.62055)
+\path(2.41473,1.66171)(2.45452,1.63374)
+\color{rgb_000000}%
+\path(2.45455,1.63265)(2.4545,1.63426)(2.45438,1.63585)
+ (2.45417,1.63744)(2.45388,1.63902)(2.45351,1.64058)
+ (2.45306,1.64211)(2.45253,1.64362)(2.45193,1.6451)(2.45124,1.64655)
+ (2.45049,1.64796)(2.44966,1.64933)(2.44876,1.65065)
+ (2.44779,1.65192)(2.44676,1.65314)(2.44567,1.6543)(2.44452,1.6554)
+ (2.44331,1.65644)(2.44205,1.65742)(2.44075,1.65833)
+ (2.43939,1.65916)(2.438,1.65993)(2.43657,1.66062)(2.4351,1.66123)
+ (2.43361,1.66177)(2.43209,1.66222)(2.43054,1.6626)(2.42898,1.66289)
+ (2.42741,1.6631)(2.42583,1.66322)(2.42424,1.66327)(2.42266,1.66322)
+ (2.42107,1.6631)(2.4195,1.66289)(2.41794,1.6626)(2.4164,1.66222)
+ (2.41488,1.66177)(2.41338,1.66123)(2.41192,1.66062)
+ (2.41049,1.65993)(2.40909,1.65916)(2.40774,1.65833)
+ (2.40643,1.65742)(2.40517,1.65644)(2.40397,1.6554)(2.40281,1.6543)
+ (2.40172,1.65314)(2.40069,1.65192)(2.39973,1.65065)
+ (2.39883,1.64933)(2.398,1.64796)(2.39724,1.64655)(2.39656,1.6451)
+ (2.39595,1.64362)(2.39542,1.64211)(2.39497,1.64058)(2.3946,1.63902)
+ (2.39431,1.63744)(2.39411,1.63585)(2.39398,1.63426)
+ (2.39394,1.63265)(2.39398,1.63105)(2.39411,1.62945)
+ (2.39431,1.62786)(2.3946,1.62629)(2.39497,1.62473)(2.39542,1.62319)
+ (2.39595,1.62168)(2.39656,1.6202)(2.39724,1.61876)(2.398,1.61735)
+ (2.39883,1.61598)(2.39973,1.61466)(2.40069,1.61339)
+ (2.40172,1.61217)(2.40281,1.61101)(2.40397,1.6099)(2.40517,1.60886)
+ (2.40643,1.60789)(2.40774,1.60698)(2.40909,1.60614)
+ (2.41049,1.60538)(2.41192,1.60469)(2.41338,1.60407)
+ (2.41488,1.60354)(2.4164,1.60308)(2.41794,1.60271)(2.4195,1.60242)
+ (2.42107,1.60221)(2.42266,1.60208)(2.42424,1.60204)
+ (2.42583,1.60208)(2.42741,1.60221)(2.42898,1.60242)
+ (2.43054,1.60271)(2.43209,1.60308)(2.43361,1.60354)(2.4351,1.60407)
+ (2.43657,1.60469)(2.438,1.60538)(2.43939,1.60614)(2.44075,1.60698)
+ (2.44205,1.60789)(2.44331,1.60886)(2.44452,1.6099)(2.44567,1.61101)
+ (2.44676,1.61217)(2.44779,1.61339)(2.44876,1.61466)
+ (2.44966,1.61598)(2.45049,1.61735)(2.45124,1.61876)(2.45193,1.6202)
+ (2.45253,1.62168)(2.45306,1.62319)(2.45351,1.62473)
+ (2.45388,1.62629)(2.45417,1.62786)(2.45438,1.62945)(2.4545,1.63105)(2.45455,1.63265)
+\color{rgb_ffffff}%
+\path(2.09336,7.23287)(2.14045,7.22125)
+\path(2.09094,7.24607)(2.14861,7.23184)
+\path(2.09382,7.25796)(2.15148,7.24373)
+\path(2.10198,7.26855)(2.14907,7.25693)
+\path(2.13299,7.2167)(2.14472,7.26422)
+\path(2.11991,7.21432)(2.13427,7.27251)
+\path(2.10815,7.21729)(2.12251,7.27548)
+\path(2.09771,7.22558)(2.10943,7.27309)
+\color{rgb_000000}%
+\path(2.15152,7.2449)(2.15147,7.2465)(2.15135,7.2481)
+ (2.15114,7.24969)(2.15085,7.25126)(2.15048,7.25282)
+ (2.15003,7.25436)(2.1495,7.25587)(2.1489,7.25735)(2.14821,7.2588)
+ (2.14746,7.2602)(2.14663,7.26157)(2.14573,7.26289)(2.14476,7.26416)
+ (2.14373,7.26538)(2.14264,7.26654)(2.14149,7.26765)
+ (2.14028,7.26869)(2.13902,7.26966)(2.13772,7.27057)
+ (2.13636,7.27141)(2.13497,7.27217)(2.13354,7.27286)
+ (2.13207,7.27348)(2.13058,7.27401)(2.12906,7.27447)
+ (2.12751,7.27484)(2.12595,7.27513)(2.12438,7.27534)(2.1228,7.27547)
+ (2.12121,7.27551)(2.11963,7.27547)(2.11804,7.27534)
+ (2.11647,7.27513)(2.11491,7.27484)(2.11337,7.27447)
+ (2.11185,7.27401)(2.11035,7.27348)(2.10889,7.27286)
+ (2.10745,7.27217)(2.10606,7.27141)(2.10471,7.27057)(2.1034,7.26966)
+ (2.10214,7.26869)(2.10094,7.26765)(2.09978,7.26654)
+ (2.09869,7.26538)(2.09766,7.26416)(2.0967,7.26289)(2.0958,7.26157)
+ (2.09497,7.2602)(2.09421,7.2588)(2.09353,7.25735)(2.09292,7.25587)
+ (2.09239,7.25436)(2.09194,7.25282)(2.09157,7.25126)
+ (2.09128,7.24969)(2.09108,7.2481)(2.09095,7.2465)(2.09091,7.2449)
+ (2.09095,7.2433)(2.09108,7.2417)(2.09128,7.24011)(2.09157,7.23853)
+ (2.09194,7.23697)(2.09239,7.23544)(2.09292,7.23393)
+ (2.09353,7.23245)(2.09421,7.231)(2.09497,7.22959)(2.0958,7.22823)
+ (2.0967,7.2269)(2.09766,7.22563)(2.09869,7.22441)(2.09978,7.22325)
+ (2.10094,7.22215)(2.10214,7.22111)(2.1034,7.22013)(2.10471,7.21922)
+ (2.10606,7.21839)(2.10745,7.21762)(2.10889,7.21693)
+ (2.11035,7.21632)(2.11185,7.21578)(2.11337,7.21533)
+ (2.11491,7.21495)(2.11647,7.21466)(2.11804,7.21445)
+ (2.11963,7.21433)(2.12121,7.21429)(2.1228,7.21433)(2.12438,7.21445)
+ (2.12595,7.21466)(2.12751,7.21495)(2.12906,7.21533)
+ (2.13058,7.21578)(2.13207,7.21632)(2.13354,7.21693)
+ (2.13497,7.21762)(2.13636,7.21839)(2.13772,7.21922)
+ (2.13902,7.22013)(2.14028,7.22111)(2.14149,7.22215)
+ (2.14264,7.22325)(2.14373,7.22441)(2.14476,7.22563)(2.14573,7.2269)
+ (2.14663,7.22823)(2.14746,7.22959)(2.14821,7.231)(2.1489,7.23245)
+ (2.1495,7.23393)(2.15003,7.23544)(2.15048,7.23697)(2.15085,7.23853)
+ (2.15114,7.24011)(2.15135,7.2417)(2.15147,7.2433)(2.15152,7.2449)
+\color{rgb_ffffff}%
+\path(8.70804,6.2026)(8.70174,6.25115)
+\path(8.69673,6.19555)(8.68902,6.25501)
+\path(8.68471,6.19396)(8.67701,6.25343)
+\path(8.67199,6.19783)(8.6657,6.24638)
+\path(8.70859,6.24582)(8.66051,6.23959)
+\path(8.71554,6.23438)(8.65666,6.22675)
+\path(8.71708,6.22223)(8.6582,6.2146)
+\path(8.71322,6.20939)(8.66514,6.20316)
+\color{rgb_000000}%
+\path(8.71717,6.22449)(8.71713,6.22609)(8.71701,6.22769)
+ (8.7168,6.22928)(8.71651,6.23085)(8.71614,6.23241)(8.71569,6.23395)
+ (8.71516,6.23546)(8.71455,6.23694)(8.71387,6.23839)(8.71311,6.2398)
+ (8.71228,6.24116)(8.71138,6.24248)(8.71042,6.24375)
+ (8.70939,6.24497)(8.7083,6.24614)(8.70715,6.24724)(8.70594,6.24828)
+ (8.70468,6.24926)(8.70337,6.25016)(8.70202,6.251)(8.70063,6.25177)
+ (8.69919,6.25246)(8.69773,6.25307)(8.69623,6.2536)(8.69471,6.25406)
+ (8.69317,6.25443)(8.69161,6.25473)(8.69004,6.25493)
+ (8.68845,6.25506)(8.68687,6.2551)(8.68528,6.25506)(8.6837,6.25493)
+ (8.68213,6.25473)(8.68057,6.25443)(8.67903,6.25406)(8.6775,6.2536)
+ (8.67601,6.25307)(8.67454,6.25246)(8.67311,6.25177)(8.67172,6.251)
+ (8.67036,6.25016)(8.66906,6.24926)(8.6678,6.24828)(8.66659,6.24724)
+ (8.66544,6.24614)(8.66435,6.24497)(8.66332,6.24375)
+ (8.66235,6.24248)(8.66145,6.24116)(8.66063,6.2398)(8.65987,6.23839)
+ (8.65919,6.23694)(8.65858,6.23546)(8.65805,6.23395)(8.6576,6.23241)
+ (8.65723,6.23085)(8.65694,6.22928)(8.65673,6.22769)
+ (8.65661,6.22609)(8.65657,6.22449)(8.65661,6.22289)
+ (8.65673,6.22129)(8.65694,6.2197)(8.65723,6.21813)(8.6576,6.21657)
+ (8.65805,6.21503)(8.65858,6.21352)(8.65919,6.21204)
+ (8.65987,6.21059)(8.66063,6.20918)(8.66145,6.20782)(8.66235,6.2065)
+ (8.66332,6.20522)(8.66435,6.20401)(8.66544,6.20284)
+ (8.66659,6.20174)(8.6678,6.2007)(8.66906,6.19972)(8.67036,6.19882)
+ (8.67172,6.19798)(8.67311,6.19721)(8.67454,6.19652)
+ (8.67601,6.19591)(8.6775,6.19538)(8.67903,6.19492)(8.68057,6.19455)
+ (8.68213,6.19425)(8.6837,6.19405)(8.68528,6.19392)(8.68687,6.19388)
+ (8.68845,6.19392)(8.69004,6.19405)(8.69161,6.19425)
+ (8.69317,6.19455)(8.69471,6.19492)(8.69623,6.19538)
+ (8.69773,6.19591)(8.69919,6.19652)(8.70063,6.19721)
+ (8.70202,6.19798)(8.70337,6.19882)(8.70468,6.19972)(8.70594,6.2007)
+ (8.70715,6.20174)(8.7083,6.20284)(8.70939,6.20401)(8.71042,6.20522)
+ (8.71138,6.2065)(8.71228,6.20782)(8.71311,6.20918)(8.71387,6.21059)
+ (8.71455,6.21204)(8.71516,6.21352)(8.71569,6.21503)
+ (8.71614,6.21657)(8.71651,6.21813)(8.7168,6.2197)(8.71701,6.22129)
+ (8.71713,6.22289)(8.71717,6.22449)
+\color{rgb_ffffff}%
+\path(10.0127,0.640039)(9.97003,0.616758)
+\path(10.0232,0.631885)(9.97101,0.603375)
+\path(10.029,0.621115)(9.97677,0.592605)
+\path(10.03,0.607732)(9.98732,0.584451)
+\path(9.97238,0.624821)(9.99578,0.58194)
+\path(9.98036,0.635545)(10.009,0.58303)
+\path(9.99097,0.641459)(10.0196,0.588945)
+\path(10.0042,0.64255)(10.0276,0.599669)
+\color{rgb_000000}%
+\path(10.0303,0.612245)(10.0303,0.613847)(10.0301,0.615445)
+ (10.0299,0.617034)(10.0296,0.61861)(10.0293,0.620168)
+ (10.0288,0.621705)(10.0283,0.623215)(10.0277,0.624696)
+ (10.027,0.626143)(10.0262,0.627551)(10.0254,0.628918)
+ (10.0245,0.630238)(10.0235,0.63151)(10.0225,0.632728)
+ (10.0214,0.633891)(10.0203,0.634994)(10.0191,0.636035)
+ (10.0178,0.637011)(10.0165,0.637918)(10.0152,0.638756)
+ (10.0138,0.639521)(10.0123,0.640211)(10.0109,0.640824)
+ (10.0094,0.641359)(10.0078,0.641814)(10.0063,0.642188)
+ (10.0047,0.64248)(10.0032,0.642689)(10.0016,0.642815)(10,0.642857)
+ (9.99841,0.642815)(9.99683,0.642689)(9.99526,0.64248)
+ (9.9937,0.642188)(9.99216,0.641814)(9.99064,0.641359)
+ (9.98914,0.640824)(9.98767,0.640211)(9.98624,0.639521)
+ (9.98485,0.638756)(9.9835,0.637918)(9.98219,0.637011)
+ (9.98093,0.636035)(9.97972,0.634994)(9.97857,0.633891)
+ (9.97748,0.632728)(9.97645,0.63151)(9.97548,0.630238)
+ (9.97459,0.628918)(9.97376,0.627551)(9.973,0.626143)
+ (9.97232,0.624696)(9.97171,0.623215)(9.97118,0.621705)
+ (9.97073,0.620168)(9.97036,0.61861)(9.97007,0.617034)
+ (9.96986,0.615445)(9.96974,0.613847)(9.9697,0.612245)
+ (9.96974,0.610643)(9.96986,0.609045)(9.97007,0.607456)
+ (9.97036,0.60588)(9.97073,0.604322)(9.97118,0.602785)
+ (9.97171,0.601274)(9.97232,0.599794)(9.973,0.598347)
+ (9.97376,0.596939)(9.97459,0.595572)(9.97548,0.594251)
+ (9.97645,0.59298)(9.97748,0.591761)(9.97857,0.590599)
+ (9.97972,0.589496)(9.98093,0.588455)(9.98219,0.587479)
+ (9.9835,0.586571)(9.98485,0.585734)(9.98624,0.584969)
+ (9.98767,0.584279)(9.98914,0.583666)(9.99064,0.583131)
+ (9.99216,0.582676)(9.9937,0.582302)(9.99526,0.58201)
+ (9.99683,0.5818)(9.99841,0.581675)(10,0.581633)(10.0016,0.581675)
+ (10.0032,0.5818)(10.0047,0.58201)(10.0063,0.582302)
+ (10.0078,0.582676)(10.0094,0.583131)(10.0109,0.583666)
+ (10.0123,0.584279)(10.0138,0.584969)(10.0152,0.585734)
+ (10.0165,0.586571)(10.0178,0.587479)(10.0191,0.588455)
+ (10.0203,0.589496)(10.0214,0.590599)(10.0225,0.591761)
+ (10.0235,0.59298)(10.0245,0.594251)(10.0254,0.595572)
+ (10.0262,0.596939)(10.027,0.598347)(10.0277,0.599794)
+ (10.0283,0.601274)(10.0288,0.602785)(10.0293,0.604322)
+ (10.0296,0.60588)(10.0299,0.607456)(10.0301,0.609045)
+ (10.0303,0.610643)(10.0303,0.612245)
+\color{rgb_ff0000}%
+\path(8.35358,7.85873)(8.3908,7.82736)
+\path(8.35717,7.87165)(8.40275,7.83323)
+\path(8.36493,7.88106)(8.41051,7.84264)
+\path(8.37688,7.88693)(8.4141,7.85556)
+\path(8.38196,7.8266)(8.41339,7.86388)
+\path(8.36921,7.83034)(8.40769,7.87601)
+\path(8.35998,7.83828)(8.39847,7.88394)
+\path(8.35429,7.8504)(8.38571,7.88769)
+\color{rgb_000000}%
+\path(8.41414,7.85714)(8.4141,7.85874)(8.41398,7.86034)
+ (8.41377,7.86193)(8.41348,7.86351)(8.41311,7.86507)(8.41266,7.8666)
+ (8.41213,7.86811)(8.41152,7.86959)(8.41084,7.87104)
+ (8.41008,7.87245)(8.40925,7.87382)(8.40835,7.87514)
+ (8.40739,7.87641)(8.40636,7.87763)(8.40527,7.87879)
+ (8.40412,7.87989)(8.40291,7.88093)(8.40165,7.88191)
+ (8.40034,7.88282)(8.39899,7.88365)(8.3976,7.88442)(8.39616,7.88511)
+ (8.3947,7.88572)(8.3932,7.88626)(8.39168,7.88671)(8.39014,7.88709)
+ (8.38858,7.88738)(8.38701,7.88759)(8.38542,7.88771)
+ (8.38384,7.88776)(8.38225,7.88771)(8.38067,7.88759)(8.3791,7.88738)
+ (8.37754,7.88709)(8.376,7.88671)(8.37447,7.88626)(8.37298,7.88572)
+ (8.37151,7.88511)(8.37008,7.88442)(8.36869,7.88365)
+ (8.36733,7.88282)(8.36603,7.88191)(8.36477,7.88093)
+ (8.36356,7.87989)(8.36241,7.87879)(8.36132,7.87763)
+ (8.36029,7.87641)(8.35932,7.87514)(8.35842,7.87382)(8.3576,7.87245)
+ (8.35684,7.87104)(8.35616,7.86959)(8.35555,7.86811)(8.35502,7.8666)
+ (8.35457,7.86507)(8.3542,7.86351)(8.35391,7.86193)(8.3537,7.86034)
+ (8.35358,7.85874)(8.35354,7.85714)(8.35358,7.85554)(8.3537,7.85394)
+ (8.35391,7.85235)(8.3542,7.85078)(8.35457,7.84922)(8.35502,7.84768)
+ (8.35555,7.84617)(8.35616,7.84469)(8.35684,7.84325)(8.3576,7.84184)
+ (8.35842,7.84047)(8.35932,7.83915)(8.36029,7.83788)
+ (8.36132,7.83666)(8.36241,7.8355)(8.36356,7.83439)(8.36477,7.83335)
+ (8.36603,7.83238)(8.36733,7.83147)(8.36869,7.83063)
+ (8.37008,7.82987)(8.37151,7.82918)(8.37298,7.82856)
+ (8.37447,7.82803)(8.376,7.82757)(8.37754,7.8272)(8.3791,7.82691)
+ (8.38067,7.8267)(8.38225,7.82657)(8.38384,7.82653)(8.38542,7.82657)
+ (8.38701,7.8267)(8.38858,7.82691)(8.39014,7.8272)(8.39168,7.82757)
+ (8.3932,7.82803)(8.3947,7.82856)(8.39616,7.82918)(8.3976,7.82987)
+ (8.39899,7.83063)(8.40034,7.83147)(8.40165,7.83238)
+ (8.40291,7.83335)(8.40412,7.83439)(8.40527,7.8355)(8.40636,7.83666)
+ (8.40739,7.83788)(8.40835,7.83915)(8.40925,7.84047)
+ (8.41008,7.84184)(8.41084,7.84325)(8.41152,7.84469)
+ (8.41213,7.84617)(8.41266,7.84768)(8.41311,7.84922)
+ (8.41348,7.85078)(8.41377,7.85235)(8.41398,7.85394)(8.4141,7.85554)(8.41414,7.85714)
+\end{picture}%
diff --git a/documentation/tutorials/cplusplus/chap10/opt-A-n32-k5.pdf b/documentation/tutorials/cplusplus/chap10/opt-A-n32-k5.pdf
new file mode 100644
index 0000000000..3ceee7a754
Binary files /dev/null and b/documentation/tutorials/cplusplus/chap10/opt-A-n32-k5.pdf differ
diff --git a/documentation/tutorials/cplusplus/chap10/opt-A-n32-k5.xp b/documentation/tutorials/cplusplus/chap10/opt-A-n32-k5.xp
new file mode 100644
index 0000000000..e040b30013
--- /dev/null
+++ b/documentation/tutorials/cplusplus/chap10/opt-A-n32-k5.xp
@@ -0,0 +1,193 @@
+#include "epix.h"
+using namespace ePiX;
+
+int main(int argc, char **argv)
+{
+
+unitlength("1cm");
+picture(10,10);
+double radius = 0.3;
+font_size("tiny");
+bounding_box(P(-1,-1), P(98,97));
+
+ // Points:
+ P P0(82,76);
+ Circle C0(P0, radius);
+ P P1(96,44);
+ Circle C1(P1, radius);
+ P P2(50,5);
+ Circle C2(P2, radius);
+ P P3(49,8);
+ Circle C3(P3, radius);
+ P P4(13,7);
+ Circle C4(P4, radius);
+ P P5(29,89);
+ Circle C5(P5, radius);
+ P P6(58,30);
+ Circle C6(P6, radius);
+ P P7(84,39);
+ Circle C7(P7, radius);
+ P P8(14,24);
+ Circle C8(P8, radius);
+ P P9(2,39);
+ Circle C9(P9, radius);
+ P P10(3,82);
+ Circle C10(P10, radius);
+ P P11(5,10);
+ Circle C11(P11, radius);
+ P P12(98,52);
+ Circle C12(P12, radius);
+ P P13(84,25);
+ Circle C13(P13, radius);
+ P P14(61,59);
+ Circle C14(P14, radius);
+ P P15(1,65);
+ Circle C15(P15, radius);
+ P P16(88,51);
+ Circle C16(P16, radius);
+ P P17(91,2);
+ Circle C17(P17, radius);
+ P P18(19,32);
+ Circle C18(P18, radius);
+ P P19(93,3);
+ Circle C19(P19, radius);
+ P P20(50,93);
+ Circle C20(P20, radius);
+ P P21(98,14);
+ Circle C21(P21, radius);
+ P P22(5,42);
+ Circle C22(P22, radius);
+ P P23(42,9);
+ Circle C23(P23, radius);
+ P P24(61,62);
+ Circle C24(P24, radius);
+ P P25(9,97);
+ Circle C25(P25, radius);
+ P P26(80,55);
+ Circle C26(P26, radius);
+ P P27(57,69);
+ Circle C27(P27, radius);
+ P P28(23,15);
+ Circle C28(P28, radius);
+ P P29(20,70);
+ Circle C29(P29, radius);
+ P P30(85,60);
+ Circle C30(P30, radius);
+ P P31(98,5);
+ Circle C31(P31, radius);
+ // Edges:
+ Segment L0(P0,P21);
+ Segment L1(P21,P31);
+ Segment L2(P31,P19);
+ Segment L3(P19,P17);
+ Segment L4(P17,P13);
+ Segment L5(P13,P7);
+ Segment L6(P7,P26);
+ Segment L7(P26,P0);
+ Segment L8(P0,P12);
+ Segment L9(P12,P1);
+ Segment L10(P1,P16);
+ Segment L11(P16,P30);
+ Segment L12(P30,P0);
+ Segment L13(P0,P27);
+ Segment L14(P27,P24);
+ Segment L15(P24,P0);
+ Segment L16(P0,P29);
+ Segment L17(P29,P18);
+ Segment L18(P18,P8);
+ Segment L19(P8,P9);
+ Segment L20(P9,P22);
+ Segment L21(P22,P15);
+ Segment L22(P15,P10);
+ Segment L23(P10,P25);
+ Segment L24(P25,P5);
+ Segment L25(P5,P20);
+ Segment L26(P20,P0);
+ Segment L27(P0,P14);
+ Segment L28(P14,P28);
+ Segment L29(P28,P11);
+ Segment L30(P11,P4);
+ Segment L31(P4,P23);
+ Segment L32(P23,P3);
+ Segment L33(P3,P2);
+ Segment L34(P2,P6);
+ Segment L35(P6,P0);
+
+
+begin(); // ---- Figure body starts here ----
+ L0.draw();
+ L1.draw();
+ L2.draw();
+ L3.draw();
+ L4.draw();
+ L5.draw();
+ L6.draw();
+ L7.draw();
+ L8.draw();
+ L9.draw();
+ L10.draw();
+ L11.draw();
+ L12.draw();
+ L13.draw();
+ L14.draw();
+ L15.draw();
+ L16.draw();
+ L17.draw();
+ L18.draw();
+ L19.draw();
+ L20.draw();
+ L21.draw();
+ L22.draw();
+ L23.draw();
+ L24.draw();
+ L25.draw();
+ L26.draw();
+ L27.draw();
+ L28.draw();
+ L29.draw();
+ L30.draw();
+ L31.draw();
+ L32.draw();
+ L33.draw();
+ L34.draw();
+ L35.draw();
+ fill(White());
+ C0.draw();
+ C1.draw();
+ C2.draw();
+ C3.draw();
+ C4.draw();
+ C5.draw();
+ C6.draw();
+ C7.draw();
+ C8.draw();
+ C9.draw();
+ C10.draw();
+ C11.draw();
+ C12.draw();
+ C13.draw();
+ C14.draw();
+ C15.draw();
+ C16.draw();
+ C17.draw();
+ C18.draw();
+ C19.draw();
+ C20.draw();
+ C21.draw();
+ C22.draw();
+ C23.draw();
+ C24.draw();
+ C25.draw();
+ C26.draw();
+ C27.draw();
+ C28.draw();
+ C29.draw();
+ C30.draw();
+ C31.draw();
+ fill(Red());
+ C0.draw();
+ fill(White());
+
+end(); // ---- End figure; write output file ----
+
+}
diff --git a/documentation/tutorials/cplusplus/chap10/vrp.cc b/documentation/tutorials/cplusplus/chap10/vrp.cc
new file mode 100644
index 0000000000..ad5dde7e25
--- /dev/null
+++ b/documentation/tutorials/cplusplus/chap10/vrp.cc
@@ -0,0 +1,124 @@
+// 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.
+//
+//
+// Simple program to solve the VRP with Local Search in or-tools.
+
+#include
+#include
+
+#include "base/commandlineflags.h"
+#include "constraint_solver/routing.h"
+#include "base/join.h"
+#include "base/timer.h"
+
+#include "cvrp_data.h"
+#include "cvrp_solution.h"
+#include "routing_common/tsplib_reader.h"
+
+DEFINE_int32(depot, 1, "The starting node of the tour.");
+DEFINE_int32(time_limit_in_ms, 0, "Time limit in ms.");
+
+namespace operations_research {
+
+void VRPSolver (const CVRPData & data) {
+
+ const int size = data.Size();
+
+ RoutingModel routing(size, FLAGS_number_vehicles);
+ routing.SetCost(NewPermanentCallback(&data, &CVRPData::Distance));
+
+ // Disabling Large Neighborhood Search, comment out to activate it.
+ //routing.SetCommandLineOption("routing_no_lns", "true");
+
+ if (FLAGS_time_limit_in_ms > 0) {
+ routing.UpdateTimeLimit(FLAGS_time_limit_in_ms);
+ }
+
+ // Setting depot
+ CHECK_GT(FLAGS_depot, 0) << " Because we use the" << " TSPLIB convention, the depot id must be > 0";
+ RoutingModel::NodeIndex depot(FLAGS_depot -1);
+ routing.SetDepot(depot);
+
+ routing.CloseModel();
+
+ // Forbidding empty routes
+ for (int vehicle_nbr = 0; vehicle_nbr < FLAGS_number_vehicles; ++vehicle_nbr) {
+ IntVar* const start_var = routing.NextVar(routing.Start(vehicle_nbr));
+ for (int64 node_index = routing.Size(); node_index < routing.Size() + routing.vehicles(); ++node_index) {
+ start_var->RemoveValue(node_index);
+ }
+ }
+
+ // SOLVE
+ const Assignment* solution = routing.Solve();
+
+ // INSPECT SOLUTION
+ if (solution != NULL) {
+ CVRPSolution cvrp_sol(data, &routing, solution);
+ cvrp_sol.SetName(StrCat("Solution for instance ", data.Name(), " computed by vrp.cc"));
+ // test solution
+ if (!cvrp_sol.IsSolution()) {
+ LOG(ERROR) << "Solution is NOT feasible!";
+ } else {
+ LG << "Solution is feasible and has an obj value of " << cvrp_sol.ComputeObjectiveValue();
+ // SAVE SOLUTION IN CVRP FORMAT
+ if (FLAGS_solution_file != "") {
+ cvrp_sol.Write(FLAGS_solution_file);
+ }
+ }
+
+ // Solution cost.
+ LG << "Obj value: " << solution->ObjectiveValue();
+ // Inspect solution.
+ std::string route;
+ for (int vehicle_nbr = 0; vehicle_nbr < FLAGS_number_vehicles; ++vehicle_nbr) {
+ route = "";
+ for (int64 node = routing.Start(vehicle_nbr); !routing.IsEnd(node);
+ node = solution->Value(routing.NextVar(node))) {
+ route = StrCat(route, StrCat(routing.IndexToNode(node).value() + 1 , " -> "));
+ }
+ route = StrCat(route, routing.IndexToNode(routing.End(vehicle_nbr)).value() + 1 );
+ LG << "Route #" << vehicle_nbr + 1 << std::endl << route << std::endl;
+ }
+
+ } else {
+ LG << "No solution found.";
+ }
+
+} // void VRPSolver (CVRPData & data)
+
+
+} // namespace operations_research
+
+
+int main(int argc, char **argv) {
+ std::string usage("Computes a simple VRP.\n"
+ "See Google or-tools tutorials\n"
+ "Sample usage:\n\n");
+ usage += argv[0];
+ usage += " -instance_file=";
+
+ google::SetUsageMessage(usage);
+ google::ParseCommandLineFlags(&argc, &argv, true);
+
+ if (FLAGS_instance_file == "") {
+ std::cout << google::ProgramUsage();
+ exit(-1);
+ }
+ operations_research::TSPLIBReader tsplib_reader(FLAGS_instance_file);
+ operations_research::CVRPData cvrp_data(tsplib_reader);
+ operations_research::VRPSolver(cvrp_data);
+
+ return 0;
+} // main
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/chap10/vrp_solution_to_epix.cc b/documentation/tutorials/cplusplus/chap10/vrp_solution_to_epix.cc
new file mode 100644
index 0000000000..3b54723134
--- /dev/null
+++ b/documentation/tutorials/cplusplus/chap10/vrp_solution_to_epix.cc
@@ -0,0 +1,56 @@
+// 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.
+//
+//
+// Simple program to visualize a VRP solution.
+
+#include
+
+#include "base/commandlineflags.h"
+
+#include "cvrp_data.h"
+#include "cvrp_solution.h"
+#include "routing_common/tsplib_reader.h"
+#include "cvrp_epix_data.h"
+
+int main(int argc, char **argv) {
+ std::string usage("Prints a CVRP solution in ePiX format.\n"
+ "See Google or-tools tutorials\n"
+ "Sample usage:\n\n");
+ usage += argv[0];
+ usage += " -instance_file= -solution_file= > epix_file.xp\n\n";
+ usage += " ./elaps -pdf epix_file.xp\n";
+
+ google::SetUsageMessage(usage);
+ google::ParseCommandLineFlags(&argc, &argv, true);
+
+ if (FLAGS_instance_file != "" && FLAGS_solution_file != "") {
+ operations_research::TSPLIBReader tsplib_reader(FLAGS_instance_file);
+ operations_research::CVRPData cvrp_data(tsplib_reader);
+ operations_research::CVRPSolution cvrp_sol(cvrp_data, FLAGS_solution_file);
+ if (cvrp_sol.IsSolution()) {
+ if (cvrp_data.IsVisualizable()) {
+ operations_research::CVRPEpixData epix_data(cvrp_data);
+ epix_data.PrintSolution(std::cout, cvrp_sol);
+ } else {
+ LG << "Solution is not visualizable!";
+ }
+ } else {
+ LG << "Solution is NOT feasible...";
+ }
+ } else {
+ std::cout << google::ProgramUsage();
+ exit(-1);
+ }
+ return 0;
+}
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/chap13/Makefile b/documentation/tutorials/cplusplus/chap13/Makefile
new file mode 100644
index 0000000000..506c7ccec9
--- /dev/null
+++ b/documentation/tutorials/cplusplus/chap13/Makefile
@@ -0,0 +1,26 @@
+OR_TOOLS_TOP=/home/nikolaj/Documents/WORK/Google/or-tools-read-only
+OR_TOOLS_SOURCES=$(OR_TOOLS_TOP)/src
+
+TUTORIAL=/home/nikolaj/Documents/WORK/Google/OR_TOOLS_DOC/SOURCES/TUTORIALS/cplusplus
+
+SOURCES= rl_auxiliary_graph
+
+OBJECTS=$(SOURCES:.cc=.o)
+
+EXE=$(SOURCES:.cc=)
+
+include $(OR_TOOLS_TOP)/Makefile
+
+.PHONY: all local_clean
+
+all: $(EXE)
+
+rl_auxiliary_graph.o: rl_auxiliary_graph.cc $(OR_TOOLS_SOURCES)/constraint_solver/routing.h
+ $(CCC) $(CFLAGS) -c rl_auxiliary_graph.cc -o rl_auxiliary_graph.o
+
+rl_auxiliary_graph: $(ROUTING_DEPS) rl_auxiliary_graph.o
+ $(CCC) $(CFLAGS) rl_auxiliary_graph.o $(DYNAMIC_ROUTING_LNK) $(DYNAMIC_LD_FLAGS) -o rl_auxiliary_graph
+
+local_clean:
+ rm $(OBJECTS) $(EXE)
+
diff --git a/documentation/tutorials/cplusplus/chap13/rl_auxiliary_graph.cc b/documentation/tutorials/cplusplus/chap13/rl_auxiliary_graph.cc
new file mode 100644
index 0000000000..79944ad073
--- /dev/null
+++ b/documentation/tutorials/cplusplus/chap13/rl_auxiliary_graph.cc
@@ -0,0 +1,87 @@
+// 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.
+//
+#include
+#include
+
+#include "base/commandlineflags.h"
+#include "constraint_solver/routing.h"
+#include "base/join.h"
+
+namespace operations_research {
+
+// Not very interesting
+int64 MyCost(RoutingModel::NodeIndex from, RoutingModel::NodeIndex to) {
+ return (from + to).value();
+}
+
+
+void VRP_Partial_Routes(void) {
+ // create multi depots
+ std::vector > depots(4);
+ depots[0] = std::make_pair(1,4);
+ depots[1] = std::make_pair(3,4);
+ depots[2] = std::make_pair(3,7);
+ depots[3] = std::make_pair(4,7);
+
+ RoutingModel VRP(9, 4, depots);
+
+ VRP.SetCost(NewPermanentCallback(MyCost));
+
+ // Constructing routes
+ std::vector > routes(4);
+ // Constructing route 0 : 1 - 0 - 2 - 4
+ routes[0].push_back(RoutingModel::NodeIndex(0));
+ routes[0].push_back(RoutingModel::NodeIndex(2));
+ // Constructing route 1 : 3 - 5 - 4
+ routes[1].push_back(RoutingModel::NodeIndex(5));
+ // Constructing route 2 : 3 - 6 - 7
+ routes[2].push_back(RoutingModel::NodeIndex(6));
+ // Constructing route 3 : 4 - 8 - 7
+ routes[3].push_back(RoutingModel::NodeIndex(8));
+
+ VRP.CloseModel();
+
+ if (VRP.ApplyLocksToAllVehicles(routes, true)) {
+ LG << "Routes successfully locked";
+ } else {
+ LG << "Routes not successfully locked";
+ }
+
+ const Assignment* Solution = VRP.Solve();
+
+ for (int p = 0; p < VRP.vehicles(); ++p) {
+ LG << "Route: " << p;
+ std::string route;
+ std::string index_route;
+ for (int64 index = VRP.Start(p); !VRP.IsEnd(index); index = Solution->Value(VRP.NextVar(index))) {
+ route = StrCat(route, StrCat(VRP.IndexToNode(index).value(), " -> "));
+ index_route = StrCat(index_route, StrCat(index, " -> "));
+ }
+ route = StrCat(route, VRP.IndexToNode(VRP.End(p)).value());
+ index_route = StrCat(index_route, VRP.End(p));
+ LG << route;
+ LG << index_route;
+ }
+
+} // void VRP_Partial_Routes(void)
+
+} // namespace operations_research
+
+int main(int argc, char **argv) {
+
+ google::ParseCommandLineFlags(&argc, &argv, true);
+ operations_research::VRP_Partial_Routes();
+
+ return 0;
+} // main
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/chap6/.kdev_include_paths b/documentation/tutorials/cplusplus/chap6/.kdev_include_paths
deleted file mode 100644
index 380f496939..0000000000
--- a/documentation/tutorials/cplusplus/chap6/.kdev_include_paths
+++ /dev/null
@@ -1,2 +0,0 @@
-RESOLVE: SOURCE=/home/nikolaj/Documents/WORK/Google/or-tools-read-only/src BUILD=
-/home/nikolaj/Documents/WORK/Google/or-tools-read-only/src
diff --git a/documentation/tutorials/cplusplus/chap6/chap6.kdev4 b/documentation/tutorials/cplusplus/chap6/chap6.kdev4
deleted file mode 100644
index 185220d7c1..0000000000
--- a/documentation/tutorials/cplusplus/chap6/chap6.kdev4
+++ /dev/null
@@ -1,3 +0,0 @@
-[Project]
-Manager=KDevCustomMakeManager
-Name=chap6
diff --git a/documentation/tutorials/cplusplus/common/IO_helpers.h b/documentation/tutorials/cplusplus/common/IO_helpers.h
new file mode 100644
index 0000000000..542073632b
--- /dev/null
+++ b/documentation/tutorials/cplusplus/common/IO_helpers.h
@@ -0,0 +1,98 @@
+// 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.
+//
+//
+// Some helpers for Input/Ouput.
+
+#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_IO_HELPERS_H
+#define OR_TOOLS_TUTORIALS_CPLUSPLUS_IO_HELPERS_H
+
+namespace operations_research {
+
+// Generic class to write an object of class T to a file thanks
+// to one of its member with MemberSignature signature.
+// We restrict ourself to this signature as all checking are done with
+// asserts.
+// You must pass a FULLY qualified method name to SetMember()!
+template
+class WriteToFile {
+public:
+ typedef void (T::*MemberSignature)(std::ostream &) const;
+ WriteToFile(const T * t, const std::string & filename) : t_(t), filename_(filename), member_(NULL) {};
+ void SetMember(MemberSignature m) {
+ member_ = m;
+ }
+ void Run() {
+ std::ofstream write_stream(filename_.c_str());
+ CHECK_EQ(write_stream.is_open(), true) << "Unable to open file: " << filename_;
+ CHECK_NE(member_, NULL) << "Object method is not set!";
+ (t_->*member_)(write_stream);
+ write_stream.close();
+ }
+private:
+ const T * t_;
+ const std::string & filename_;
+ MemberSignature member_;
+};
+
+// Same but with an additional parameter.
+template
+class WriteToFileP1 {
+public:
+ typedef void (T::*MemberSignature)(std::ostream &, const P1 &) const;
+ WriteToFileP1(const T * t, const std::string & filename) : t_(t), filename_(filename), member_(NULL) {};
+ void SetMember(MemberSignature m) {
+ member_ = m;
+ }
+ void Run(const P1 & p) {
+ std::ofstream write_stream(filename_.c_str());
+ CHECK_EQ(write_stream.is_open(), true) << "Unable to open file: " << filename_;
+ CHECK_NE(member_, NULL) << "Object method is not set!";
+ (t_->*member_)(write_stream, p);
+ write_stream.close();
+ }
+private:
+ const T * t_;
+ const std::string & filename_;
+ MemberSignature member_;
+};
+
+// One entry class to "fatally" log to different std::ostreams if needed.
+class FatalInstanceLoadingLog {
+public:
+ FatalInstanceLoadingLog() {}
+ void AddOutputStream(std::ostream * out) {
+ streams_.push_back(out);
+ }
+ void Write(const char * msg, const std::string & wrong_keyword = "", int line_number = -1) {
+ std::stringstream line;
+ line << msg;
+ if (wrong_keyword != "") {
+ line << ": \"" << wrong_keyword << "\"";
+ }
+ if (line_number != -1) {
+ line << " on line " << line_number;
+ }
+ line << std::endl;
+ for (int i = 0; i < streams_.size(); ++i) {
+ (*streams_[i]) << line.str();
+ }
+ LOG(FATAL) << msg << ": \"" << wrong_keyword << "\" on line " << line_number;
+ }
+private:
+ std::vector streams_;
+};
+
+} // namespace operations_research
+
+#endif // OR_TOOLS_TUTORIALS_CPLUSPLUS_IO_HELPERS_H
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/common/common_flags.h b/documentation/tutorials/cplusplus/common/common_flags.h
new file mode 100644
index 0000000000..d5d09dcca8
--- /dev/null
+++ b/documentation/tutorials/cplusplus/common/common_flags.h
@@ -0,0 +1,30 @@
+// 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 flags.
+
+#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_COMMON_FLAGS_H
+#define OR_TOOLS_TUTORIALS_CPLUSPLUS_COMMON_FLAGS_H
+
+#include "base/commandlineflags.h"
+
+#include "common/constants.h"
+
+DEFINE_bool(deterministic_random_seed, true,
+ "Use deterministic random seeds or not?");
+
+DEFINE_int32(random_generated_graph_max_edges_percent, 80, "Maximal percent of edges allowed for a randomly generated graph.");
+DEFINE_bool(print_graph_labels, true, "Print graph labels for nodes?");
+
+#endif // OR_TOOLS_TUTORIALS_CPLUSPLUS_COMMON_FLAGS_H
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/common/constants.h b/documentation/tutorials/cplusplus/common/constants.h
new file mode 100644
index 0000000000..108b02b89a
--- /dev/null
+++ b/documentation/tutorials/cplusplus/common/constants.h
@@ -0,0 +1,27 @@
+// 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 constants.
+
+#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_CONSTANTS_H
+#define OR_TOOLS_TUTORIALS_CPLUSPLUS_CONSTANTS_H
+
+namespace operations_research {
+
+const static int64 kPostiveInfinityInt64 = std::numeric_limits::max();
+
+
+} // namespace operations_research
+
+#endif // OR_TOOLS_TUTORIALS_CPLUSPLUS_CONSTANTS_H
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/common/limits.h b/documentation/tutorials/cplusplus/common/limits.h
new file mode 100644
index 0000000000..d6ea739a2e
--- /dev/null
+++ b/documentation/tutorials/cplusplus/common/limits.h
@@ -0,0 +1,222 @@
+// 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 base for custom SearchLimits via callbacks.
+
+#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_COMMON_LIMITS_H
+#define OR_TOOLS_TUTORIALS_CPLUSPLUS_COMMON_LIMITS_H
+
+#include
+#include
+#include
+#include
+#include
+
+#include "base/bitmap.h"
+#include "base/logging.h"
+#include "base/file.h"
+#include "base/split.h"
+#include "base/filelinereader.h"
+#include "base/join.h"
+#include "base/strtoint.h"
+
+#include "constraint_solver/constraint_solver.h"
+
+
+namespace operations_research {
+
+ namespace {
+class LSInitialSolLimit : public ResultCallback {
+ public:
+ LSInitialSolLimit(Solver * solver, int64 global_time_limit,
+ int solution_nbr_tolerance) :
+ solver_(solver), global_time_limit_(global_time_limit),
+ solution_nbr_tolerance_(solution_nbr_tolerance),
+ time_at_beginning_(solver_->wall_time()),
+ solutions_at_beginning_(solver_->solutions()),
+ solutions_since_last_check_(0) {}
+
+ // Returns true if limit is reached, false otherwise.
+ virtual bool Run() {
+ bool limit_reached = false;
+
+ // Test if time limit is reached.
+ if ((solver_->wall_time() - time_at_beginning_)
+ > global_time_limit_) {
+ limit_reached = true;
+ // Test if we continue despite time limit reached.
+ if (solver_->solutions() - solutions_since_last_check_
+ >= solution_nbr_tolerance_) {
+ // We continue because we produce enough new solutions.
+ limit_reached = false;
+ }
+ }
+ solutions_since_last_check_ = solver_->solutions();
+
+ return limit_reached;
+ }
+
+ private:
+ Solver * solver_;
+ int64 global_time_limit_;
+ int solution_nbr_tolerance_;
+
+ int64 time_at_beginning_;
+ int solutions_at_beginning_;
+ int solutions_since_last_check_;
+};
+
+ }
+
+SearchLimit * MakeLSInitialSolLimit(Solver * solver,
+ int64 global_time_limit,
+ int solution_nbr_tolerance) {
+
+ // By default, the solver takes the ownership of the callback, no need to delete it!
+ return solver->MakeCustomLimit(new LSInitialSolLimit(solver, global_time_limit, solution_nbr_tolerance));
+}
+
+
+extern "C" {
+ bool limit_reached = false;
+ void CTRLBreakHandler(int s) {
+ LG << "Ctrl-break catched! exit properly..";
+ limit_reached = true;
+ }
+}
+
+namespace {
+
+class CatchCTRLBreakLimit : public ResultCallback {
+ public:
+ CatchCTRLBreakLimit(Solver * solver) :
+ solver_(solver) {
+sigIntHandler_.sa_handler = CTRLBreakHandler;
+ sigemptyset(&sigIntHandler_.sa_mask);
+ sigIntHandler_.sa_flags = 0;
+
+ sigaction(SIGINT, &sigIntHandler_, NULL);
+ }
+
+ // Returns true if limit is reached, false otherwise.
+ virtual bool Run() {
+ return limit_reached;
+ }
+
+ private:
+ Solver * solver_;
+ static bool limit_reached_;
+ struct sigaction sigIntHandler_;
+};
+
+}
+
+SearchLimit * MakeCatchCTRLBreakLimit(Solver * solver) {
+ return solver->MakeCustomLimit(new CatchCTRLBreakLimit(solver));
+}
+
+namespace {
+
+class NoImprovementLimit : public SearchLimit {
+ public:
+ NoImprovementLimit(Solver * solver, int solution_nbr_tolerance, bool minimize = true) :
+ SearchLimit(solver),
+ solver_(solver), prototype_(new Assignment(solver_)),
+ solution_nbr_tolerance_(solution_nbr_tolerance),
+ nbr_solutions_with_no_better_obj_(0),
+ minimize_(minimize),
+ limit_reached_(false) {
+ if (minimize_) {
+ best_result_ = kint64max;
+ } else {
+ best_result_ = kint64min;
+ }
+ }
+
+ void AddObjective(IntVar* const objective) {
+ if (prototype_.get() != NULL && objective != NULL) {
+ prototype_->AddObjective(objective);
+ }
+ }
+
+ virtual void Init() {
+ nbr_solutions_with_no_better_obj_ = 0;
+ limit_reached_ = false;
+ if (minimize_) {
+ best_result_ = kint64max;
+ } else {
+ best_result_ = kint64min;
+ }
+ }
+
+ // Returns true if limit is reached, false otherwise.
+ virtual bool Check() {
+ return limit_reached_;
+ }
+
+ virtual bool AtSolution() {
+ ++nbr_solutions_with_no_better_obj_;
+ if (prototype_.get() != NULL) {
+ prototype_->Store();
+ const IntVar* objective = prototype_->Objective();
+ solver_->state();
+ if (objective != NULL) {
+ if (minimize_ && objective->Min() < best_result_) {
+ best_result_ = objective->Min();
+ nbr_solutions_with_no_better_obj_ = 0;
+ } else if (!minimize_ && objective->Max() > best_result_) {
+ best_result_ = objective->Max();
+ nbr_solutions_with_no_better_obj_ = 0;
+ }
+ }
+ }
+ if (nbr_solutions_with_no_better_obj_ > solution_nbr_tolerance_) {
+ limit_reached_ = true;
+ }
+ return true;
+ }
+
+ virtual void Copy(const SearchLimit* const limit) {
+ const NoImprovementLimit* const copy_limit =
+ reinterpret_cast(limit);
+ int64 best_result_ = copy_limit->best_result_;
+ int solution_nbr_tolerance_ = copy_limit->solution_nbr_tolerance_;
+ bool minimize_ = copy_limit->minimize_;
+ bool limit_reached_ = copy_limit->limit_reached_;
+ int nbr_solutions_with_no_better_obj_ = copy_limit->nbr_solutions_with_no_better_obj_;
+ }
+
+ // Allocates a clone of the limit
+ virtual SearchLimit* MakeClone() const {
+ return solver_->RevAlloc(new NoImprovementLimit(solver_, solution_nbr_tolerance_, minimize_));
+ }
+
+ private:
+ Solver * solver_;
+ int64 best_result_;
+ int solution_nbr_tolerance_;
+ bool minimize_;
+ bool limit_reached_;
+ int nbr_solutions_with_no_better_obj_;
+ std::unique_ptr prototype_;
+};
+
+}
+
+NoImprovementLimit * MakeNoImprovementLimit(Solver * solver, int solution_nbr_tolerance, bool minimize = true) {
+ return solver->RevAlloc(new NoImprovementLimit(solver, solution_nbr_tolerance, minimize));
+}
+}
+
+#endif // OR_TOOLS_TUTORIALS_CPLUSPLUS_COMMON_LIMITS_H
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/common/random.h b/documentation/tutorials/cplusplus/common/random.h
new file mode 100644
index 0000000000..338f5368e6
--- /dev/null
+++ b/documentation/tutorials/cplusplus/common/random.h
@@ -0,0 +1,39 @@
+// 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.
+//
+//
+// Several helper functions to generate random numbers.
+
+#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_RANDOM_H
+#define OR_TOOLS_TUTORIALS_CPLUSPLUS_RANDOM_H
+
+#include "base/random.h"
+
+#include "common/constants.h"
+
+#include "common/common_flags.h"
+
+namespace operations_research {
+
+// Random seed generator.
+int32 GetSeed() {
+ if (FLAGS_deterministic_random_seed) {
+ return ACMRandom::DeterministicSeed();
+ } else {
+ return ACMRandom::HostnamePidTimeSeed();
+ }
+}
+
+} // namespace opertional_research
+
+#endif // OR_TOOLS_TUTORIALS_CPLUSPLUS_RANDOM_H
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/routing_common/routing_common.h b/documentation/tutorials/cplusplus/routing_common/routing_common.h
new file mode 100644
index 0000000000..f70c3fd1e5
--- /dev/null
+++ b/documentation/tutorials/cplusplus/routing_common/routing_common.h
@@ -0,0 +1,230 @@
+// 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
+#include
+#include
+#include
+#include
+
+#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_;
+ std::unique_ptr 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::max()),
+ max_x(std::numeric_limits::min()),
+ min_y(std::numeric_limits::max()),
+ max_y(std::numeric_limits::min()),
+ min_z(std::numeric_limits::max()),
+ max_z(std::numeric_limits::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
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/routing_common/routing_common_flags.h b/documentation/tutorials/cplusplus/routing_common/routing_common_flags.h
new file mode 100644
index 0000000000..ef73d5c376
--- /dev/null
+++ b/documentation/tutorials/cplusplus/routing_common/routing_common_flags.h
@@ -0,0 +1,57 @@
+// 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 flags.
+
+#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_COMMON_FLAGS_H
+#define OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_COMMON_FLAGS_H
+
+#include "base/commandlineflags.h"
+
+#include "common/constants.h"
+
+DEFINE_int32(instance_size, 10, "Number of nodes, including the depot.");
+DEFINE_string(instance_name, "Dummy instance", "Instance name.");
+
+DEFINE_int32(instance_depot, 0, "Depot for instance.");
+
+DEFINE_string(instance_file, "", "TSPLIB instance file.");
+DEFINE_string(solution_file, "", "TSPLIB solution file.");
+
+DEFINE_string(distance_file, "", "TSP matrix distance file.");
+
+
+DEFINE_int32(edge_min, 1, "Minimum edge value.");
+DEFINE_int32(edge_max, 100, "Maximum edge value.");
+
+
+DEFINE_int32(instance_edges_percent, 20, "Percent of edges in the graph.");
+
+DEFINE_int32(x_max, 100, "Maximum x coordinate.");
+DEFINE_int32(y_max, 100, "Maximum y coordinate.");
+
+
+DEFINE_int32(width_size, 6, "Width size of fields in output.");
+
+DEFINE_int32(epix_width, 10, "Width of the pictures in cm.");
+DEFINE_int32(epix_height, 10, "Height of the pictures in cm.");
+
+DEFINE_double(epix_radius, 0.3, "Radius of circles.");
+
+DEFINE_bool(epix_node_labels, false, "Print node labels?");
+
+DEFINE_int32(percentage_forbidden_arcs_max, 94, "Maximum percentage of arcs to forbid.");
+DEFINE_int64(M, operations_research::kPostiveInfinityInt64, "Big m value to represent infinity.");
+
+#endif // OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_COMMON_FLAGS_H
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/routing_common/routing_data.h b/documentation/tutorials/cplusplus/routing_common/routing_data.h
new file mode 100644
index 0000000000..d21dae31bb
--- /dev/null
+++ b/documentation/tutorials/cplusplus/routing_common/routing_data.h
@@ -0,0 +1,228 @@
+// 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 minimalistic base for routing data (instance) classes.
+
+#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_DATA_H
+#define OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_DATA_H
+
+#include
+
+#include "constraint_solver/routing.h"
+
+#include "routing_common/routing_common.h"
+#include "routing_common/routing_data_generator.h"
+
+DECLARE_int32(width_size);
+
+namespace operations_research {
+
+// Forward declaration.
+class TSPLIBReader;
+
+
+// Base class with Routing Data (instances).
+class RoutingData {
+public:
+ explicit RoutingData(int32 size = 0) : size_(size), name_("no name"), is_routing_data_created_(false), is_routing_data_instanciated_(false),
+ has_coordinates_(false), has_diplay_coords_(false), raw_bbox_(BoundingBox())
+ {
+ if (size > 0) {
+ CreateRoutingData(size);
+ }
+ }
+ explicit RoutingData(const RoutingDataGenerator & g): size_(g.Size()), name_(g.InstanceName()), is_routing_data_created_(false), is_routing_data_instanciated_(false),
+ has_coordinates_(false), has_diplay_coords_(false), raw_bbox_(BoundingBox())
+ {
+ if (Size() > 0) {
+ CreateRoutingData(Size());
+ for (RoutingModel::NodeIndex i(0); i < Size(); ++i) {
+ Coordinate(i) = g.Coordinate(i);
+ for (RoutingModel::NodeIndex j(0); j < Size(); ++j) {
+ InternalDistance(i,j) = g.Distance(i,j);
+ }
+ }
+ SetRoutingDataInstanciated();
+ SetHasCoordinates();
+ }
+
+ }
+
+ explicit RoutingData(const RoutingData & other) {
+ CreateRoutingData(other.Size());
+ name_ = other.Name();
+ comment_ = other.Comment();
+ for (RoutingModel::NodeIndex i(RoutingModel::kFirstNode); i < Size(); ++i) {
+ for (RoutingModel::NodeIndex j(RoutingModel::kFirstNode); j < Size(); ++j) {
+ InternalDistance(i,j) = other.Distance(i,j);
+ }
+ }
+
+ if (other.HasDisplayCoordinates()) {
+ for (RoutingModel::NodeIndex i(RoutingModel::kFirstNode); i < Size(); ++i) {
+ Coordinate(i) = other.Coordinate(i);
+ }
+ }
+
+ if (other.HasCoordinates()) {
+ for (RoutingModel::NodeIndex i(RoutingModel::kFirstNode); i < Size(); ++i) {
+ DisplayCoordinate(i) = other.DisplayCoordinate(i);
+ }
+ }
+ SetHasCoordinates(other.HasCoordinates());
+ SetHasDisplayCoordinates(other.HasDisplayCoordinates());
+ SetRoutingDataInstanciated();
+ }
+
+
+ virtual ~RoutingData() {}
+
+ void SetHasCoordinates(const bool coordinates = true) {
+ has_coordinates_ = coordinates;
+ }
+
+ void SetHasDisplayCoordinates(const bool display_coordinates = true) {
+ has_diplay_coords_ = display_coordinates;
+ }
+
+ bool HasCoordinates() const {
+ return has_coordinates_;
+ }
+
+ bool HasDisplayCoordinates() const {
+ return has_diplay_coords_;
+ }
+
+ bool IsVisualizable() const {
+ return HasCoordinates() || HasDisplayCoordinates();
+ }
+
+ int32 Size() const {
+ return size_;
+ }
+
+ std::string Name() const {
+ return name_;
+ }
+
+ std::string Comment() const {
+ return comment_;
+ }
+
+ int64 Distance(RoutingModel::NodeIndex i, RoutingModel::NodeIndex j) const {
+ CheckNodeIsValid(i);
+ return distances_.Cost(i,j);
+ }
+
+ Point Coordinate(RoutingModel::NodeIndex i) const {
+ CheckNodeIsValid(i);
+ return coordinates_[i.value()];
+ }
+
+ Point DisplayCoordinate(RoutingModel::NodeIndex i) const {
+ CheckNodeIsValid(i);
+ return display_coords_[i.value()];
+ }
+
+ BoundingBox RawBoundingBox() const {
+ return raw_bbox_;
+ }
+
+ void PrintDistanceMatrix(std::ostream& out, const int32 & width = FLAGS_width_size) const;
+ void WriteDistanceMatrix(const std::string & filename, const int32 & width = FLAGS_width_size) const;
+
+protected:
+ void CreateRoutingData(int32 size) {
+ size_ = size;
+ distances_.Create(size);
+ coordinates_.resize(size);
+ display_coords_.resize(size);
+ is_routing_data_created_ = true;
+ }
+
+ bool IsRoutingDataCreated() const {
+ return is_routing_data_created_;
+ }
+
+ bool IsRoutingDataInstanciated() const {
+ return is_routing_data_instanciated_;
+ }
+
+ void SetRoutingDataInstanciated() {
+ is_routing_data_instanciated_ = true;
+ distances_.SetIsInstanciated();
+ //Find bounding box
+ if (HasDisplayCoordinates()) {
+ for (int32 i = 0; i < Size(); ++i ) {
+ raw_bbox_.Update(display_coords_[i]);
+ }
+ } else if (HasCoordinates()) {
+ for (int32 i = 0; i < Size(); ++i ) {
+ raw_bbox_.Update(coordinates_[i]);
+ }
+ }
+ }
+
+ void CheckNodeIsValid(const RoutingModel::NodeIndex i) const {
+ CHECK_GE(i.value(), 0) << "Internal node " << i.value() << " should be greater than 0!";
+ CHECK_LT(i.value(), Size()) << "Internal node " << i.value() << " should be less than " << Size();
+ }
+
+ int64& InternalDistance(RoutingModel::NodeIndex i, RoutingModel::NodeIndex j) {
+ CheckNodeIsValid(i);
+ CheckNodeIsValid(j);
+ return distances_.Cost(i,j);
+ }
+
+ Point& Coordinate(RoutingModel::NodeIndex i) {
+ CheckNodeIsValid(i);
+ return coordinates_[i.value()];
+ }
+
+ Point& DisplayCoordinate(RoutingModel::NodeIndex i) {
+ CheckNodeIsValid(i);
+ return display_coords_[i.value()];
+ }
+
+protected:
+ int32 size_;
+ std::string name_;
+ std::string comment_;
+private:
+ bool is_routing_data_created_;
+ bool is_routing_data_instanciated_;
+ bool has_coordinates_;
+ bool has_diplay_coords_;
+protected:
+ CompleteGraphArcCost distances_;
+ std::vector coordinates_;
+ std::vector display_coords_;
+ BoundingBox raw_bbox_;
+
+};
+
+void RoutingData::PrintDistanceMatrix(std::ostream& out, const int32 & width) const {
+ distances_.Print(out, width);
+}
+
+void RoutingData::WriteDistanceMatrix(const std::string& filename, const int32 & width) const {
+ WriteToFileP1 writer(this, filename);
+ writer.SetMember(&operations_research::RoutingData::PrintDistanceMatrix);
+ writer.Run(width);
+}
+
+
+} // namespace operations_research
+
+#endif // OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_DATA_H
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/routing_common/routing_data_generator.h b/documentation/tutorials/cplusplus/routing_common/routing_data_generator.h
new file mode 100644
index 0000000000..22067768af
--- /dev/null
+++ b/documentation/tutorials/cplusplus/routing_common/routing_data_generator.h
@@ -0,0 +1,80 @@
+// 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 base to generate routing data (instances).
+
+#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_DATA_GENERATOR_H
+#define OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_DATA_GENERATOR_H
+
+#include
+
+#include "base/join.h"
+#include "base/integral_types.h"
+#include "constraint_solver/routing.h"
+
+#include "common/random.h"
+#include "routing_common/routing_common_flags.h"
+#include "routing_common/routing_common.h"
+#include "routing_common/routing_random.h"
+#include "routing_common/routing_distance.h"
+
+namespace operations_research {
+ class RoutingDataGenerator {
+ public:
+ RoutingDataGenerator(std::string problem_name, std::string instance_name, int32 size) :
+ problem_name_(problem_name), instance_name_(instance_name), size_(size), randomizer_(GetSeed()),
+ coordinates_(size_), dist_coords_(coordinates_) {}
+ int64 Distance(RoutingModel::NodeIndex i, RoutingModel::NodeIndex j) const {
+ return dist_coords_.Distance(i,j);
+ }
+
+ Point Coordinate(RoutingModel::NodeIndex i) const {
+ return coordinates_.Coordinate(i);
+ }
+ std::string ProblemName() const {
+ return problem_name_;
+ }
+ std::string InstanceName() const {
+ return instance_name_;
+ }
+ int32 Size() const {
+ return size_;
+ }
+
+ void ReplaceDistance(RoutingModel::NodeIndex i, RoutingModel::NodeIndex j, int64 dist) {
+ dist_coords_.ReplaceDistance(i, j, dist);
+ }
+ protected:
+ std::string problem_name_;
+ std::string instance_name_;
+ int32 size_;
+ ACMRandom randomizer_;
+ GenerateTWODCoordinates coordinates_;
+ DistancesFromTWODCoordinates dist_coords_;
+
+ };
+
+ // Common usage message for instance generators.
+ std::string GeneratorUsage(std::string invocation, std::string problem_name) {
+ return StrCat("Generates a ", problem_name, " instance.\n"
+ "See Google or-tools tutorials\n"
+ "Sample usage:\n\n",
+ invocation,
+ " -instance_name= -instance_size=\n\n");
+ }
+} // namespace operations_research
+
+#endif // OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_DATA_GENERATOR_H
+
+
diff --git a/documentation/tutorials/cplusplus/routing_common/routing_distance.h b/documentation/tutorials/cplusplus/routing_common/routing_distance.h
new file mode 100644
index 0000000000..461c660d63
--- /dev/null
+++ b/documentation/tutorials/cplusplus/routing_common/routing_distance.h
@@ -0,0 +1,76 @@
+// 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 distance stuff.
+
+#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_DISTANCE_H
+#define OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_DISTANCE_H
+
+#include
+
+#include "constraint_solver/routing.h"
+
+#include "routing_random.h"
+#include "tsplib.h"
+
+DECLARE_int32(width_size);
+
+namespace operations_research {
+
+ class CompleteGraphDistances {
+ public:
+ CompleteGraphDistances(int32 size): size_(size), costs_(size_) {}
+ virtual int64 Distance(RoutingModel::NodeIndex i, RoutingModel::NodeIndex j) const = 0;
+ int32 Size() const {
+ return size_;
+ }
+ void Print(std::ostream & out, const int width = FLAGS_width_size);
+ void ReplaceDistance(RoutingModel::NodeIndex i, RoutingModel::NodeIndex j, int64 dist) {
+ costs_.Cost(i,j) = dist;
+ }
+ private:
+ int32 size_;
+ protected:
+ CompleteGraphArcCost costs_;
+ };
+
+ void CompleteGraphDistances::Print(std::ostream & out, const int width) {
+ costs_.Print(out, width);
+ }
+
+ // Basic distance class on "complete" graphs from coordinates.
+ class DistancesFromTWODCoordinates : public CompleteGraphDistances {
+ public:
+ explicit DistancesFromTWODCoordinates(const GenerateTWODCoordinates& coords): CompleteGraphDistances(coords.Size()), coords_(coords) {
+ for (RoutingModel::NodeIndex i(0); i < Size(); ++i) {
+ costs_.Cost(i,i) = 0;
+ for (RoutingModel::NodeIndex j(i.value()+1); j < Size(); ++j) {
+ int64 dist = TSPLIBDistanceFunctions::TWOD_euc_2d_distance(coords_.Coordinate(i), coords_.Coordinate(j));
+ costs_.Cost(i,j) = dist;
+ costs_.Cost(j,i) = dist;
+ }
+ }
+ }
+ virtual int64 Distance(RoutingModel::NodeIndex i, RoutingModel::NodeIndex j) const {
+ return costs_.Cost(i,j);
+ }
+ void ReplaceDistance(RoutingModel::NodeIndex i, RoutingModel::NodeIndex j, int64 dist) {
+ costs_.Cost(i,j) = dist;
+ }
+ private:
+ const GenerateTWODCoordinates& coords_;
+ };
+} // namespace operations_research
+
+#endif // OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_COMMON_H
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/routing_common/routing_epix_helper.h b/documentation/tutorials/cplusplus/routing_common/routing_epix_helper.h
new file mode 100644
index 0000000000..733a6825d4
--- /dev/null
+++ b/documentation/tutorials/cplusplus/routing_common/routing_epix_helper.h
@@ -0,0 +1,124 @@
+// 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 base to use the epix library to visualize
+// routing data (instance) and solutions.
+
+#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_EPIX_HELPER_H
+#define OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_EPIX_HELPER_H
+
+#include
+
+#include "constraint_solver/routing.h"
+#include "base/join.h"
+
+#include "routing_common/routing_common.h"
+
+namespace operations_research {
+
+class RoutingEpixHelper {
+public:
+ explicit RoutingEpixHelper(std::ostream & out) : out_(&out) {}
+ void SetOuptutStream(std::ostream & out) {
+ out_ = &out;
+ }
+private:
+ std::ostream * out_;
+};
+
+ void PrintEpixBeginFile(std::ostream & out) {
+ out << "#include \"epix.h\"" << std::endl;
+ out << "using namespace ePiX;" << std::endl;
+ out << std::endl;
+ out << "int main(int argc, char **argv)" << std::endl;
+ out << "{" << std::endl;
+ }
+
+ void PrintEpixPreamble(std::ostream & out) {
+ out << std::endl;
+ out << "unitlength(\"1cm\");" << std::endl;
+ out << "picture(" << FLAGS_epix_width << "," << FLAGS_epix_height << ");" << std::endl;
+ out << "double radius = " << FLAGS_epix_radius << ";" << std::endl;
+ out << "font_size(\"tiny\");" << std::endl;
+ }
+
+ void PrintEpixBoundingBox(std::ostream & out, const BoundingBox & P) {
+ out << "bounding_box(P(" << P.min_x << "," << P.min_y << "), P(" << P.max_x << "," << P.max_y << "));" << std::endl;
+ }
+
+
+ void PrintEpixBeginFigure(std::ostream & out) {
+ out << std::endl;
+ out << "begin(); // ---- Figure body starts here ----" << std::endl;
+ }
+
+ void PrintEpixEndFigure(std::ostream & out) {
+ out << std::endl;
+ out << "end(); // ---- End figure; write output file ----" << std::endl;
+ }
+
+ void PrintEpixEndFile(std::ostream & out) {
+ out << std::endl;
+ out << "}" << std::endl;
+ }
+
+ void PrintEpixNewLine(std::ostream & out) {
+ out << std::endl;
+ }
+
+ void PrintEpixRaw(std::ostream & out, const char* s) {
+ out << s << std::endl;
+ }
+
+ void PrintEpixComment(std::ostream & out, const char* s) {
+ out << " // " << s << std::endl;
+ }
+
+ void PrintEpixPoint(std::ostream & out, Point p, RoutingModel::NodeIndex i) {
+ out << " P " << StrCat("P",i.value()) << "(" << p.x << "," << p.y << ");" << std::endl;
+ out << StrCat(" Circle C",i.value()) << StrCat("(P",i.value()) << ", radius);" << std::endl;
+ }
+
+ void PrintEpixSegment(std::ostream & out, int segment_index, RoutingModel::NodeIndex i, RoutingModel::NodeIndex j) {
+ out << StrCat(" Segment L", segment_index) <<"(P" << StrCat(i.value()) << ",P" <<
+ StrCat(j.value()) << ");" << std::endl;
+ }
+
+ void PrintEpixDepot(std::ostream & out, RoutingModel::NodeIndex d) {
+ out << " fill(Red());" << std::endl;
+ out << StrCat(" C", d.value(), ".draw();") << std::endl;
+ out << " fill(White());" << std::endl;
+ }
+
+ void PrintEpixDrawMultiplePoints(std::ostream & out, int size) {
+ for (int i = 0; i < size; ++i) {
+ out << StrCat(" C",i) << ".draw();" << std::endl;
+ if (FLAGS_epix_node_labels) {
+ out << StrCat(" label (P", i) << StrCat(",P(0.2,0.1),\"", i+1 ) << "\",tr);" << std::endl;
+ }
+ }
+ }
+ void PrintEpixArrow(std::ostream & out, RoutingModel::NodeIndex from_node, RoutingModel::NodeIndex to_node) {
+ out << "arrow " <<"(P" << from_node.value() << ", P" << to_node.value() << ");" << std::endl;
+ }
+
+ void PrintEpixDrawMultipleSegments(std::ostream & out, int size) {
+ for (int i = 0; i < size; ++i) {
+ out << StrCat(" L",i) << ".draw();" << std::endl;
+ }
+ }
+
+} // namespace operations_research
+
+#endif // OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_EPIX_HELPER_H
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/routing_common/routing_random.h b/documentation/tutorials/cplusplus/routing_common/routing_random.h
new file mode 100644
index 0000000000..ed05fe73b8
--- /dev/null
+++ b/documentation/tutorials/cplusplus/routing_common/routing_random.h
@@ -0,0 +1,73 @@
+// 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 random routing stuff.
+
+#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_RANDOM_H
+#define OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_RANDOM_H
+
+#include
+#include
+
+#include "base/random.h"
+#include "constraint_solver/routing.h"
+
+#include "common/random.h"
+#include "routing_common/routing_common.h"
+
+namespace operations_research {
+
+
+class GenerateTWODCoordinates {
+public:
+ GenerateTWODCoordinates(int32 size): size_(size), randomizer_(GetSeed()), coordinates_(size_) {
+ Generate();
+ }
+ const Point Coordinate(RoutingModel::NodeIndex i) const {
+ return coordinates_[i.value()];
+ }
+ const int32 Size() const {
+ return size_;
+ }
+private:
+ void Generate() {
+ bool coord_found = false;
+ int32 x = 0;
+ int32 y = 0;
+ for (int32 i = 0; i < size_; i++) {
+ coord_found = false;
+ while (!coord_found) {
+ x = randomizer_.Uniform(FLAGS_x_max);
+ y = randomizer_.Uniform(FLAGS_y_max);
+ // test if coordinates are not already taken
+ // maybe we should ask for a minimum distance between points?
+ coord_found = true;
+ for (int32 j = 0; j < i; ++j) {
+ if (x == coordinates_[j].x && y == coordinates_[j].y) {
+ coord_found = false;
+ break;
+ }
+ }
+ }
+ coordinates_[i] = Point(x, y);
+ }
+ }
+ int32 size_;
+ ACMRandom randomizer_;
+ std::vector coordinates_;
+
+};
+} // namespace operations_research
+
+#endif // OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_RANDOM_H
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/routing_common/routing_solution.h b/documentation/tutorials/cplusplus/routing_common/routing_solution.h
new file mode 100644
index 0000000000..15034aa2ec
--- /dev/null
+++ b/documentation/tutorials/cplusplus/routing_common/routing_solution.h
@@ -0,0 +1,51 @@
+// 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 base for routing solution classes.
+// A route is given by its depot (first node) and then the path (except for the first node), e.g.
+// RoutingSolution 1 -> 2 -> 5 is in fact path 1 -> 2 -> 5 -> 1 and 1 is a depot.
+
+#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_SOLUTION_H
+#define OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_SOLUTION_H
+
+#include "constraint_solver/routing.h"
+
+#include "routing_data.h"
+
+namespace operations_research {
+
+ class RoutingSolution {
+ public:
+ explicit RoutingSolution(const RoutingData & data) : size_(data.Size()) {}
+ virtual ~RoutingSolution() {}
+ virtual bool IsSolution() const = 0;
+ virtual bool IsFeasibleSolution() const = 0;
+ virtual int64 ComputeObjectiveValue() const = 0;
+
+ void SetSize(int32 size) {
+ size_ = size;
+ }
+ // Size of the instance.
+ int32 Size() const {
+ return size_;
+ }
+ virtual bool Add(RoutingModel::NodeIndex i, int route_number = 0) = 0;
+ virtual void Print(std::ostream & out) const = 0;
+ protected:
+ int32 size_;
+ };
+
+} // namespace operations_research
+
+#endif // OR_TOOLS_TUTORIALS_CPLUSPLUS_ROUTING_SOLUTION_H
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/routing_common/tsplib.h b/documentation/tutorials/cplusplus/routing_common/tsplib.h
new file mode 100644
index 0000000000..cdced5a2d9
--- /dev/null
+++ b/documentation/tutorials/cplusplus/routing_common/tsplib.h
@@ -0,0 +1,406 @@
+// 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.
+//
+//
+// Definitions for the TSPLIB format.
+
+#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_TSPLIB_H
+#define OR_TOOLS_TUTORIALS_CPLUSPLUS_TSPLIB_H
+
+#include
+#include
+
+//#include "base/commandlineflags.h"
+#include "base/integral_types.h"
+
+#include "routing_common.h"
+
+//DEFINE_bool(tsp_start_counting_at_1, true, "TSPLIB convention: first node is 1 (not 0).");
+
+// You can find the technical description of the TSPLIB in
+// http://comopt.ifi.uni-heidelberg.de/software/TSPLIB95/DOC.PS
+
+// EOF is tested separately because it is sometimes redefined
+
+namespace operations_research {
+
+typedef int64 (*TWOD_distance_function)(const Point, const Point);
+typedef int64 (*THREED_distance_function)(const Point, const Point);
+
+const int kTSPLIBDelimiter = -1;
+const char * kTSPLIBEndFileDelimiter = "EOF";
+
+#define TSPLIB_STATES \
+ ENUM_OR_STRING( NAME ), \
+ ENUM_OR_STRING( TYPE ), \
+ ENUM_OR_STRING( COMMENT ), \
+ ENUM_OR_STRING( DIMENSION ), \
+ ENUM_OR_STRING( CAPACITY ), \
+ ENUM_OR_STRING( EDGE_WEIGHT_TYPE ), \
+ ENUM_OR_STRING( EDGE_WEIGHT_FORMAT ), \
+ ENUM_OR_STRING( EDGE_DATA_FORMAT ), \
+ ENUM_OR_STRING( NODE_COORD_TYPE ), \
+ ENUM_OR_STRING( DISPLAY_DATA_TYPE ), \
+ ENUM_OR_STRING( NODE_COORD_SECTION ), \
+ ENUM_OR_STRING( DEPOT_SECTION ), \
+ ENUM_OR_STRING( DEMAND_SECTION ), \
+ ENUM_OR_STRING( EDGE_DATA_SECTION ), \
+ ENUM_OR_STRING( FIXED_EDGE_SECTION ), \
+ ENUM_OR_STRING( DISPLAY_DATA_SECTION ), \
+ ENUM_OR_STRING( TOUR_SECTION ), \
+ ENUM_OR_STRING( EDGE_WEIGHT_SECTION ), \
+ ENUM_OR_STRING( TSPLIB_STATES_COUNT ), \
+ ENUM_OR_STRING( TSPLIB_STATES_UNDEFINED )
+
+// TYPE
+#define TSPLIB_PROBLEM_TYPES \
+ ENUM_OR_STRING( TSP ), \
+ ENUM_OR_STRING( ATSP ), \
+ ENUM_OR_STRING( CVRP ), \
+ ENUM_OR_STRING( CCPP ), \
+ ENUM_OR_STRING( TOUR ), \
+ ENUM_OR_STRING( TSPLIB_PROBLEM_TYPES_COUNT ), \
+ ENUM_OR_STRING( TSPLIB_PROBLEM_TYPES_UNDEFINED )
+
+// EDGE_WEIGHT_TYPE
+#define TSPLIB_EDGE_WEIGHT_TYPES \
+ ENUM_OR_STRING( ATT ), \
+ ENUM_OR_STRING( CEIL_2D ), \
+ ENUM_OR_STRING( CEIL_3D ), \
+ ENUM_OR_STRING( EUC_2D ), \
+ ENUM_OR_STRING( EUC_3D ), \
+ ENUM_OR_STRING( EXPLICIT ), \
+ ENUM_OR_STRING( GEO ), \
+ ENUM_OR_STRING( GEOM ), \
+ ENUM_OR_STRING( GEO_MEEUS ), \
+ ENUM_OR_STRING( GEOM_MEEUS ), \
+ ENUM_OR_STRING( MAN_2D ), \
+ ENUM_OR_STRING( MAN_3D ), \
+ ENUM_OR_STRING( MAX_2D ), \
+ ENUM_OR_STRING( MAX_3D ), \
+ ENUM_OR_STRING( TSPLIB_EDGE_WEIGHT_TYPES_COUNT ), \
+ ENUM_OR_STRING( TSPLIB_EDGE_WEIGHT_TYPES_UNDEFINED )
+
+// EDGE_WEIGHT_FORMAT
+#define TSPLIB_EDGE_WEIGHT_FORMAT_TYPES \
+ ENUM_OR_STRING( FUNCTION ), \
+ ENUM_OR_STRING( FULL_MATRIX ), \
+ ENUM_OR_STRING( UPPER_ROW ), \
+ ENUM_OR_STRING( LOWER_ROW ), \
+ ENUM_OR_STRING( UPPER_DIAG_ROW ), \
+ ENUM_OR_STRING( LOWER_DIAG_ROW ), \
+ ENUM_OR_STRING( UPPER_COL ), \
+ ENUM_OR_STRING( LOWER_COL ), \
+ ENUM_OR_STRING( UPPER_DIAG_COL ), \
+ ENUM_OR_STRING( LOWER_DIAG_COL ), \
+ ENUM_OR_STRING( TSPLIB_EDGE_WEIGHT_FORMAT_TYPES_COUNT ), \
+ ENUM_OR_STRING( TSPLIB_EDGE_WEIGHT_FORMAT_TYPES_UNDEFINED )
+
+// EDGE_DATA_FORMAT
+#define TSPLIB_EDGE_DATA_FORMAT_TYPES \
+ ENUM_OR_STRING( EDGE_LIST ), \
+ ENUM_OR_STRING( ADJ_LIST ), \
+ ENUM_OR_STRING( TSPLIB_EDGE_DATA_FORMAT_TYPES_COUNT ), \
+ ENUM_OR_STRING( TSPLIB_EDGE_DATA_FORMAT_TYPES_UNDEFINED )
+
+// NODE_COORD_TYPE
+#define TSPLIB_NODE_COORD_TYPE_TYPES \
+ ENUM_OR_STRING( TWOD_COORDS ), \
+ ENUM_OR_STRING( THREED_COORDS ), \
+ ENUM_OR_STRING( NO_COORDS ), \
+ ENUM_OR_STRING( TSPLIB_NODE_COORD_TYPE_TYPES_COUNT ), \
+ ENUM_OR_STRING( TSPLIB_NODE_COORD_TYPE_TYPES_UNDEFINED )
+
+// DISPLAY_DATA_TYPE
+#define TSPLIB_DISPLAY_DATA_TYPE_TYPES \
+ ENUM_OR_STRING( COORD_DISPLAY ), \
+ ENUM_OR_STRING( TWOD_DISPLAY ), \
+ ENUM_OR_STRING( NO_DISPLAY ), \
+ ENUM_OR_STRING( TSPLIB_DISPLAY_DATA_TYPE_TYPES_COUNT ), \
+ ENUM_OR_STRING( TSPLIB_DISPLAY_DATA_TYPE_TYPES_UNDEFINED )
+
+
+// Enum
+#undef ENUM_OR_STRING
+#define ENUM_OR_STRING( x ) x
+
+enum TSPLIB_STATES_enum
+{
+ TSPLIB_STATES
+};
+
+enum TSPLIB_PROBLEM_TYPES_enum
+{
+ TSPLIB_PROBLEM_TYPES
+};
+
+enum TSPLIB_EDGE_WEIGHT_TYPES_enum
+{
+ TSPLIB_EDGE_WEIGHT_TYPES
+};
+
+enum TSPLIB_EDGE_WEIGHT_FORMAT_TYPES_enum
+{
+ TSPLIB_EDGE_WEIGHT_FORMAT_TYPES
+};
+
+enum TSPLIB_EDGE_DATA_FORMAT_TYPES_enum
+{
+ TSPLIB_EDGE_DATA_FORMAT_TYPES
+};
+
+enum TSPLIB_NODE_COORD_TYPE_TYPES_enum
+{
+ TSPLIB_NODE_COORD_TYPE_TYPES
+};
+
+enum TSPLIB_DISPLAY_DATA_TYPE_TYPES_enum
+{
+ TSPLIB_DISPLAY_DATA_TYPE_TYPES
+};
+
+
+// Strings
+#undef ENUM_OR_STRING
+#define ENUM_OR_STRING( x ) #x
+
+const char * TSPLIB_STATES_KEYWORDS[] =
+{
+ TSPLIB_STATES
+};
+
+const char * TSPLIB_PROBLEM_TYPES_KEYWORDS[] =
+{
+ TSPLIB_PROBLEM_TYPES
+};
+
+
+const char * TSPLIB_EDGE_WEIGHT_TYPES_KEYWORDS[] =
+{
+ TSPLIB_EDGE_WEIGHT_TYPES
+};
+
+
+const char * TSPLIB_EDGE_WEIGHT_FORMAT_TYPES_KEYWORDS[] =
+{
+ TSPLIB_EDGE_WEIGHT_FORMAT_TYPES
+};
+
+const char * TSPLIB_EDGE_DATA_FORMAT_TYPES_KEYWORDS[] =
+{
+ TSPLIB_EDGE_DATA_FORMAT_TYPES
+};
+
+const char * TSPLIB_NODE_COORD_TYPE_TYPES_KEYWORDS[] =
+{
+ TSPLIB_NODE_COORD_TYPE_TYPES
+};
+
+const char * TSPLIB_DISPLAY_DATA_TYPE_TYPES_KEYWORDS[] =
+{
+ TSPLIB_DISPLAY_DATA_TYPE_TYPES
+};
+
+
+struct TSPLIBDistanceFunctions {
+
+ typedef int64 (*TWOD_distance_function)(const Point, const Point);
+ typedef int64 (*THREED_distance_function)(const Point, const Point, const Point);
+
+ static constexpr double PI = 3.141594;
+ // Earth radius in km
+ static constexpr double RRR = 6378.388;
+
+ TSPLIBDistanceFunctions(const TSPLIB_NODE_COORD_TYPE_TYPES_enum dim , const TSPLIB_EDGE_WEIGHT_TYPES_enum type) {
+ switch (dim) {
+ case TWOD_COORDS: {
+ switch (type) {
+ case EUC_2D: {
+ TWOD_dist_fun_ = &TWOD_euc_2d_distance;
+ break;
+ }
+
+ case GEO:
+ case GEOM: {
+ TWOD_dist_fun_ = &TSPLIBDistanceFunctions::TWOD_geo_distance;
+ break;
+ }
+ case ATT: {
+ TWOD_dist_fun_ = &TSPLIBDistanceFunctions::TWOD_att_distance;
+ break;
+ }
+ }
+break;
+ } // case TWOD_COORDS:
+
+ case THREED_COORDS: {
+ break;
+ }
+
+ case NO_COORDS: {
+ break;
+ }
+
+ case TSPLIB_NODE_COORD_TYPE_TYPES_UNDEFINED: {
+ break;
+ }
+ }
+ }
+
+
+ int64 TWOD_distance(const Point x, const Point y) {
+ return TWOD_dist_fun_(x,y);
+ }
+
+
+// Rounds to the nearest int
+static int64 nint(double d)
+{
+ return std::floor(d+0.5);
+}
+
+// Convert longitude and latitude given in DDD.MM with DDD = degrees and MM = minutes
+// into longitude and latitude given in radians.
+static double convert_to_geo(double x) {
+ int64 deg = nint(x);
+
+ return PI * (deg + 5.0 * (x - deg) / 3.0 ) / 180.0;
+}
+
+
+// 2D functions
+
+static int64 TWOD_euc_2d_distance(const Point a, const Point b) {
+ double xd = a.x - b.x;
+ double yd = a.y - b.y;
+
+ return nint(std::sqrt(xd*xd + yd*yd));;
+
+}
+
+static int64 THREED_euc_3d_distance(const Point a, const Point b) {
+ double xd = a.x - b.x;
+ double yd = a.y - b.y;
+ double zd = a.z - b.z;
+
+ return nint(std::sqrt(xd*xd + yd*yd + zd*zd));;
+
+}
+
+static int64 TWOD_max_2d_distance(const Point a, const Point b) {
+ double xd = std::abs(a.x - b.x);
+ double yd = std::abs(a.y - b.y);
+
+ return std::max(nint(xd), nint(yd));
+}
+
+static int64 THREED_max_3d_distance(const Point a, const Point b) {
+ double xd = std::abs(a.x - b.x);
+ double yd = std::abs(a.y - b.y);
+ double zd = std::abs(a.z - b.z);
+
+ return std::max(std::max(nint(xd), nint(yd)), nint(zd));
+}
+
+static int64 TWOD_man_2d_distance(const Point a, const Point b) {
+ double xd = std::abs(a.x - b.x);
+ double yd = std::abs(a.y - b.y);
+
+ return nint(xd + yd);
+}
+
+static int64 THREED_man_3d_distance(const Point a, const Point b) {
+ double xd = std::abs(a.x - b.x);
+ double yd = std::abs(a.y - b.y);
+ double zd = std::abs(a.z - b.z);
+
+ return nint(xd + yd +zd);
+}
+
+static int64 TWOD_ceil_2d_distance(const Point a, const Point b) {
+ double xd = std::abs(a.x - b.x);
+ double yd = std::abs(a.y - b.y);
+
+ return std::ceil(xd + yd);
+}
+
+static int64 THREED_ceil_3d_distance(const Point a, const Point b) {
+ double xd = std::abs(a.x - b.x);
+ double yd = std::abs(a.y - b.y);
+ double zd = std::abs(a.z - b.z);
+
+ return std::ceil(xd + yd +zd);
+}
+
+static int64 TWOD_geo_distance(const Point a, const Point b) {
+ Point a_geo(convert_to_geo(a.x), convert_to_geo(a.y) );
+ Point b_geo(convert_to_geo(b.x), convert_to_geo(b.y) );
+
+ double q1 = std::cos(a_geo.y - b_geo.y);
+ double q2 = std::cos(a_geo.x - b_geo.x);
+ double q3 = std::cos(a_geo.x + b_geo.x);
+ return (int64) RRR * std::acos( 0.5 * ((1.0 + q1)*q2 - (1.0 - q1) * q3)) + 1.0;
+ }
+
+static int64 TWOD_att_distance(const Point a, const Point b) {
+ double xd = a.x - b.x;
+ double yd = a.y - b.y;
+
+ double rij = std::sqrt( (xd*xd + yd*yd) / 10.0);
+ int64 tij = nint(rij);
+
+ return (tij < rij)? tij + 1: tij;
+}
+TWOD_distance_function TWOD_dist_fun_;
+
+ // 3D functions
+THREED_distance_function THREED_dist_fun_;
+
+};
+
+void PrintFatalLog(const char * msg,const std::string & wrong_keyword, int line_number) {
+ LOG(FATAL) << "TSPLIB: " << msg << ": \"" << wrong_keyword << "\" on line " << line_number;
+}
+
+// Find the enum corresponding to a string
+// This only works if the strings and enums are ordered in the same way
+// and an "undefined enum" is placed at the end of the enum (hence the "index + 1").
+template
+E FindEnumKeyword(const char** list,const std::string word,const E end_index) {
+ int index = 0;
+ for (; index < end_index; ++index) {
+ if (!strcmp(word.c_str(),list[index])) {
+ return (E) index;
+ }
+ }
+ return (E) (index + 1);
+}
+
+// Find the enum corresponding to a string
+// This only works if the strings and enums are ordered in the same way
+// and an "undefined enum" is placed at the end of the enum (hence the "index + 1")
+// and a "count enum" gives the number of elements in the enum (XXX_UNDEFINED = XXX_COUNT + 1).
+// Print a LOG(FATAL) if no enum if found.
+template
+E FindOrDieEnumKeyword(const char** list, const std::string word, const E end_index, const char * err_msg, int line_number) {
+ E enum_element = FindEnumKeyword(list, word, end_index);
+ if (enum_element == end_index + 1) {
+ PrintFatalLog(err_msg, word, line_number);
+ }
+ return enum_element;
+}
+
+
+} // namespace operations_research
+
+#endif
\ No newline at end of file
diff --git a/documentation/tutorials/cplusplus/routing_common/tsplib_reader.h b/documentation/tutorials/cplusplus/routing_common/tsplib_reader.h
new file mode 100644
index 0000000000..cbafa9ed3b
--- /dev/null
+++ b/documentation/tutorials/cplusplus/routing_common/tsplib_reader.h
@@ -0,0 +1,618 @@
+// 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.
+//
+//
+// TSPLIBReader.
+//
+// Only valid for:
+// - TSP
+// - ATSP
+// - CVRP
+// - CCPP (this is an extension)
+
+#ifndef OR_TOOLS_TUTORIALS_CPLUSPLUS_TSPLIB_READER_H
+#define OR_TOOLS_TUTORIALS_CPLUSPLUS_TSPLIB_READER_H
+
+#include
+#include
+#include
+
+#include "base/integral_types.h"
+#include "base/filelinereader.h"
+#include "base/split.h"
+#include "base/strtoint.h"
+
+#include "routing_common/routing_common.h"
+#include "routing_common/routing_data.h"
+#include "routing_common/tsplib.h"
+
+namespace operations_research {
+ class TSPLIBReader : public RoutingData {
+ public:
+ typedef std::vector::iterator solution_iterator;
+ typedef std::vector::const_iterator const_solution_iterator;
+ explicit TSPLIBReader(const std::string & filename) :
+ RoutingData(0),
+ line_number_(0),
+ visualizable_(false),
+ two_dimension_(false),
+ symmetric_(false),
+ need_to_compute_distances_(false),
+ tsplib_state_unknown_(true),
+ tsplib_state_(TSPLIB_STATES_UNDEFINED),
+ name_(""),
+ type_(TSPLIB_PROBLEM_TYPES_UNDEFINED),
+ comment_(""),
+ capacity_(-1),
+ edge_weight_type_(TSPLIB_EDGE_WEIGHT_TYPES_UNDEFINED),
+ edge_weight_format_type_(TSPLIB_EDGE_WEIGHT_FORMAT_TYPES_UNDEFINED),
+ edge_data_format_type_(TSPLIB_EDGE_DATA_FORMAT_TYPES_UNDEFINED),
+ node_coord_type_(TWOD_COORDS), // If no coord type is given, we assume 2D.
+ display_data_type_(TSPLIB_DISPLAY_DATA_TYPE_TYPES_UNDEFINED)
+
+ {
+ LoadInstance(filename);
+ if (depots_.size() == 0) {
+ depots_.push_back(RoutingModel::kFirstNode);
+ }
+ SetRoutingDataInstanciated();
+ }
+ TSPLIB_PROBLEM_TYPES_enum TSPLIBType () const {
+ return type_;
+ }
+ RoutingModel::NodeIndex Depot() const {
+ return depots_[0];
+ }
+
+std::vector Depots() const {
+ return depots_;
+}
+
+int32 Capacity() const {
+ return capacity_;
+}
+
+int64 Demand(RoutingModel::NodeIndex i) const {
+ return demands_[i.value()];
+}
+ bool HasDimensionTwo() const {
+ return two_dimension_;
+ }
+ TSPLIB_NODE_COORD_TYPE_TYPES_enum NodeCoordinateType() const {
+ return node_coord_type_;
+ }
+
+ TSPLIB_DISPLAY_DATA_TYPE_TYPES_enum DisplayDataType() const {
+ return display_data_type_;
+ }
+
+ TSPLIB_EDGE_WEIGHT_TYPES_enum EdgeWeightType() const {
+ return edge_weight_type_;
+ }
+
+ TSPLIB_EDGE_WEIGHT_FORMAT_TYPES_enum EdgeWeightTypeFormat() const {
+ return edge_weight_format_type_;
+ }
+
+ solution_iterator solution_begin() {
+ return tsp_sol_.begin();
+ }
+ const_solution_iterator solution_begin() const {
+ return tsp_sol_.begin();
+ }
+ solution_iterator solution_end() {
+ return tsp_sol_.end();
+ }
+ const_solution_iterator solution_end() const {
+ return tsp_sol_.end();
+ }
+ protected:
+ void LoadInstance(const std::string& filename);
+ // Helper function
+ int64& SetMatrix(int i, int j) {
+ return distances_.Cost(RoutingModel::NodeIndex(i), RoutingModel::NodeIndex(j));
+ }
+
+ private:
+ void ProcessNewLine(char* const line);
+
+ std::vector depots_;
+ int line_number_;
+ bool visualizable_;
+ bool two_dimension_;
+ bool symmetric_;
+ bool need_to_compute_distances_;
+
+ TSPLIB_STATES_enum tsplib_state_;
+ bool tsplib_state_unknown_;
+
+ TSPLIB_PROBLEM_TYPES_enum type_;
+ std::string name_;
+ std::string comment_;
+ int32 capacity_;
+ TSPLIB_EDGE_WEIGHT_TYPES_enum edge_weight_type_;
+ TSPLIB_EDGE_WEIGHT_FORMAT_TYPES_enum edge_weight_format_type_;
+ TSPLIB_EDGE_DATA_FORMAT_TYPES_enum edge_data_format_type_;
+ TSPLIB_NODE_COORD_TYPE_TYPES_enum node_coord_type_;
+ TSPLIB_DISPLAY_DATA_TYPE_TYPES_enum display_data_type_;
+
+ TWOD_distance_function TWOD_dist_fun_;
+ THREED_distance_function THREED_dist_fun_;
+
+ std::vector tsp_sol_;
+ std::vector demands_;
+ };
+
+ void TSPLIBReader::LoadInstance(const std::string& filename)
+ {
+
+ FileLineReader reader(filename.c_str());
+ reader.set_line_callback(NewPermanentCallback(
+ this,
+ &TSPLIBReader::ProcessNewLine));
+ reader.Reload();
+ if (!reader.loaded_successfully()) {
+ LOG(FATAL) << "Could not open TSPLIB instance file: " << filename;
+ }
+ }
+
+
+ void TSPLIBReader::ProcessNewLine(char*const line) {
+ ++line_number_;
+ VLOG(2) << "Line " << line_number_ << ": " << line;
+ // Must always be -1 outside a section
+ static int32 nodes_nbr = -1;
+ static bool read_matrix_done = false;
+
+ static const char kWordDelimiters[] = " :";
+ std::vector words;
+ words = strings::Split(line, kWordDelimiters, strings::SkipEmpty());
+
+ // Empty lines
+ if (words.size() == 0) {
+ return;
+ }
+
+ // FIND TSPLIB KEYWORD
+ if (tsplib_state_unknown_) {
+ bool keyword_found = false;
+ //read_matrix_done = false;
+
+ tsplib_state_ = FindEnumKeyword(TSPLIB_STATES_KEYWORDS, words[0], TSPLIB_STATES_COUNT);
+ if (tsplib_state_ != TSPLIB_STATES_UNDEFINED) {
+ keyword_found = true;
+ }
+
+ // separate test because "EOF" is sometimes redefined
+ if (words[0] == kTSPLIBEndFileDelimiter) {
+ return;
+ }
+
+ if (!keyword_found) {
+ PrintFatalLog("Unknown keyword", words[0], line_number_);
+ }
+
+ tsplib_state_unknown_ = false;
+ }
+
+ // SWITCH FOLLOWING TSPLIB KEYWORD
+ switch (tsplib_state_) {
+ case NAME: {
+ name_ = words[1];
+ tsplib_state_unknown_ = true;
+ break;
+ }
+ case TYPE: {
+ type_ = FindOrDieEnumKeyword(TSPLIB_PROBLEM_TYPES_KEYWORDS, words[1], TSPLIB_PROBLEM_TYPES_COUNT, "Unknown problem type", line_number_);
+ tsplib_state_unknown_ = true;
+ break;
+ }
+ case COMMENT: {
+ if (words.size() > 1) {
+ for (int index = 1; index < words.size(); ++index) {
+ comment_ = StrCat(comment_, words[index] + " ");
+ }
+ }
+ tsplib_state_unknown_ = true;
+ break;
+ }
+ case DIMENSION: {
+ int32 size = atoi32(words[1]);
+ CreateRoutingData(size);
+ tsplib_state_unknown_ = true;
+ break;
+ }
+ case CAPACITY: {
+ capacity_ = atoi32(words[1]);
+ tsplib_state_unknown_ = true;
+ break;
+ }
+ case DEPOT_SECTION: {
+ if (nodes_nbr == -1) {
+ // titel
+ ++nodes_nbr;
+ break;
+ }
+ if (atoi32(words[0]) == -1) {
+ nodes_nbr = -1;
+ tsplib_state_unknown_ = true;
+ break;
+ }
+ depots_.push_back(RoutingModel::NodeIndex(atoi32(words[1]) - 1));
+ ++nodes_nbr;
+ break;
+ }
+ case DEMAND_SECTION: {
+ if (nodes_nbr == -1) {
+ // titel
+ demands_.resize(Size());
+ ++nodes_nbr;
+ break;
+ }
+
+ if (nodes_nbr == Size() - 1) {
+ tsplib_state_unknown_ = true;
+ nodes_nbr = -1;
+ break;
+ }
+ CHECK_EQ(words.size(), 2) << "Demand section should only contain node_id and demand on line " << line_number_;
+ CHECK_LE(atoi32(words[0]), Size()) << "Node with node_id bigger than size of instance on line " << line_number_;
+ demands_[atoi32(words[0]) - 1] = atoi32(words[1]);
+ ++nodes_nbr;
+ break;
+ }
+ case TOUR_SECTION: {
+ if (nodes_nbr == -1) {
+ // titel
+ tsp_sol_.resize(Size());
+ ++nodes_nbr;
+ break;
+ }
+ if (nodes_nbr == Size()) {
+ CHECK_EQ(atoi32(words[0]), -1) << "Tour is supposed to end with -1.";
+ tsplib_state_unknown_ = true;
+ break;
+ }
+ RoutingModel::NodeIndex node(atoi32(words[0]) - 1);
+ tsp_sol_[nodes_nbr] = node;
+ ++nodes_nbr;
+ break;
+ }
+ case EDGE_WEIGHT_TYPE: {
+ edge_weight_type_ = FindOrDieEnumKeyword(TSPLIB_EDGE_WEIGHT_TYPES_KEYWORDS,
+ words[1],
+ TSPLIB_EDGE_WEIGHT_TYPES_COUNT,
+ "Unknown edge weight type",
+ line_number_);
+ // Do we need to compute the distances?
+ switch (edge_weight_type_) {
+ case EXPLICIT: {
+ need_to_compute_distances_ = false;
+ break;
+ }
+ case EUC_2D: {
+ need_to_compute_distances_ = true;
+ two_dimension_ = true;
+ symmetric_ = true;
+ visualizable_ = true;
+ TWOD_dist_fun_ = &TSPLIBDistanceFunctions::TWOD_euc_2d_distance;
+ break;
+ }
+ case EUC_3D: {
+ need_to_compute_distances_ = true;
+ two_dimension_ = false;
+ symmetric_ = true;
+ visualizable_ = true;
+ THREED_dist_fun_ = &TSPLIBDistanceFunctions::THREED_euc_3d_distance;
+ break;
+ }
+ case MAX_2D: {
+ need_to_compute_distances_ = true;
+ two_dimension_ = true;
+ symmetric_ = true;
+ visualizable_ = true;
+ TWOD_dist_fun_ = &TSPLIBDistanceFunctions::TWOD_max_2d_distance;
+ break;
+ }
+ case MAX_3D: {
+ need_to_compute_distances_ = true;
+ two_dimension_ = false;
+ symmetric_ = true;
+ visualizable_ = true;
+ THREED_dist_fun_ = &TSPLIBDistanceFunctions::THREED_max_3d_distance;
+ break;
+ }
+ case MAN_2D: {
+ need_to_compute_distances_ = true;
+ two_dimension_ = true;
+ symmetric_ = true;
+ visualizable_ = true;
+ TWOD_dist_fun_ = &TSPLIBDistanceFunctions::TWOD_man_2d_distance;
+ break;
+ }
+ case MAN_3D: {
+ need_to_compute_distances_ = true;
+ two_dimension_ = false;
+ symmetric_ = true;
+ visualizable_ = true;
+ THREED_dist_fun_ = &TSPLIBDistanceFunctions::THREED_man_3d_distance;
+ break;
+ }
+ case CEIL_2D: {
+ need_to_compute_distances_ = true;
+ two_dimension_ = true;
+ symmetric_ = true;
+ visualizable_ = true;
+ TWOD_dist_fun_ = &TSPLIBDistanceFunctions::TWOD_ceil_2d_distance;
+ break;
+ }
+ case CEIL_3D: {
+ need_to_compute_distances_ = true;
+ two_dimension_ = false;
+ symmetric_ = true;
+ visualizable_ = true;
+ THREED_dist_fun_ = &TSPLIBDistanceFunctions::THREED_ceil_3d_distance;
+ break;
+ }
+ case GEO:
+ case GEOM: {
+ need_to_compute_distances_ = true;
+ two_dimension_ = true;
+ symmetric_ = true;
+ visualizable_ = true;
+ TWOD_dist_fun_ = &TSPLIBDistanceFunctions::TWOD_geo_distance;
+ break;
+ }
+ case ATT: {
+ need_to_compute_distances_ = true;
+ two_dimension_ = true;
+ symmetric_ = true;
+ visualizable_ = true;
+ TWOD_dist_fun_ = &TSPLIBDistanceFunctions::TWOD_att_distance;
+ break;
+ }
+ } // switch (edge_weight_type_)
+ tsplib_state_unknown_ = true;
+ break;
+ }
+ case EDGE_WEIGHT_FORMAT: {
+ edge_weight_format_type_ = FindOrDieEnumKeyword(TSPLIB_EDGE_WEIGHT_FORMAT_TYPES_KEYWORDS,
+ words[1],
+ TSPLIB_EDGE_WEIGHT_FORMAT_TYPES_COUNT,
+ "Unknown edge weight format type",
+ line_number_);
+ tsplib_state_unknown_ = true;
+ break;
+ }
+ case EDGE_DATA_FORMAT: {
+ edge_data_format_type_ = FindOrDieEnumKeyword(TSPLIB_EDGE_DATA_FORMAT_TYPES_KEYWORDS,
+ words[1],
+ TSPLIB_EDGE_DATA_FORMAT_TYPES_COUNT,
+ "Unknown edge data format type",
+ line_number_);
+ tsplib_state_unknown_ = true;
+ break;
+ }
+ case NODE_COORD_TYPE: {
+ node_coord_type_ = FindOrDieEnumKeyword(TSPLIB_NODE_COORD_TYPE_TYPES_KEYWORDS,
+ words[1],
+ TSPLIB_NODE_COORD_TYPE_TYPES_COUNT,
+ "Unknown node coord format type",
+ line_number_);
+ tsplib_state_unknown_ = true;
+ break;
+ }
+ case DISPLAY_DATA_TYPE: {
+ display_data_type_ = FindOrDieEnumKeyword(TSPLIB_DISPLAY_DATA_TYPE_TYPES_KEYWORDS,
+ words[1],
+ TSPLIB_DISPLAY_DATA_TYPE_TYPES_COUNT,
+ "Unknown display data format type",
+ line_number_);
+ switch (display_data_type_) {
+ case NO_DISPLAY:
+ break;
+ case COORD_DISPLAY:
+ case TWOD_DISPLAY:
+ visualizable_ = true;
+ break;
+ }
+ tsplib_state_unknown_ = true;
+ break;
+ }
+ case NODE_COORD_SECTION: {
+ if (nodes_nbr == -1) {
+ ++nodes_nbr;
+ visualizable_ = true;
+ break;
+ }
+ ++nodes_nbr;
+ switch (node_coord_type_) {
+ case TWOD_COORDS: {
+ CHECK_EQ(words.size(), 3) << "Node coord data not conform on line " << line_number_;
+ CHECK_LE(atoi32(words[0].c_str()), size_) << "Unknown node number " << atoi32(words[0].c_str()) << " on line " << line_number_;
+ coordinates_[atoi32(words[0].c_str()) -1] = Point(atof(words[1].c_str()), atof(words[2].c_str()));
+ break;
+ }
+ case THREED_COORDS: {
+ CHECK_EQ(words.size(), 4) << "Node coord data not conform on line " << line_number_;
+ CHECK_LE(atoi32(words[0].c_str()), size_) << "Unknown node number " << atoi32(words[0].c_str()) << " on line " << line_number_;
+ coordinates_[atoi32(words[0].c_str()) -1] = Point(atof(words[1].c_str()), atof(words[2].c_str()), atof(words[3].c_str()));
+ break;
+ }
+ case NO_COORDS: {
+ LOG(FATAL) << "Coordinate is non existent but there is a node coordinate section???";
+ break;
+ }
+ default:
+ LOG(FATAL) << "Coordinate type is not defined.";
+ }
+ if (nodes_nbr == size_) {
+ SetHasCoordinates();
+ // Compute distance if needed
+ TSPLIBDistanceFunctions tsplib_dist_function(node_coord_type_, edge_weight_type_);
+ int64 dist = 0;
+ if (need_to_compute_distances_) {
+ LG << "Computing distance matrix...";
+ // TWO DIMENSION
+ if (two_dimension_) {
+ // SYMMETRIC
+ if (symmetric_) {
+ for (int i = 0; i < size_; ++i) {
+ for (int j = i + 1; j < size_; ++j ) {
+ dist = tsplib_dist_function.TWOD_distance(coordinates_[i], coordinates_[j]);
+ SetMatrix(i,j) = dist;
+ SetMatrix(j,i) = dist;
+ }
+ }
+ for (int i = 0; i < size_; ++i) {
+ SetMatrix(i,i) = 0LL;
+ }
+ // NOT SYMMETRIC
+ } else {
+ for (int i = 0; i < size_; ++i) {
+ for (int j = 0; j < size_; ++j ) {
+ if (i == j) {
+ SetMatrix(i,j) = 0LL;
+ } else {
+ SetMatrix(i,j) = dist;
+ }
+ }
+ }
+ }
+ // THREE DIMENSION
+ } else {
+
+ }
+ LG << "Computing distance matrix... Done!";
+ } // if (tsplib_dist_function.NeedToComputeDistances())
+ tsplib_state_unknown_ = true;
+ nodes_nbr = -1;
+ }
+ break;
+ } // case NODE_COORD_SECTION:
+ case DISPLAY_DATA_SECTION: {
+ if (nodes_nbr == -1) {
+ ++nodes_nbr;
+ break;
+ }
+ if (display_data_type_ == TWOD_DISPLAY) {
+ CHECK_EQ(words.size(), 3) << "Display data not conform on line " << line_number_;
+ CHECK_LE(atoi32(words[0].c_str()), size_) << "Unknown node number " << atoi32(words[0].c_str()) << " on line " << line_number_;
+ display_coords_[atoi32(words[0].c_str()) -1] = Point(atof(words[1].c_str()), atof(words[2].c_str()));
+ ++nodes_nbr;
+ if (nodes_nbr == size_) {
+ SetHasDisplayCoordinates();
+ tsplib_state_unknown_ = true;
+ nodes_nbr = -1;
+ }
+ } else {
+ tsplib_state_unknown_ = true;
+ nodes_nbr = -1;
+ }
+ break;
+ }
+ case EDGE_DATA_SECTION: {
+ if (words.size() == 1 && words[0] == "-1") {
+ // complete matrix
+ //TO DO
+ read_matrix_done = true;
+ tsplib_state_unknown_ = true;
+ break;
+ }
+ switch(edge_data_format_type_) {
+ case EDGE_LIST: {
+ CHECK_EQ(words.size(), 2) << "Edge not well defined on line " << line_number_;
+ break;
+ }
+ case ADJ_LIST: {
+ break;
+ }
+ }
+ }
+ case EDGE_WEIGHT_SECTION: {
+ if (nodes_nbr == -1) {
+ ++nodes_nbr;
+ read_matrix_done = false;
+ break;
+ }
+ switch (edge_weight_format_type_) {
+ case FULL_MATRIX: {
+ CHECK_EQ(words.size(),size_) << "Matrix not full on line " << line_number_;
+ for (int index = 0; index < size_; ++index) {
+ int64 dist = atoi64(words[index].c_str());
+ SetMatrix(nodes_nbr, index) = dist;
+ }
+ if (nodes_nbr == size_ - 1) {
+ read_matrix_done = true;
+ }
+ break;
+ }
+ case UPPER_ROW: {
+ CHECK_EQ(words.size(), size_ - nodes_nbr - 1) << " Wrong number of tokens on line " << line_number_;
+ SetMatrix(nodes_nbr, nodes_nbr) = 0LL;
+ for (int index = 0; index < size_ - nodes_nbr - 1; ++index) {
+ int64 dist = atoi64(words[index].c_str());
+ SetMatrix(nodes_nbr, index + nodes_nbr + 1) = dist;
+ SetMatrix(index + nodes_nbr + 1, nodes_nbr) = dist;
+ }
+ if (nodes_nbr == size_ - 2) {
+ read_matrix_done = true;
+ }
+ break;
+ }
+ case UPPER_DIAG_ROW: { // BUGGY?
+ CHECK_EQ(words.size(), size_ - nodes_nbr - 1);
+ for (int index = 0; index < size_ - nodes_nbr ; ++index) {
+ int64 dist = atoi64(words[index].c_str());
+ std::cout << dist << " ";
+ SetMatrix(nodes_nbr, index + nodes_nbr) = dist;
+ SetMatrix(index + nodes_nbr , nodes_nbr) = dist;
+ }
+ std::cout << std::endl;
+ if (nodes_nbr == size_ - 2) {
+ read_matrix_done = true;
+ }
+ break;
+ }
+ case LOWER_ROW: { // TO BE CHECKED
+ CHECK_EQ(words.size(), nodes_nbr + 1);
+ SetMatrix(nodes_nbr, nodes_nbr) = 0LL;
+ for (int index = 0; index < nodes_nbr + 1; ++index) {
+ int64 dist = atoi64(words[index].c_str());
+ std::cout << dist << " ";
+ SetMatrix(nodes_nbr, index) = dist;
+ SetMatrix(index , nodes_nbr) = dist;
+ }
+ std::cout << std::endl;
+ if (nodes_nbr == size_ - 2) {
+ read_matrix_done = true;
+ break;
+ }
+ break;
+ }
+ } // switch (edge_weight_format_type_)
+
+ if (read_matrix_done) {
+ tsplib_state_unknown_ = true;
+ nodes_nbr = -1;
+ break;
+ }
+ ++nodes_nbr;
+ } // case EDGE_WEIGHT_SECTION:
+ } // switch
+ } // ProcessNewLine()
+
+} // namespace operations_research
+
+
+#endif // OR_TOOLS_TUTORIALS_CPLUSPLUS_TSPLIB_READER_H