-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmolstructgraph.cpp
More file actions
87 lines (75 loc) · 2.32 KB
/
molstructgraph.cpp
File metadata and controls
87 lines (75 loc) · 2.32 KB
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
#include "molstructgraph.h"
MolStructGraph::MolStructGraph(const MolStruct &mol)
{
atoms.resize(mol.atoms.size());
for (int i = 0; i < mol.bonds.size(); ++i)
{
auto const &b = mol.bonds[i];
atoms[b.from].bonds.push_back({i, b.to});
atoms[b.to].bonds.push_back({i, b.from});
}
}
QVector<int> MolStructGraph::findPath(int from, int to, int limit)
{
QList<int> currentQueue;
QList<int> nextQueue;
QVector<int> visited; // Record the parent from which this node was visited
visited.fill(-1, atoms.size());
visited[from] = from;
currentQueue.push_back(from);
if (limit < 0)
limit = atoms.size() + 1;
int depth = 0;
while ((depth < limit) && !currentQueue.isEmpty())
{
while (!currentQueue.isEmpty())
{
int a = currentQueue.takeFirst();
for (auto const &b: atoms[a].bonds)
{
if (b.partner == to)
{
// We found our target, now backtrack to get the path
QVector<int> result;
result.push_back(to);
for (int last = a; last != from; last = visited[last])
{
result.push_back(last);
}
result.push_back(from);
std::reverse(result.begin(), result.end());
return result;
}
else if (-1 == visited[b.partner])
{
nextQueue.push_back(b.partner);
visited[b.partner] = a;
}
}
}
std::swap(currentQueue, nextQueue);
}
return {};
}
QVector<int> MolStructGraph::selectBranch(int from, int to)
{
QVector<int> result;
QVector<bool> visited;
visited.resize(atoms.size());
int bond = -1;
for (auto const &b: atoms[from].bonds)
if (b.partner == to)
bond = b.id;
if (bond < 0) // "from" is not connected to "to"
return {};
visited[from] = true;
std::function<void(int)> visitAtom = [&](int id) {
result.push_back(id);
visited[id] = true;
for (auto const &b: atoms[id].bonds)
if (!visited[b.partner])
visitAtom(b.partner);
};
visitAtom(to);
return result;
}