-
Notifications
You must be signed in to change notification settings - Fork 4
/
problem.hpp
149 lines (108 loc) · 3.4 KB
/
problem.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#ifndef PROBLEM_HPP
#define PROBLEM_HPP
#include "node.hpp"
namespace AI
{
using std::shared_ptr;
using std::make_shared;
using std::cout;
using std::endl;
template <typename T, typename Impl>
struct Problem
{
using state_type = T;
using node_type = Node<state_type>;
using node_ptr = typename node_type::node_ptr;
using leafs_list = typename node_type::leafs_list;
Problem(node_ptr head)
: mTree(move(head))
{ }
Problem(T head)
: mTree(make_shared<node_type>(head))
{ }
inline node_type & getRoot() const
{ return *mTree; }
inline node_ptr initial() const
{ return mTree; }
bool testGoal(const node_ptr &node) const
{
T && val = node->getState();
getImpl().watch(node);
return getImpl().isGoal(val);
}
leafs_list successors(const node_ptr &state) const
{
leafs_list leafs;
const auto edgeBoarder = state->edges();
for(auto itr = edgeBoarder.first; itr != edgeBoarder.second; ++itr)
{
const node_ptr &node = itr->first;
const long &cost = itr->second;
leafs.push_back(makeNode(node, state, getImpl().F(node, cost, state->cost())));
}
return leafs;
}
void watch(const node_ptr &node) const
{
cout << "Visited node \""
<< node->getState()
<< "\" with cost of "
<< node->cost()
<< " and depth of "
<< node->depth()
<< endl;
}
long F(const node_ptr &n, const long &gn, const long &pcost) const
{ return gn; }
private:
const Impl &getImpl() const
{ return *static_cast<const Impl*>(this); }
const node_ptr mTree;
};
namespace Private
{
template<typename T, typename G >
struct ProblemMaker : public Problem<T, ProblemMaker<T,G>>
{
using daddy_type = Problem<T, ProblemMaker<T,G>>;
using node_ptr = typename daddy_type::node_ptr;
ProblemMaker(T root, T goal, const G &gen )
: daddy_type(forward<T>(root)), mGoal(makeNode<T>(forward<T>(goal))), mGenerator(gen)
{ }
ProblemMaker(const node_ptr &node, T goal, const G &gen )
: daddy_type(node), mGoal(makeNode<T>(forward<T>(goal))), mGenerator(gen)
{ }
ProblemMaker(node_ptr node, node_ptr goal, const G &gen )
: daddy_type(node), mGoal(goal), mGenerator(gen)
{ }
bool isGoal (const T & value) const
{ return value == mGoal->getState(); }
typename Node<T>::leafs_list
successors(const node_ptr &state) const
{ return mGenerator(state); }
private:
const node_ptr mGoal;
const G &mGenerator;
};
}
using namespace Private;
template <typename T, typename G>
ProblemMaker<T,G> makeProblem(T root, T goal, G gen )
{
return ProblemMaker<T,G>(forward<T>(root), forward<T>(goal), gen);
}
template <typename T, typename E = typename T::element_type::state_type , typename G >
ProblemMaker<E,G> makeProblem(const T &graph, const T &goal)
{
G gen;
return ProblemMaker<E,G>(graph, goal, gen);
}
#define MAKE_PROBLEM(ROOT, GOAL, NODE, STATE, GEN) makeProblem(ROOT, GOAL, [&]( \
const Node<decltype(ROOT)>::node_ptr & NODE) { \
typename Node<decltype(ROOT)>::leafs_list GEN; \
auto STATE = NODE ->getState();
#define END_PROBLEM })
#define DefClassProblem(name, type) struct name : public Problem<type, name>
#define DefConstructorProblem(p, initial) p::p() : Problem(initial)
}
#endif