submine 0.1.1__cp312-cp312-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. submine/__init__.py +37 -0
  2. submine/algorithms/__init__.py +23 -0
  3. submine/algorithms/base.py +143 -0
  4. submine/algorithms/gspan.py +156 -0
  5. submine/algorithms/gspan_cpp.cpython-312-darwin.so +0 -0
  6. submine/algorithms/sopagrami.py +250 -0
  7. submine/algorithms/sopagrami_cpp.cpython-312-darwin.so +0 -0
  8. submine/api.py +134 -0
  9. submine/backends/__init__.py +0 -0
  10. submine/backends/gspan/CMakeLists.txt +65 -0
  11. submine/backends/gspan/dfs.cpp +98 -0
  12. submine/backends/gspan/graph.cpp +165 -0
  13. submine/backends/gspan/gspan.cpp +776 -0
  14. submine/backends/gspan/gspan.h +296 -0
  15. submine/backends/gspan/ismin.cpp +124 -0
  16. submine/backends/gspan/main.cpp +106 -0
  17. submine/backends/gspan/misc.cpp +177 -0
  18. submine/backends/gspan/python_bindings.cpp +133 -0
  19. submine/backends/sopagrami/cpp/CMakeLists.txt +44 -0
  20. submine/backends/sopagrami/cpp/include/alg.hpp +150 -0
  21. submine/backends/sopagrami/cpp/include/common/timer.hpp +18 -0
  22. submine/backends/sopagrami/cpp/src/alg.cpp +805 -0
  23. submine/backends/sopagrami/cpp/src/dump.cpp +262 -0
  24. submine/backends/sopagrami/cpp/src/main.cpp +94 -0
  25. submine/backends/sopagrami/cpp/src/python_bindings.cpp +123 -0
  26. submine/cli/__init__.py +6 -0
  27. submine/cli/main.py +87 -0
  28. submine/core/__init__.py +12 -0
  29. submine/core/graph.py +179 -0
  30. submine/core/result.py +121 -0
  31. submine/datasets/__init__.py +11 -0
  32. submine/datasets/loaders.py +145 -0
  33. submine/errors.py +41 -0
  34. submine/io/__init__.py +30 -0
  35. submine/io/common.py +173 -0
  36. submine/io/gexf.py +88 -0
  37. submine/io/gspan.py +268 -0
  38. submine/io/sopagrami.py +143 -0
  39. submine/io/transcode.py +147 -0
  40. submine/registry.py +8 -0
  41. submine/utils/__init__.py +6 -0
  42. submine/utils/checks.py +115 -0
  43. submine/utils/logging.py +41 -0
  44. submine-0.1.1.dist-info/METADATA +178 -0
  45. submine-0.1.1.dist-info/RECORD +47 -0
  46. submine-0.1.1.dist-info/WHEEL +6 -0
  47. submine-0.1.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,296 @@
1
+ /*
2
+ $Id: gspan.h,v 1.6 2004/05/21 05:50:13 taku-ku Exp $;
3
+
4
+ Copyright (C) 2004 Taku Kudo, All rights reserved.
5
+ This is free software with ABSOLUTELY NO WARRANTY.
6
+
7
+ This program is free software; you can redistribute it and/or modify
8
+ it under the terms of the GNU General Public License as published by
9
+ the Free Software Foundation; either version 2 of the License, or
10
+ (at your option) any later version.
11
+
12
+ This program is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ GNU General Public License for more details.
16
+
17
+ You should have received a copy of the GNU General Public License
18
+ along with this program; if not, write to the Free Software
19
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20
+ 02111-1307, USA
21
+ */
22
+ #include <iostream>
23
+ #include <map>
24
+ #include <vector>
25
+ #include <set>
26
+ #include <algorithm>
27
+ #include <functional>
28
+
29
+ // Standalone C++ build: no MATLAB/MEX dependency.
30
+
31
+ namespace GSPAN {
32
+
33
+ template <class T> inline void _swap (T &x, T &y) { T z = x; x = y; y = z; }
34
+
35
+ struct Edge {
36
+ int from;
37
+ int to;
38
+ int elabel;
39
+ unsigned int id;
40
+ Edge(): from(0), to(0), elabel(0), id(0) {};
41
+ };
42
+
43
+ class Vertex
44
+ {
45
+ public:
46
+ typedef std::vector<Edge>::iterator edge_iterator;
47
+
48
+ int label;
49
+ std::vector<Edge> edge;
50
+
51
+ void push (int from, int to, int elabel)
52
+ {
53
+ edge.resize (edge.size()+1);
54
+ edge[edge.size()-1].from = from;
55
+ edge[edge.size()-1].to = to;
56
+ edge[edge.size()-1].elabel = elabel;
57
+ return;
58
+ }
59
+ };
60
+
61
+ class Graph: public std::vector<Vertex> {
62
+ private:
63
+ unsigned int edge_size_;
64
+ public:
65
+ typedef std::vector<Vertex>::iterator vertex_iterator;
66
+
67
+ Graph (bool _directed)
68
+ {
69
+ directed = _directed;
70
+ };
71
+ bool directed;
72
+
73
+ // int y; // class label
74
+ unsigned int edge_size () { return edge_size_; }
75
+ unsigned int vertex_size () { return (unsigned int)size(); } // wrapper
76
+ void buildEdge ();
77
+ std::istream &read (std::istream &); // read
78
+ std::ostream &write (std::ostream &); // write
79
+ void check (void);
80
+
81
+ Graph(): edge_size_(0), directed(false) {};
82
+ };
83
+
84
+ class DFS {
85
+ public:
86
+ int from;
87
+ int to;
88
+ int fromlabel;
89
+ int elabel;
90
+ int tolabel;
91
+ friend bool operator == (const DFS &d1, const DFS &d2)
92
+ {
93
+ return (d1.from == d2.from && d1.to == d2.to && d1.fromlabel == d2.fromlabel
94
+ && d1.elabel == d2.elabel && d1.tolabel == d2.tolabel);
95
+ }
96
+ friend bool operator != (const DFS &d1, const DFS &d2) { return (! (d1 == d2)); }
97
+ DFS(): from(0), to(0), fromlabel(0), elabel(0), tolabel(0) {};
98
+ };
99
+
100
+ typedef std::vector<int> RMPath;
101
+
102
+ struct DFSCode: public std::vector <DFS> {
103
+ private:
104
+ RMPath rmpath;
105
+ public:
106
+ const RMPath& buildRMPath ();
107
+
108
+ /* Convert current DFS code into a graph.
109
+ */
110
+ bool toGraph (Graph &);
111
+
112
+ /* Clear current DFS code and build code from the given graph.
113
+ */
114
+ void fromGraph (Graph &g);
115
+
116
+ /* Return number of nodes in the graph.
117
+ */
118
+ unsigned int nodeCount (void);
119
+
120
+ void push (int from, int to, int fromlabel, int elabel, int tolabel)
121
+ {
122
+ resize (size() + 1);
123
+ DFS &d = (*this)[size()-1];
124
+
125
+ d.from = from;
126
+ d.to = to;
127
+ d.fromlabel = fromlabel;
128
+ d.elabel = elabel;
129
+ d.tolabel = tolabel;
130
+ }
131
+ void pop () { resize (size()-1); }
132
+ std::ostream &write (std::ostream &); // write
133
+ };
134
+
135
+ struct PDFS {
136
+ unsigned int id; // ID of the original input graph
137
+ Edge *edge;
138
+ PDFS *prev;
139
+ PDFS(): id(0), edge(0), prev(0) {};
140
+ };
141
+
142
+ class History: public std::vector<Edge*> {
143
+ private:
144
+ std::vector<int> edge;
145
+ std::vector<int> vertex;
146
+
147
+ public:
148
+ bool hasEdge (unsigned int id) { return (bool)edge[id]; }
149
+ bool hasVertex (unsigned int id) { return (bool)vertex[id]; }
150
+ void build (Graph &, PDFS *);
151
+ History() {};
152
+ History (Graph& g, PDFS *p) { build (g, p); }
153
+
154
+ };
155
+
156
+ class Projected: public std::vector<PDFS> {
157
+ public:
158
+ void push (int id, Edge *edge, PDFS *prev)
159
+ {
160
+ resize (size() + 1);
161
+ PDFS &d = (*this)[size()-1];
162
+ d.id = id; d.edge = edge; d.prev = prev;
163
+ }
164
+ };
165
+
166
+ /* class FrequentSet {
167
+ private:
168
+ std::vector <unsigned> frequent1;
169
+ std::map <unsigned, std::set<int> > frequent2;
170
+
171
+ public:
172
+ void push (unsigned int); // set single item
173
+ void push (unsigned int, unsigned int); // set two nodes
174
+ }; */
175
+
176
+ typedef std::vector <Edge*> EdgeList;
177
+
178
+ bool get_forward_pure (Graph&, Edge *, int, History&, EdgeList &);
179
+ bool get_forward_rmpath (Graph&, Edge *, int, History&, EdgeList &);
180
+ bool get_forward_root (Graph&, Vertex&, EdgeList &);
181
+ Edge *get_backward (Graph&, Edge *, Edge *, History&);
182
+
183
+ class gSpan {
184
+ public:
185
+
186
+ gSpan (void);
187
+
188
+ /* boostType: 1 for 1.5-class LPBoosting, 2 for 2-class LPBoosting
189
+ */
190
+ void boost_setup (unsigned int _boostN, double _boostTau,
191
+ unsigned int _boostmax,
192
+ std::vector<double>& _boostY,
193
+ std::vector<double>& _boostWeights,
194
+ int boostType);
195
+
196
+ void run (std::istream &is, std::ostream &_os,
197
+ unsigned int _minsup,
198
+ unsigned int _maxpat_min, unsigned int _maxpat_max,
199
+ bool _enc,
200
+ bool _where,
201
+ bool _directed);
202
+
203
+ using PatternCallback = std::function<void(const Graph& pattern,
204
+ unsigned int support,
205
+ const Projected* projected)>;
206
+
207
+
208
+ void set_callback(PatternCallback cb) { callback_ = std::move(cb); }
209
+ private:
210
+
211
+ typedef std::map<int, std::map <int, std::map <int, Projected> > > Projected_map3;
212
+ typedef std::map<int, std::map <int, Projected> > Projected_map2;
213
+ typedef std::map<int, Projected> Projected_map1;
214
+ typedef std::map<int, std::map <int, std::map <int, Projected> > >::iterator Projected_iterator3;
215
+ typedef std::map<int, std::map <int, Projected> >::iterator Projected_iterator2;
216
+ typedef std::map<int, Projected>::iterator Projected_iterator1;
217
+ typedef std::map<int, std::map <int, std::map <int, Projected> > >::reverse_iterator Projected_riterator3;
218
+
219
+ std::vector < Graph > TRANS;
220
+ DFSCode DFS_CODE;
221
+ DFSCode DFS_CODE_IS_MIN;
222
+ Graph GRAPH_IS_MIN;
223
+
224
+
225
+
226
+ unsigned int ID;
227
+ unsigned int minsup;
228
+ unsigned int maxpat_min; // lower bound on node count
229
+ unsigned int maxpat_max; // upper bound on node count
230
+ bool where;
231
+ bool enc;
232
+ bool directed;
233
+ std::ostream* os;
234
+
235
+ /* Singular vertex handling stuff
236
+ * [graph][vertexlabel] = count.
237
+ */
238
+ std::map<unsigned int, std::map<unsigned int, unsigned int> > singleVertex;
239
+ std::map<unsigned int, unsigned int> singleVertexLabel;
240
+
241
+ /* Graph boosting variables
242
+ */
243
+ bool boost;
244
+ double boostTau; // lower bound to be a suitable pattern.
245
+ unsigned int boostN; // Number of top-n graphs to collect
246
+ double boostWeightSum; // \sum_{i=1}^L y_i d_i
247
+ int boostType; // 1: 1.5-class, 2: 2-class LPBoosting
248
+ std::vector<double> boostY; // +1/-1 labels
249
+ std::vector<double> boostWeights; // sample weights
250
+
251
+ std::vector<Graph> bestGraphs;
252
+ std::vector<double> bestGraphsY;
253
+ std::vector<double> bestGraphsGain;
254
+ std::vector<std::map<unsigned int, unsigned int> > bestGraphsCounts;
255
+ unsigned int boostseen;
256
+ unsigned int boostmax;
257
+
258
+ /* Transparent pointers for gain function and gain bound.
259
+ */
260
+ double (gSpan::* gain)(Projected &projected, double y);
261
+ double (gSpan::* gainbound)(Projected &projected);
262
+
263
+ /* Graph boosting methods
264
+ */
265
+ double gainbound2 (Projected &projected);
266
+ double gainbound1d5 (Projected &projected);
267
+
268
+ double gain2 (Projected &projected, double y);
269
+ double gain1d5 (Projected &projected, double y);
270
+
271
+ void report_boosting (Projected &projected, unsigned int sup,
272
+ double gain, double yval);
273
+ void report_boosting_inter (Graph &g, unsigned int sup,
274
+ double gain, double yval, std::map<unsigned int, unsigned int>& GYcounts);
275
+ void report_single (Graph &g, std::map<unsigned int, unsigned int>& ncount);
276
+
277
+ bool is_min ();
278
+ bool project_is_min (Projected &);
279
+
280
+ std::map<unsigned int, unsigned int> support_counts (Projected &projected);
281
+ unsigned int support (Projected&);
282
+ void project (Projected &);
283
+ void report (Projected &, unsigned int);
284
+
285
+ std::istream &read (std::istream &);
286
+
287
+
288
+ void run_intern (void);
289
+ PatternCallback callback_;
290
+
291
+
292
+
293
+ };
294
+ };
295
+
296
+
@@ -0,0 +1,124 @@
1
+ /*
2
+ $Id: ismin.cpp,v 1.5 2004/05/21 05:50:13 taku-ku Exp $;
3
+
4
+ Copyright (C) 2004 Taku Kudo, All rights reserved.
5
+ This is free software with ABSOLUTELY NO WARRANTY.
6
+
7
+ This program is free software; you can redistribute it and/or modify
8
+ it under the terms of the GNU General Public License as published by
9
+ the Free Software Foundation; either version 2 of the License, or
10
+ (at your option) any later version.
11
+
12
+ This program is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ GNU General Public License for more details.
16
+
17
+ You should have received a copy of the GNU General Public License
18
+ along with this program; if not, write to the Free Software
19
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20
+ 02111-1307, USA
21
+ */
22
+ #include "gspan.h"
23
+
24
+ namespace GSPAN {
25
+
26
+ bool gSpan::is_min ()
27
+ {
28
+ if (DFS_CODE.size() == 1)
29
+ return (true);
30
+
31
+ DFS_CODE.toGraph (GRAPH_IS_MIN);
32
+ DFS_CODE_IS_MIN.clear ();
33
+
34
+ Projected_map3 root;
35
+ EdgeList edges;
36
+
37
+ for (unsigned int from = 0; from < GRAPH_IS_MIN.size() ; ++from)
38
+ if (get_forward_root (GRAPH_IS_MIN, GRAPH_IS_MIN[from], edges))
39
+ for (EdgeList::iterator it = edges.begin(); it != edges.end(); ++it)
40
+ root[GRAPH_IS_MIN[from].label][(*it)->elabel][GRAPH_IS_MIN[(*it)->to].label].push (0, *it, 0);
41
+
42
+ Projected_iterator3 fromlabel = root.begin();
43
+ Projected_iterator2 elabel = fromlabel->second.begin();
44
+ Projected_iterator1 tolabel = elabel->second.begin();
45
+
46
+ DFS_CODE_IS_MIN.push (0, 1, fromlabel->first, elabel->first, tolabel->first);
47
+
48
+ return (project_is_min (tolabel->second));
49
+ }
50
+
51
+ bool gSpan::project_is_min (Projected &projected)
52
+ {
53
+ const RMPath& rmpath = DFS_CODE_IS_MIN.buildRMPath ();
54
+ int minlabel = DFS_CODE_IS_MIN[0].fromlabel;
55
+ int maxtoc = DFS_CODE_IS_MIN[rmpath[0]].to;
56
+
57
+ {
58
+ Projected_map1 root;
59
+ bool flg = false;
60
+ int newto = 0;
61
+
62
+ for (int i = rmpath.size()-1; ! flg && i >= 1; --i) {
63
+ for (unsigned int n = 0; n < projected.size(); ++n) {
64
+ PDFS *cur = &projected[n];
65
+ History history (GRAPH_IS_MIN, cur);
66
+ Edge *e = get_backward (GRAPH_IS_MIN, history[rmpath[i]], history[rmpath[0]], history);
67
+ if (e) {
68
+ root[e->elabel].push (0, e, cur);
69
+ newto = DFS_CODE_IS_MIN[rmpath[i]].from;
70
+ flg = true;
71
+ }
72
+ }
73
+ }
74
+
75
+ if (flg) {
76
+ Projected_iterator1 elabel = root.begin();
77
+ DFS_CODE_IS_MIN.push (maxtoc, newto, -1, elabel->first, -1);
78
+ if (DFS_CODE[DFS_CODE_IS_MIN.size()-1] != DFS_CODE_IS_MIN [DFS_CODE_IS_MIN.size()-1]) return false;
79
+ return project_is_min (elabel->second);
80
+ }
81
+ }
82
+
83
+ {
84
+ bool flg = false;
85
+ int newfrom = 0;
86
+ Projected_map2 root;
87
+ EdgeList edges;
88
+
89
+ for (unsigned int n = 0; n < projected.size(); ++n) {
90
+ PDFS *cur = &projected[n];
91
+ History history (GRAPH_IS_MIN, cur);
92
+ if (get_forward_pure (GRAPH_IS_MIN, history[rmpath[0]], minlabel, history, edges)) {
93
+ flg = true;
94
+ newfrom = maxtoc;
95
+ for (EdgeList::iterator it = edges.begin(); it != edges.end(); ++it)
96
+ root[(*it)->elabel][GRAPH_IS_MIN[(*it)->to].label].push (0, *it, cur);
97
+ }
98
+ }
99
+
100
+ for (int i = 0; ! flg && i < (int)rmpath.size(); ++i) {
101
+ for (unsigned int n = 0; n < projected.size(); ++n) {
102
+ PDFS *cur = &projected[n];
103
+ History history (GRAPH_IS_MIN, cur);
104
+ if (get_forward_rmpath (GRAPH_IS_MIN, history[rmpath[i]], minlabel, history, edges)) {
105
+ flg = true;
106
+ newfrom = DFS_CODE_IS_MIN[rmpath[i]].from;
107
+ for (EdgeList::iterator it = edges.begin(); it != edges.end(); ++it)
108
+ root[(*it)->elabel][GRAPH_IS_MIN[(*it)->to].label].push (0, *it, cur);
109
+ }
110
+ }
111
+ }
112
+
113
+ if (flg) {
114
+ Projected_iterator2 elabel = root.begin();
115
+ Projected_iterator1 tolabel = elabel->second.begin();
116
+ DFS_CODE_IS_MIN.push (newfrom, maxtoc + 1, -1, elabel->first, tolabel->first);
117
+ if (DFS_CODE[DFS_CODE_IS_MIN.size()-1] != DFS_CODE_IS_MIN [DFS_CODE_IS_MIN.size()-1]) return false;
118
+ return project_is_min (tolabel->second);
119
+ }
120
+ }
121
+
122
+ return true;
123
+ }
124
+ }
@@ -0,0 +1,106 @@
1
+ #include <iostream>
2
+ #include <string>
3
+ #include <cstdlib> // std::strtoul
4
+ #include <cerrno> // errno
5
+ #include <climits> // ULONG_MAX
6
+
7
+ #include "gspan.h"
8
+
9
+ static void usage() {
10
+ std::cerr
11
+ << "Usage: gspan_cli [options] < input.data > output.txt\n"
12
+ << "Options:\n"
13
+ << " -m <minsup> Minimum support (same as -s)\n"
14
+ << " -s <minsup> Minimum support (same as -m)\n"
15
+ << " -n <minnodes> Minimum number of nodes in a pattern\n"
16
+ << " -L <maxpat> Maximum pattern size (edges) / limit (as in original)\n"
17
+ << " -d Enable encoding (same as -e)\n"
18
+ << " -e Enable encoding (same as -d)\n"
19
+ << " -w Output where (occurrences)\n"
20
+ << " -D Directed graphs\n"
21
+ << " -h Show this help\n";
22
+ }
23
+
24
+ // Strict-ish unsigned int parser with basic validation.
25
+ static bool parse_uint(const char* s, unsigned int& out) {
26
+ if (!s || !*s) return false;
27
+ errno = 0;
28
+ char* end = nullptr;
29
+ unsigned long v = std::strtoul(s, &end, 10);
30
+ if (errno != 0 || end == s || *end != '\0') return false;
31
+ if (v > static_cast<unsigned long>(UINT_MAX)) return false;
32
+ out = static_cast<unsigned int>(v);
33
+ return true;
34
+ }
35
+
36
+ int main(int argc, char** argv) {
37
+ unsigned int minsup = 1;
38
+ unsigned int maxpat = 0xffffffffu;
39
+ unsigned int minnodes = 0;
40
+ bool where = false;
41
+ bool enc = false;
42
+ bool directed = false;
43
+
44
+ for (int i = 1; i < argc; ++i) {
45
+ std::string a = argv[i];
46
+
47
+ auto need_value = [&](const char* flag) -> const char* {
48
+ if (i + 1 >= argc) {
49
+ std::cerr << "Missing value after " << flag << "\n";
50
+ usage();
51
+ std::exit(-1);
52
+ }
53
+ return argv[++i];
54
+ };
55
+
56
+ if (a == "-h") {
57
+ usage();
58
+ return 0;
59
+ } else if (a == "-m" || a == "-s") {
60
+ unsigned int v = 0;
61
+ const char* s = need_value(a.c_str());
62
+ if (!parse_uint(s, v)) {
63
+ std::cerr << "Invalid value for " << a << ": " << s << "\n";
64
+ usage();
65
+ return -1;
66
+ }
67
+ minsup = v;
68
+ } else if (a == "-n") {
69
+ unsigned int v = 0;
70
+ const char* s = need_value("-n");
71
+ if (!parse_uint(s, v)) {
72
+ std::cerr << "Invalid value for -n: " << s << "\n";
73
+ usage();
74
+ return -1;
75
+ }
76
+ minnodes = v;
77
+ } else if (a == "-L") {
78
+ unsigned int v = 0;
79
+ const char* s = need_value("-L");
80
+ if (!parse_uint(s, v)) {
81
+ std::cerr << "Invalid value for -L: " << s << "\n";
82
+ usage();
83
+ return -1;
84
+ }
85
+ maxpat = v;
86
+ } else if (a == "-d" || a == "-e") {
87
+ enc = true;
88
+ } else if (a == "-w") {
89
+ where = true;
90
+ } else if (a == "-D") {
91
+ directed = true;
92
+ } else {
93
+ std::cerr << "Unknown option: " << a << "\n";
94
+ usage();
95
+ return -1;
96
+ }
97
+ }
98
+
99
+ // Optional I/O speedups (safe and portable)
100
+ std::ios::sync_with_stdio(false);
101
+ std::cin.tie(nullptr);
102
+
103
+ GSPAN::gSpan gspan;
104
+ gspan.run(std::cin, std::cout, minsup,minnodes, maxpat, enc, where, directed);
105
+ return 0;
106
+ }
@@ -0,0 +1,177 @@
1
+ /*
2
+ $Id: misc.cpp,v 1.6 2004/05/21 05:50:13 taku-ku Exp $;
3
+
4
+ Copyright (C) 2004 Taku Kudo, All rights reserved.
5
+ This is free software with ABSOLUTELY NO WARRANTY.
6
+
7
+ This program is free software; you can redistribute it and/or modify
8
+ it under the terms of the GNU General Public License as published by
9
+ the Free Software Foundation; either version 2 of the License, or
10
+ (at your option) any later version.
11
+
12
+ This program is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ GNU General Public License for more details.
16
+
17
+ You should have received a copy of the GNU General Public License
18
+ along with this program; if not, write to the Free Software
19
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20
+ 02111-1307, USA
21
+ */
22
+ #include "gspan.h"
23
+ #include <assert.h>
24
+
25
+ namespace GSPAN {
26
+
27
+ const RMPath &DFSCode::buildRMPath ()
28
+ {
29
+ rmpath.clear ();
30
+
31
+ int old_from = -1;
32
+
33
+ for (int i = size() - 1 ; i >= 0 ; --i) {
34
+ if ((*this)[i].from < (*this)[i].to && // forward
35
+ (rmpath.empty() || old_from == (*this)[i].to))
36
+ {
37
+ rmpath.push_back (i);
38
+ old_from = (*this)[i].from;
39
+ }
40
+ }
41
+
42
+ return rmpath;
43
+ }
44
+
45
+ void History::build (Graph &graph, PDFS *e)
46
+ {
47
+ // first build history
48
+ clear ();
49
+ edge.clear ();
50
+ edge.resize (graph.edge_size());
51
+ vertex.clear ();
52
+ vertex.resize (graph.size());
53
+
54
+ if (e) {
55
+ push_back (e->edge);
56
+ edge[e->edge->id] = vertex[e->edge->from] = vertex[e->edge->to] = 1;
57
+
58
+ for (PDFS *p = e->prev ; p ; p = p->prev) {
59
+ push_back (p->edge); // this line eats 8% of overall instructions(!)
60
+ edge[p->edge->id] = vertex[p->edge->from] = vertex[p->edge->to] = 1;
61
+ }
62
+ std::reverse (begin(), end());
63
+ }
64
+ }
65
+
66
+ /* get_forward_pure ()
67
+ e1 (from1, elabel1, to1)
68
+ from $B$+$i7R$,$k(B edge e2(from2, elabel2, to2) $B$rJV$9(B.
69
+
70
+ minlabel <= elabel2,
71
+ (elabel1 < elabel2 ||
72
+ (elabel == elabel2 && tolabel1 < tolabel2) $B$N>r7o$r$_$?$9(B.
73
+ (elabel1, to1) $B$N$[$&$,@h$KC5:w$5$l$k$Y$-(B
74
+ $B$^$?(B, $B$$$^$^$G8+$?(B vertex $B$K$O@B$+$J$$(B (backward $B$N$d$/$a(B)
75
+ */
76
+ bool get_forward_rmpath (Graph &graph, Edge *e, int minlabel, History& history, EdgeList &result)
77
+ {
78
+ result.clear ();
79
+ assert (e->to >= 0 && e->to < graph.size ());
80
+ assert (e->from >= 0 && e->from < graph.size ());
81
+ int tolabel = graph[e->to].label;
82
+
83
+ for (Vertex::edge_iterator it = graph[e->from].edge.begin() ;
84
+ it != graph[e->from].edge.end() ; ++it)
85
+ {
86
+ int tolabel2 = graph[it->to].label;
87
+ if (e->to == it->to || minlabel > tolabel2 || history.hasVertex (it->to))
88
+ continue;
89
+
90
+ if (e->elabel < it->elabel || (e->elabel == it->elabel && tolabel <= tolabel2))
91
+ result.push_back (&(*it));
92
+ }
93
+
94
+ return (! result.empty());
95
+ }
96
+
97
+ /* get_forward_pure ()
98
+ e (from, elabel, to)
99
+ to $B$+$i7R$,$k(B edge $B$rJV$9(B
100
+ $B$?$@$7(B, minlabel $B$h$jBg$-$$$b$N$K$7$+$$$+$J$$(B (DFS$B$N@)Ls(B)
101
+ $B$^$?(B, $B$$$^$^$G8+$?(B vertex $B$K$O@B$+$J$$(B (backward $B$N$d$/$a(B)
102
+ */
103
+ bool get_forward_pure (Graph &graph, Edge *e, int minlabel, History& history, EdgeList &result)
104
+ {
105
+ result.clear ();
106
+
107
+ assert (e->to >= 0 && e->to < graph.size ());
108
+
109
+ /* Walk all edges leaving from vertex e->to.
110
+ */
111
+ for (Vertex::edge_iterator it = graph[e->to].edge.begin() ;
112
+ it != graph[e->to].edge.end() ; ++it)
113
+ {
114
+ /* -e-> [e->to] -it-> [it->to]
115
+ */
116
+ assert (it->to >= 0 && it->to < graph.size ());
117
+ if (minlabel > graph[it->to].label || history.hasVertex (it->to))
118
+ continue;
119
+
120
+ result.push_back (&(*it));
121
+ }
122
+
123
+ return (! result.empty());
124
+ }
125
+
126
+ /* graph $B$N(B vertex $B$+$i$O$($k(B edge $B$rC5$9(B
127
+ $B$?$@$7(B, fromlabel <= tolabel $B$N@-<A$rK~$?$9(B.
128
+ */
129
+ bool get_forward_root (Graph &g, Vertex &v, EdgeList &result)
130
+ {
131
+ result.clear ();
132
+ for (Vertex::edge_iterator it = v.edge.begin(); it != v.edge.end(); ++it) {
133
+ assert (it->to >= 0 && it->to < g.size ());
134
+ if (v.label <= g[it->to].label)
135
+ result.push_back (&(*it));
136
+ }
137
+
138
+ return (! result.empty());
139
+ }
140
+
141
+ /* get_backward (graph, e1, e2, history);
142
+ e1 (from1, elabel1, to1)
143
+ e2 (from2, elabel2, to2)
144
+ to2 -> from1 $B$K7R$,$k$+$I$&$+$7$i$Y$k(B.
145
+
146
+ (elabel1 < elabel2 ||
147
+ (elabel == elabel2 && tolabel1 < tolabel2) $B$N>r7o$r$_$?$9(B. (elabel1, to1) $B$N$[$&$,@h$KC5:w$5$l$k$Y$-(B
148
+ */
149
+ Edge *get_backward (Graph &graph, Edge* e1, Edge* e2, History& history)
150
+ {
151
+ if (e1 == e2)
152
+ return 0;
153
+
154
+ assert (e1->from >= 0 && e1->from < graph.size ());
155
+ assert (e1->to >= 0 && e1->to < graph.size ());
156
+ assert (e2->to >= 0 && e2->to < graph.size ());
157
+
158
+ for (Vertex::edge_iterator it = graph[e2->to].edge.begin() ;
159
+ it != graph[e2->to].edge.end() ; ++it)
160
+ {
161
+ if (history.hasEdge (it->id))
162
+ continue;
163
+
164
+ if ( (it->to == e1->from) &&
165
+ ( (e1->elabel < it->elabel) ||
166
+ (e1->elabel == it->elabel) &&
167
+ (graph[e1->to].label <= graph[e2->to].label)
168
+ ) )
169
+ {
170
+ return &(*it);
171
+ }
172
+ }
173
+
174
+ return 0;
175
+ }
176
+ }
177
+