source: src/Graph/BoostGraphCreator.cpp@ 1c0b0b

Candidate_v1.7.0 stable
Last change on this file since 1c0b0b was 1c0b0b, checked in by Frederik Heber <frederik.heber@…>, 3 years ago

Graph6Writer::write_elementlist uses BFS from boundary atom.

  • the elementlist is not stable as the set of atoms is arbitrary to any kind of permutation. However, the underlying bond graph is not, even though it may also have some symmetries.
  • Therefore, we use a BFS from a non-hydrogen atom on the boundary.
  • FIX: BoosGraphCreator gets vector of const atom*.
  • Property mode set to 100644
File size: 6.3 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2017 Frederik Heber. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * BoostGraphCreator.cpp
25 *
26 * Created on: May 17, 2017
27 * Author: heber
28 */
29
30
31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36//#include "CodePatterns/MemDebug.hpp"
37
38#include "BoostGraphCreator.hpp"
39
40#include <algorithm>
41
42#include "CodePatterns/Assert.hpp"
43
44#include "Atom/atom.hpp"
45#include "Graph/Graph6Reader.hpp"
46#include "molecule.hpp"
47
48void BoostGraphCreator::createFromMolecule(
49 const molecule &_mol,
50 const predicate_t &_pred)
51{
52 createFromRange<molecule::const_iterator>(_mol.begin(), _mol.end(), _mol.getAtomCount(), _pred);
53}
54
55static bool predicateAnd(
56 const BoostGraphCreator::predicate_t &_pred1,
57 const BoostGraphCreator::predicate_t &_pred2,
58 const bond &_bond)
59{ return (_pred1(_bond) && _pred2(_bond)); }
60
61static atomId_t getAtomId(
62 const atom *_atom
63 )
64{ return _atom->getId(); }
65
66static bool inSetPredicate(
67 const std::vector<atomId_t> &_atomids,
68 const bond &_bond)
69{
70 const atomId_t leftid = _bond.leftatom->getId();
71 const atomId_t rightid = _bond.rightatom->getId();
72 return std::binary_search(_atomids.begin(), _atomids.end(), leftid)
73 && std::binary_search(_atomids.begin(), _atomids.end(), rightid);
74}
75
76void BoostGraphCreator::createFromAtoms(
77 const std::vector<const atom *> &_atoms,
78 const predicate_t &_pred)
79{
80 // sort makes binary_search possible
81 std::vector<atomId_t> atomids;
82 std::transform(_atoms.begin(), _atoms.end(),
83 std::back_inserter(atomids), getAtomId);
84 ASSERT( _atoms.size() == atomids.size(),
85 "BoostGraphCreator::createFromAtom() - atomids "
86 +toString(atomids.size())+" and atoms "+toString(_atoms.size())
87 +" differ in size?");
88 std::sort(atomids.begin(), atomids.end());
89 const predicate_t predicate = boost::bind(inSetPredicate, boost::ref(atomids), _1);
90 createFromRange<std::vector<const atom *>::const_iterator>(
91 const_cast<const std::vector<const atom *> &>(_atoms).begin(),
92 const_cast<const std::vector<const atom *> &>(_atoms).end(),
93 _atoms.size(),
94 boost::bind(predicateAnd, _pred, predicate, _1));
95}
96
97void BoostGraphCreator::createFromGraph6String(
98 const std::string &_graph_string)
99{
100 Graph6Reader reader;
101 {
102 std::stringstream inputstream(_graph_string);
103 reader(inputstream);
104 }
105
106 graph = UndirectedGraph();
107
108 // add nodes
109 for(int numbers = 0; numbers < reader.get_num_nodes(); ++numbers) {
110 const atomId_t atomid = numbers;
111 Vertex v = boost::add_vertex(atomid, graph);
112 const atomId_t vertexname = boost::get(boost::get(boost::vertex_name, graph), v);
113 const nodeId_t vertexindex = boost::get(boost::get(boost::vertex_index, graph), v);
114 LOG(2, "DEBUG: Adding node " << vertexindex << " associated to atom #" << vertexname);
115 ASSERT( vertexname == atomid,
116 "BoostGraphCreator::createFromRange() - atomid "+toString(atomid)
117 +" is not name of vertex "+toString(vertexname)+".");
118 atomids_nodeids.insert( std::make_pair(vertexname, vertexindex) );
119 }
120 LOG(1, "INFO: Added " << reader.get_num_nodes() << " nodes.");
121
122 // add edges
123 const Graph6Reader::edges_t &edges = reader.get_edges();
124 for(Graph6Reader::edges_t::const_iterator iter = edges.begin();
125 iter != edges.end(); ++iter) {
126 // graph6 contains only upper triangle of adjacency matrix, hence add only once
127 const nodeId_t leftnodeid = iter->first;
128 const nodeId_t rightnodeid = iter->second;
129 boost::add_edge(leftnodeid, rightnodeid, graph);
130 }
131 LOG(1, "INFO: Added " << reader.get_edges().size() << " edges.");
132}
133
134BoostGraphCreator::nodeId_t BoostGraphCreator::getNodeId(
135 const atomId_t &_atomid) const
136{
137 atomids_nodeids_t::const_iterator iter =
138 atomids_nodeids.find(_atomid);
139 return (iter == atomids_nodeids.end()) ? (nodeId_t)-1 : iter->second;
140}
141
142BoostGraphCreator::Edge BoostGraphCreator::findEdge(const atomId_t &_firstid, const atomId_t &_secondid)
143{
144 edge_iter i, end;
145 const name_map_t name_map = boost::get(boost::vertex_name, graph);
146 for (boost::tie(i, end) = boost::edges(graph); i != end; ++i) {
147 const BoostGraphCreator::Edge &e = *i;
148 const Vertex u = source(e, graph);
149 const Vertex v = target(e, graph);
150 const atomId_t atomid_u = boost::get(name_map, u);
151 const atomId_t atomid_v = boost::get(name_map, v);
152 if (atomid_u == _firstid) {
153 if (atomid_v == _secondid)
154 break;
155 } else if (atomid_u == _secondid) {
156 if (atomid_v == _firstid)
157 break;
158 }
159 }
160 if (i != end) {
161 BoostGraphCreator::Edge e = *i;
162 return e;
163 }
164
165 return BoostGraphCreator::Edge();
166}
167
168bool BoostGraphCreator::removeEdge(const atomId_t &_firstid, const atomId_t &_secondid)
169{
170 // look through all edges
171 BoostGraphCreator::Edge e = findEdge(_firstid, _secondid);
172
173 // edge was found
174 if (e != BoostGraphCreator::Edge()) {
175 const Vertex u = source(e, graph);
176 const Vertex v = target(e, graph);
177 if (DoLog(3)) {
178 const name_map_t name_map = boost::get(boost::vertex_name, graph);
179 LOG(3, "DEBUG: Found edge " << boost::get(name_map, u) << " <-> "
180 << boost::get(name_map, v) << ", removing.");
181 }
182 boost::remove_edge(e, graph);
183
184 return true;
185 }
186 return false;
187}
188
189bool BoostGraphCreator::addEdge(const atomId_t &_firstid, const atomId_t &_secondid)
190{
191 // look through all edges
192 BoostGraphCreator::Edge e = findEdge(_firstid, _secondid);
193
194 if (e != BoostGraphCreator::Edge()) {
195 return false;
196 } else {
197 const nodeId_t leftnodeid = getNodeId(_firstid);
198 const nodeId_t rightnodeid = getNodeId(_secondid);
199
200 boost::add_edge(leftnodeid, rightnodeid, graph);
201
202 return true;
203 }
204}
Note: See TracBrowser for help on using the repository browser.