Samchon Framework for CPP  1.0.0
samchon::example::tsp Namespace Reference

Traveling Salesman Problem Solver. More...

Classes

struct  GAParameters
 Parameters for Genetic-Algorithm. More...
 
class  GeometryPoint
 A geometry coordinates (point) More...
 
class  Scheduler
 A scheduler. More...
 
class  Travel
 Represent a travel containning Point(s) More...
 

Detailed Description

Traveling Salesman Problem Solver.

Module tsp deducts an optimal traveling scheduel by genetic algorithm.

The tsp module is built for providing guidance of using entity and genetic algorithm module.

example_tsp.png

Example Sources

Scheduler.hpp
1 #pragma once
2 #include <samchon/protocol/Entity.hpp>
3 #include <samchon/example/tsp/Travel.hpp>
4 
5 #include <samchon/library/GeneticAlgorithm.hpp>
6 
7 #include <iostream>
8 #include <Windows.h>
9 
10 namespace samchon
11 {
12 namespace example
13 {
14 namespace tsp
15 {
16  using namespace std;
17 
18  using namespace library;
19  using namespace protocol;
20 
31  struct GAParameters
32  {
33  double mutationRate;
34  size_t tournament;
35 
36  size_t population;
37  size_t generation;
38  };
39 
46  class Scheduler
47  : public Entity
48  {
49  private:
50  typedef Entity super;
51 
52  protected:
56  shared_ptr<Travel> travel;
57 
61  struct GAParameters gaParameters;
62 
63  public:
64  /* -----------------------------------------------------------
65  CONSTRUCTORS
66  ----------------------------------------------------------- */
70  Scheduler()
71  : super()
72  {
73  this->travel = make_shared<Travel>();
74  this->gaParameters = {.03, 50, 100, 300};
75  };
76 
80  Scheduler(shared_ptr<Travel> travel, const struct GAParameters &gaParameteres)
81  : super()
82  {
83  this->travel = travel;
84  this->gaParameters = gaParameteres;
85  };
86 
87  virtual ~Scheduler() = default;
88 
89  virtual void construct(shared_ptr<XML> xml) override
90  {
91  super::construct(xml);
92  gaParameters.mutationRate = xml->getProperty<double>("mutationRate");
93  gaParameters.tournament = xml->getProperty<size_t>("tournament");
94  gaParameters.population = xml->getProperty<size_t>("population");
95  gaParameters.generation = xml->getProperty<size_t>("generation");
96 
97  travel->construct(xml->get(travel->TAG())->at(0));
98  };
99 
100  /* -----------------------------------------------------------
101  CALCULATORS
102  ----------------------------------------------------------- */
108  auto optimize() -> shared_ptr<Travel>
109  {
110  GeneticAlgorithm<Travel> geneticAlgorithm
111  (
112  true,
113  gaParameters.mutationRate,
114  gaParameters.tournament
115  );
116 
117  travel =
118  geneticAlgorithm.evolveGeneArray
119  (
120  travel,
121  gaParameters.population,
122  gaParameters.generation
123  );
124 
125  return travel;
126  };
127 
128  auto calcDistance() const -> double
129  {
130  return travel->calcDistance();
131  };
132 
133  /* -----------------------------------------------------------
134  EXPORTER
135  ----------------------------------------------------------- */
136  virtual auto TAG() const -> string override
137  {
138  return "scheduler";
139  };
140 
141  virtual auto toXML() const -> shared_ptr<XML> override
142  {
143  shared_ptr<XML> &xml = super::toXML();
144  xml->setProperty("mutationRate", gaParameters.mutationRate);
145  xml->setProperty("tournament", gaParameters.tournament);
146  xml->setProperty("population", gaParameters.population);
147  xml->setProperty("generation", gaParameters.generation);
148 
149  xml->push_back(travel->toXML());
150  return xml;
151  };
152 
153  auto toString() const -> string
154  {
155  return travel->toString();
156  };
157 
158  /* -----------------------------------------------------------
159  MAIN
160  ----------------------------------------------------------- */
161  static void main()
162  {
163  shared_ptr<Travel> travel = make_shared<Travel>();
164  for(int i = 0; i < 30; i++)
165  travel->emplace_back(new GeometryPoint(i + 1));
166 
167  // OPTIMIZING
168  struct GAParameters gaParameters = {.03, 30, 400, 400};
169 
170  Scheduler scheduler(travel, gaParameters);
171  travel = scheduler.optimize();
172 
173  // PRINTING
174  string &str = travel->toString();
175 
176  toClipboard(str);
177  cout << str << endl;
178  };
179 
180  private:
181  static void toClipboard(const string &str)
182  {
183  #if defined(_WINDOWS) || defined(_WIN32) || defined(_WIN64)
184  OpenClipboard(0);
185  EmptyClipboard();
186  HGLOBAL hg = GlobalAlloc(GMEM_MOVEABLE, str.size());
187 
188  if (!hg)
189  {
190  CloseClipboard();
191  return;
192  }
193  memcpy(GlobalLock(hg), str.c_str(), str.size());
194 
195  GlobalUnlock(hg);
196  SetClipboardData(CF_TEXT, hg);
197  CloseClipboard();
198  GlobalFree(hg);
199  #endif
200  };
201  };
202 };
203 };
204 };
Definition: RWMutex.hpp:4
Top level namespace of products built from samchon.
Definition: ByteArray.hpp:7
Travel.hpp
1 #pragma once
2 #include <samchon/protocol/SharedEntityArray.hpp>
3 #include <samchon/example/tsp/GeometryPoint.hpp>
4 
5 namespace samchon
6 {
7 namespace example
8 {
9 namespace tsp
10 {
11  using namespace std;
12 
13  using namespace library;
14  using namespace protocol;
15 
27  class Travel
28  : public SharedEntityArray<GeometryPoint>
29  {
30  private:
31  typedef SharedEntityArray<GeometryPoint> super;
32 
33  protected:
40  double distance;
41 
42  public:
43  /* -----------------------------------------------------------
44  CONSTRUCTORS
45  ----------------------------------------------------------- */
49  Travel()
50  : super()
51  {
52  distance = INT_MIN;
53  };
54 
63  Travel(const Travel &travel)
64  : super(travel)
65  {
66  distance = INT_MIN;
67  };
68 
72  Travel(Travel &&travel)
73  : super(move(travel))
74  {
75  distance = travel.distance;
76  };
77 
78  virtual ~Travel() = default;
79 
80  virtual void construct(shared_ptr<XML> xml) override
81  {
82  super::construct(xml);
83 
84  if (xml->hasProperty("distance") == true)
85  distance = xml->getProperty<double>("distance");
86  else
87  distance = INT_MIN;
88  };
89 
90  protected:
91  virtual auto createChild(shared_ptr<XML>) -> GeometryPoint*
92  {
93  return new GeometryPoint();
94  };
95 
96  /* -----------------------------------------------------------
97  CALCULATORS
98  ----------------------------------------------------------- */
99  public:
103  auto calcDistance() const -> double
104  {
105  if(this->distance != INT_MIN)
106  return this->distance;
107 
108  double distance = 0.0;
109  for(size_t i = 1; i < size(); i++)
110  distance += at(i-1)->calcDistance(*at(i));
111 
112  ((Travel*)this)->distance = distance;
113  return distance;
114  };
115 
116  public:
124  auto operator<(const Travel &travel) const -> bool
125  {
126  return this->calcDistance() < travel.calcDistance();
127  };
128 
129  /* -----------------------------------------------------------
130  EXPORTER
131  ----------------------------------------------------------- */
132  virtual auto TAG() const -> string override
133  {
134  return "travel";
135  };
136  virtual auto CHILD_TAG() const -> string override
137  {
138  return "point";
139  };
140 
141  virtual auto toXML() const -> shared_ptr<XML> override
142  {
143  shared_ptr<XML> &xml = super::toXML();
144  if (distance != INT_MIN)
145  xml->setProperty("distance", distance);
146 
147  return xml;
148  };
149 
162  auto toString() const -> string
163  {
164  string str =
165  "Distance: " + StringUtil::numberFormat(calcDistance()) + " km\n" +
166  "uid longitude latitude\n";
167 
168  for(size_t i = 0; i < size(); i++)
169  str += at(i)->toString() + "\n";
170 
171  return str;
172  };
173  };
174 };
175 };
176 };
Definition: RWMutex.hpp:4
static auto numberFormat(double val, int precision=2) -> std::string
Definition: StringUtil.cpp:83
EntityGroup< std::vector< std::shared_ptr< _Ty >>, _Ty, std::shared_ptr< _Ty > > SharedEntityArray
An EntityGroup with vector container and children capsuled in shared pointers.
Top level namespace of products built from samchon.
Definition: ByteArray.hpp:7
GeometryPoint.hpp
1 #pragma once
2 #include <samchon/protocol/Entity.hpp>
3 
4 #include <random>
5 #include <cmath>
6 #include <samchon/library/Math.hpp>
7 #include <samchon/library/StringUtil.hpp>
8 #include <samchon/library/XML.hpp>
9 
10 namespace samchon
11 {
12 namespace example
13 {
14 namespace tsp
15 {
16  using namespace std;
17 
18  using namespace library;
19  using namespace protocol;
20 
30  class GeometryPoint
31  : public Entity
32  {
33  private:
34  typedef Entity super;
35 
36  protected:
40  int uid;
41 
45  double longitude;
46 
50  double latitude;
51 
52  public:
53  /* -----------------------------------------------------------
54  CONSTRUCTORS
55  ----------------------------------------------------------- */
59  GeometryPoint()
60  : super()
61  {
62  };
63 
71  GeometryPoint(int uid)
72  : super()
73  {
74  this->uid = uid;
75 
76  this->longitude = Math::random() * 180.0;
77  this->latitude = Math::random() * 180 - 90.0;
78  };
79 
86  GeometryPoint(int uid, double longitude, double latitude)
87  : super()
88  {
89  this->uid = uid;
90  this->longitude = longitude;
91  this->latitude = latitude;
92  };
93 
94  virtual ~GeometryPoint() = default;
95 
96  virtual void construct(shared_ptr<XML> xml) override
97  {
98  uid = xml->getProperty<int>("uid");
99  longitude = xml->getProperty<double>("longitude");
100  latitude = xml->getProperty<double>("latitude");
101  };
102 
103  /* -----------------------------------------------------------
104  GETTERS
105  ----------------------------------------------------------- */
106  virtual auto key() const -> string override
107  {
108  return to_string(uid);
109  };
110 
117  auto calcDistance(const GeometryPoint &point) const -> double
118  {
119  if (longitude == point.longitude && latitude == point.latitude)
120  return 0.0;
121 
122  double latitude_radian1 = Math::degree_to_radian(this->latitude);
123  double latitude_radian2 = Math::degree_to_radian(point.latitude);
124  double theta = this->longitude - point.longitude;
125 
126  double val =
127  sin(latitude_radian1) * sin(latitude_radian2)
128  + cos(latitude_radian1) * cos(latitude_radian2) * cos(Math::degree_to_radian(theta));
129 
130  val = acos(val);
131  val = Math::radian_to_degree(val);
132  val = val * 60 * 1.1515;
133  val = val * 1.609344;
134 
135  return val;
136  };
137 
138  /* -----------------------------------------------------------
139  EXPORTER
140  ----------------------------------------------------------- */
141  virtual auto TAG() const -> string
142  {
143  return "point";
144  };
145 
146  auto toXML() const -> shared_ptr<XML> override
147  {
148  shared_ptr<XML> &xml = super::toXML();
149  xml->setProperty("uid", uid);
150  xml->setProperty("longitude", longitude);
151  xml->setProperty("latitude", latitude);
152 
153  return xml;
154  };
155 
164  auto toString() const -> string
165  {
167  (
168  "{1}\t{2}\t{3}",
169  uid, longitude, latitude
170  );
171  };
172  };
173 };
174 };
175 };
static auto random() -> double
Get a random value.
Definition: Math.cpp:38
Definition: RWMutex.hpp:4
static auto substitute(const std::string &format, const T &val, const _Args &...args) -> std::string
Substitutes "{n}" tokens within the specified string with the respective arguments passed in...
Definition: StringUtil.hpp:55
static auto degree_to_radian(double) -> double
Convert degree to radian.
Definition: Math.cpp:26
static auto radian_to_degree(double) -> double
Convert radian to degree.
Definition: Math.cpp:30
Top level namespace of products built from samchon.
Definition: ByteArray.hpp:7

Result of the example

example_tsp_result.png
See also
protocol::Entity
library::GeneticAlgorithm
Author
Jeongho Nam http://samchon.org