Visual Computing Library
Loading...
Searching...
No Matches
bipartite_graph.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_SPACE_COMPLEX_GRAPH_BIPARTITE_GRAPH_H
24#define VCL_SPACE_COMPLEX_GRAPH_BIPARTITE_GRAPH_H
25
26#include "bipartite_iterators/adjacent_left_node_iterator.h"
27#include "bipartite_iterators/adjacent_right_node_iterator.h"
28#include "bipartite_iterators/node_iterator.h"
29#include "nodes/undirected_node.h"
30
31#include <vclib/types.h>
32
33#include <cassert>
34#include <map>
35#include <set>
36#include <vector>
37
38namespace vcl {
39
40namespace detail {
41
42template<typename Graph, typename Iterator>
43class AdjacentLeftNodeIterator;
44
45template<typename Graph, typename Iterator>
46class AdjacentRightNodeIterator;
47
48} // namespace detail
49
50template<class T1, class T2>
52{
53 template<typename Graph, typename Iterator>
54 friend class detail::AdjacentLeftNodeIterator;
55
56 template<typename Graph, typename Iterator>
57 friend class detail::AdjacentRightNodeIterator;
58
59protected:
60 std::map<T1, unsigned int> mMapL;
61 std::map<T2, unsigned int> mMapR;
62
63 std::vector<UndirectedNode<T1>> mNodesL;
64 std::vector<UndirectedNode<T2>> mNodesR;
65
66 std::set<unsigned int> mUnusedLNodes;
67 std::set<unsigned int> mUnusedRNodes;
68
69public:
70 using LeftType = T1;
71 using RightType = T2;
74
75 using LeftNodeIterator =
77 using RightNodeIterator =
79
82
83 using AdjacentLeftNodeIterator = detail::AdjacentLeftNodeIterator<
85 std::unordered_set<unsigned int>::const_iterator>;
86 using AdjacentRightNodeIterator = detail::AdjacentRightNodeIterator<
88 std::unordered_set<unsigned int>::const_iterator>;
89
92
97
103 bool leftNodeExists(const T1& lNode) const
104 {
105 return mMapL.find(lNode) != mMapL.end();
106 }
107
113 bool rightNodeExists(const T2& rNode) const
114 {
115 return mMapR.find(rNode) != mMapR.end();
116 }
117
123 {
124 return (unsigned int) (mNodesL.size() - mUnusedLNodes.size());
125 }
126
132 {
133 return (unsigned int) (mNodesR.size() - mUnusedRNodes.size());
134 }
135
142 {
143 int uid = getIdLeftNode(lNode);
144 return mNodesL[uid].sizeAdjacentNodes();
145 }
146
153 {
154 int vid = getIdRightNode(rNode);
155 return mNodesR[vid].sizeAdjacentNodes();
156 }
157
164 bool addLeftNode(const T1& info)
165 {
166 if (mMapL.find(info) == mMapL.end()) {
167 if (mUnusedLNodes.size() == 0) {
168 mMapL[info] = (unsigned int) mNodesL.size();
169 mNodesL.emplace_back(info);
170 }
171 else {
172 unsigned int id = *(mUnusedLNodes.begin());
173 mUnusedLNodes.erase(mUnusedLNodes.begin());
174 mMapL[info] = id;
175 mNodesL[id] = UndirectedNode<T1>(info);
176 }
177 return true;
178 }
179 else
180 return false;
181 }
182
189 bool addRightNode(const T2& info)
190 {
191 if (mMapR.find(info) == mMapR.end()) {
192 if (mUnusedRNodes.size() == 0) {
193 mMapR[info] = (unsigned int) mNodesR.size();
194 mNodesR.emplace_back(info);
195 }
196 else {
197 unsigned int id = *(mUnusedRNodes.begin());
198 mUnusedRNodes.erase(mUnusedRNodes.begin());
199 mMapR[info] = id;
200 mNodesR[id] = UndirectedNode<T2>(info);
201 }
202 return true;
203 }
204 else
205 return false;
206 }
207
214 {
216 mUnusedLNodes.insert(mMapL[lNode]);
217 mMapL.erase(lNode);
218 return true;
219 }
220 else
221 return false;
222 }
223
230 {
232 mUnusedRNodes.insert(mMapR[rNode]);
233 mMapR.erase(rNode);
234 return true;
235 }
236 else
237 return false;
238 }
239
247 bool addArc(const T1& lNode, const T2& rNode)
248 {
249 try {
250 int uid = getIdLeftNode(lNode);
251 int vid = getIdRightNode(rNode);
252 assert((unsigned int) uid < mNodesL.size());
253 assert((unsigned int) vid < mNodesR.size());
254 mNodesL[uid].addAdjacent(vid);
255 mNodesR[vid].addAdjacent(uid);
256 return true;
257 }
258 catch (...) {
259 return false;
260 }
261 }
262
270 bool deleteArc(const T1& lNode, const T2& rNode)
271 {
272 try {
273 int uid = getIdLeftNode(lNode);
274 int vid = getIdRightNode(rNode);
275 assert((unsigned int) uid < mNodesL.size());
276 assert((unsigned int) vid < mNodesR.size());
277 mNodesL[uid].deleteAdjacent(vid);
278 mNodesR[vid].deleteAdjacent(uid);
279 return true;
280 }
281 catch (...) {
282 return false;
283 }
284 }
285
293 {
294 try {
295 int uid = getIdLeftNode(lNode);
296 for (unsigned int adj : mNodesL[uid]) {
297 mNodesR[adj].deleteAdjacent(uid);
298 }
299 mNodesL[uid].clearAdjacentNodes();
300 return true;
301 }
302 catch (...) {
303 return false;
304 }
305 }
306
314 {
315 try {
316 int vid = getIdRightNode(rNode);
317 for (unsigned int adj : mNodesR[vid]) {
318 mNodesL[adj].deleteAdjacent(vid);
319 }
320 mNodesR[vid].clearAdjacentNodes();
321 return true;
322 }
323 catch (...) {
324 return false;
325 }
326 }
327
334 bool setLeftNode(const T1& old, const T1& newInfo)
335 {
336 try {
337 int uid = getIdLeftNode(old);
338 mNodesL[uid] = UndirectedNode<T1>(newInfo);
339 mMapL.erase(old);
340 mMapL[newInfo] = uid;
341 return true;
342 }
343 catch (...) {
344 return false;
345 }
346 }
347
354 bool setRightNode(const T2& old, const T2& newInfo)
355 {
356 try {
357 int vid = getIdRightNode(old);
358 mNodesR[vid] = UndirectedNode<T2>(newInfo);
359 mMapR.erase(old);
360 mMapR[newInfo] = vid;
361 return true;
362 }
363 catch (...) {
364 return false;
365 }
366 }
367
368 AdjacentLeftNodeIterator adjacentLeftNodeBegin(const T1& lNode) const
369 {
370 int uid = getIdLeftNode(lNode);
371 return AdjacentLeftNodeIterator(*this, mNodesL[uid].begin());
372 }
373
374 AdjacentLeftNodeIterator adjacentLeftNodeEnd(const T1& lNode) const
375 {
376 int uid = getIdLeftNode(lNode);
377 return AdjacentLeftNodeIterator(*this, mNodesL[uid].end());
378 }
379
380 AdjacentRightNodeIterator adjacentRightNodeBegin(const T2& rNode) const
381 {
382 int vid = getIdRightNode(rNode);
383 return AdjacentRightNodeIterator(*this, mNodesR[vid].begin());
384 }
385
386 AdjacentRightNodeIterator adjacentRightNodeEnd(const T2& rNode) const
387 {
388 int vid = getIdRightNode(rNode);
389 return AdjacentRightNodeIterator(*this, mNodesR[vid].end());
390 }
391
392 LeftNodeIterator leftNodeBegin() const
393 {
394 return LeftNodeIterator(mNodesL.begin());
395 }
396
397 LeftNodeIterator leftNodeEnd() const
398 {
399 return LeftNodeIterator(mNodesL.end());
400 }
401
402 RightNodeIterator rightNodeBegin() const
403 {
404 return RightNodeIterator(mNodesR.begin());
405 }
406
407 RightNodeIterator rightNodeEnd() const
408 {
409 return RightNodeIterator(mNodesR.end());
410 }
411
412 LeftNodeView leftNodes() const
413 {
414 return LeftNodeView(leftNodeBegin(), leftNodeEnd());
415 }
416
417 RightNodeView rightNodes() const
418 {
419 return RightNodeView(rightNodeBegin(), rightNodeEnd());
420 }
421
422 AdjacentLeftNodeView adjacentLeftNodes(const T1& lNode) const
423 {
424 return AdjacentLeftNodeView(
425 adjacentLeftNodeBegin(lNode), adjacentLeftNodeEnd(lNode));
426 }
427
428 AdjacentRightNodeView adjacentRightNodes(const T2& rNode) const
429 {
430 return AdjacentRightNodeView(
431 adjacentRightNodeBegin(rNode), adjacentRightNodeEnd(rNode));
432 }
433
434protected:
435 int getIdLeftNode(const T1& uNode) const { return mMapL.at(uNode); }
436
437 int getIdRightNode(const T2& vNode) const { return mMapR.at(vNode); }
438};
439
440} // namespace vcl
441
442#endif // VCL_SPACE_COMPLEX_GRAPH_BIPARTITE_GRAPH_H
Definition bipartite_graph.h:52
bool setRightNode(const T2 &old, const T2 &newInfo)
Sets the key of a rNode.
Definition bipartite_graph.h:354
bool setLeftNode(const T1 &old, const T1 &newInfo)
Sets the key of an lNode.
Definition bipartite_graph.h:334
bool addArc(const T1 &lNode, const T2 &rNode)
Creates an arc between lNode and rNode.
Definition bipartite_graph.h:247
BipartiteGraph()
Default constructor. It creates an empty Bipartite Graph.
Definition bipartite_graph.h:96
bool leftNodeExists(const T1 &lNode) const
Checks if a node exists on the left side of the graph.
Definition bipartite_graph.h:103
uint leftNodesNumber() const
Returns the number of left nodes of the graph.
Definition bipartite_graph.h:122
bool rightNodeExists(const T2 &rNode) const
Checks if a node exists on the right side of the graph.
Definition bipartite_graph.h:113
bool deleteLeftNode(const T1 &lNode)
Removes lNode and all its arcs from the graph.
Definition bipartite_graph.h:213
bool addRightNode(const T2 &info)
Adds a new node on the right side of the graph.
Definition bipartite_graph.h:189
uint adjacentLeftNodeNumber(const T1 &lNode) const
Returns the number of adjacent nodes to lNode.
Definition bipartite_graph.h:141
bool clearAdjacenciesRightNode(const T2 &rNode)
Removes all the arcs connected to rNode (lNode won't have adjacent nodes)
Definition bipartite_graph.h:313
bool clearAdjacenciesLeftNode(const T1 &lNode)
Removes all the arcs connected to lNode (lNode won't have adjacent nodes)
Definition bipartite_graph.h:292
bool deleteRightNode(const T2 &rNode)
Removes rNode and all its arcs from the graph.
Definition bipartite_graph.h:229
bool deleteArc(const T1 &lNode, const T2 &rNode)
Removes the arc between lNode and rNode.
Definition bipartite_graph.h:270
uint adjacentRightNodeNumber(const T2 &rNode) const
Returns the number of adjacent nodes to rNode.
Definition bipartite_graph.h:152
uint rightNodesNumber() const
Returns the number of right nodes of the graph.
Definition bipartite_graph.h:131
bool addLeftNode(const T1 &info)
Adds a new node on the left side of the graph.
Definition bipartite_graph.h:164
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:43