Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

TwoSAT.h
Go to the documentation of this file.
1 
31 #pragma once
32 
33 #include <ogdf/basic/Graph.h>
34 #include <ogdf/basic/GraphList.h>
35 #include <ogdf/basic/basic.h>
37 
38 #include <utility>
39 #include <vector>
40 
41 namespace ogdf {
42 
43 #ifdef OGDF_DEBUG
44 
47  int m_val;
48 
49 public:
50  OGDF_DEPRECATED("uninitialized value")
51 
52  twosat_var() : m_val(0) { }
53 
54  explicit twosat_var(int val) : m_val(val) { }
55 
56  explicit operator int() { return m_val; }
57 
58  bool operator==(const twosat_var& rhs) const { return m_val == rhs.m_val; }
59 
60  bool operator!=(const twosat_var& rhs) const { return m_val != rhs.m_val; }
61 };
62 
63 const twosat_var TwoSAT_Var_Undefined(-1);
64 
65 #else
66 using twosat_var = int;
67 const twosat_var TwoSAT_Var_Undefined = -1;
68 #endif
69 
71 class OGDF_EXPORT TwoSAT : protected Graph {
72  std::vector<bool> m_assignment;
73  std::vector<node> m_node_map;
74 
75 public:
76  TwoSAT() {};
77 
79  node pos = newNode(), neg = newNode();
80  OGDF_ASSERT(pos->index() % 2 == 0);
81  OGDF_ASSERT(pos->index() + 1 == neg->index());
82  m_assignment.push_back(false);
83  OGDF_ASSERT(m_node_map.size() == pos->index());
84  m_node_map.push_back(pos);
85  OGDF_ASSERT(m_node_map.size() == neg->index());
86  m_node_map.push_back(neg);
87  return (twosat_var)(pos->index() / 2);
88  }
89 
90  int variableCount() const {
91  OGDF_ASSERT(nodes.size() % 2 == 0);
92  return nodes.size() / 2;
93  }
94 
95  int newClause(twosat_var var1, bool sign1, twosat_var var2, bool sign2) {
96  auto [p1, n1] = getNodes(var1, !sign1);
97  auto [p2, n2] = getNodes(var2, !sign2);
98  edge e1 = newEdge(n1, p2);
99  edge e2 = newEdge(n2, p1);
100  OGDF_ASSERT(e1->index() % 2 == 0);
101  OGDF_ASSERT(e1->index() + 1 == e2->index());
102  return e1->index();
103  }
104 
105  int clauseCount() const {
106  OGDF_ASSERT(edges.size() % 2 == 0);
107  return edges.size() / 2;
108  }
109 
110  bool solve() {
111  NodeArray<int> components(*this, -1);
112  strongComponents(*this, components);
113 
114  OGDF_ASSERT(nodes.size() % 2 == 0);
115  OGDF_ASSERT(edges.size() % 2 == 0);
116  for (auto it = nodes.begin(); it != nodes.end(); it++) {
117  node pos = *(it);
118  it++;
119  node neg = *(it);
120  OGDF_ASSERT(pos->index() % 2 == 0);
121  OGDF_ASSERT(pos->index() + 1 == neg->index());
122 
123  if (components[pos] == components[neg]) {
124  return false;
125  }
126  m_assignment[pos->index() / 2] = (components[pos] > components[neg]);
127  }
128  return true;
129  }
130 
131  bool getAssignment(twosat_var var) const { return m_assignment[(int)var]; }
132 
133  void clear() override {
134  Graph::clear();
135  m_assignment.clear();
136  }
137 
138  using const_iterator = typename std::vector<bool>::const_iterator;
139  using const_reverse_iterator = typename std::vector<bool>::const_reverse_iterator;
140 
141  const_iterator begin() const { return m_assignment.begin(); }
142 
143  const_iterator end() const { return m_assignment.end(); }
144 
145  const_reverse_iterator rbegin() const { return m_assignment.rbegin(); }
146 
147  const_reverse_iterator rend() const { return m_assignment.rend(); }
148 
149 protected:
150  std::pair<node, node> getNodes(twosat_var var, bool flip = false) const {
151  int idx = getNodeIndex(var, true);
152  node pos = m_node_map[idx];
153  OGDF_ASSERT(pos->index() == idx);
154  OGDF_ASSERT(pos->index() / 2 == (int)var);
155  OGDF_ASSERT(pos->index() % 2 == 0);
156  node neg = m_node_map[idx + 1];
157  OGDF_ASSERT(neg->index() == idx + 1);
158  if (flip) {
159  return std::pair(neg, pos);
160  } else {
161  return std::pair(pos, neg);
162  }
163  }
164 
165  node getNode(twosat_var var, bool sign) const {
166  int idx = getNodeIndex(var, sign);
167  node n = m_node_map[idx];
168  OGDF_ASSERT(n->index() == idx);
169  return n;
170  }
171 
172  int getNodeIndex(twosat_var var, bool sign) const {
173  int idx = ((int)var) * 2 + (sign ? 0 : 1);
174  OGDF_ASSERT(0 <= idx);
176  return idx;
177  }
178 };
179 
180 }
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
Graph.h
Includes declaration of graph class.
ogdf::TwoSAT::begin
const_iterator begin() const
Definition: TwoSAT.h:141
ogdf::TwoSAT::getNodeIndex
int getNodeIndex(twosat_var var, bool sign) const
Definition: TwoSAT.h:172
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
OGDF_DEPRECATED
#define OGDF_DEPRECATED(reason)
Mark a class / member / function as deprecated.
Definition: config.h:120
ogdf::twosat_var::m_val
int m_val
Definition: TwoSAT.h:47
ogdf::NodeElement::index
int index() const
Returns the (unique) node index.
Definition: Graph_d.h:274
ogdf::TwoSAT::getNodes
std::pair< node, node > getNodes(twosat_var var, bool flip=false) const
Definition: TwoSAT.h:150
ogdf::TwoSAT::clear
void clear() override
Removes all nodes and all edges from the graph.
Definition: TwoSAT.h:133
ogdf::TwoSAT::const_reverse_iterator
typename std::vector< bool >::const_reverse_iterator const_reverse_iterator
Definition: TwoSAT.h:139
ogdf::EdgeElement::index
int index() const
Returns the index of the edge.
Definition: Graph_d.h:395
ogdf::TwoSAT_Var_Undefined
const twosat_var TwoSAT_Var_Undefined(-1)
ogdf::twosat_var::operator==
bool operator==(const twosat_var &rhs) const
Definition: TwoSAT.h:58
ogdf::Graph::clear
virtual void clear()
Removes all nodes and all edges from the graph.
ogdf::TwoSAT::newVariable
twosat_var newVariable()
Definition: TwoSAT.h:78
ogdf::TwoSAT::solve
bool solve()
Definition: TwoSAT.h:110
ogdf::TwoSAT::TwoSAT
TwoSAT()
Definition: TwoSAT.h:76
GraphList.h
Decralation of GraphElement and GraphList classes.
ogdf::strongComponents
int strongComponents(const Graph &G, NodeArray< int > &component)
Computes the strongly connected components of the digraph G.
ogdf::Graph::maxNodeIndex
int maxNodeIndex() const
Returns the largest used node index.
Definition: Graph_d.h:988
ogdf::TwoSAT::getAssignment
bool getAssignment(twosat_var var) const
Definition: TwoSAT.h:131
ogdf::internal::GraphRegisteredArray
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition: Graph_d.h:658
ogdf::TwoSAT::const_iterator
typename std::vector< bool >::const_iterator const_iterator
Definition: TwoSAT.h:138
ogdf::Graph
Data type for general directed graphs (adjacency list representation).
Definition: Graph_d.h:869
Minisat::Internal::sign
bool sign(Lit p)
Definition: SolverTypes.h:60
ogdf::TwoSAT::m_node_map
std::vector< node > m_node_map
Definition: TwoSAT.h:73
basic.h
Basic declarations, included by all source files.
OGDF_EXPORT
#define OGDF_EXPORT
Specifies that a function or class is exported by the OGDF DLL.
Definition: config.h:101
ogdf::TwoSAT::variableCount
int variableCount() const
Definition: TwoSAT.h:90
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:363
ogdf::TwoSAT::newClause
int newClause(twosat_var var1, bool sign1, twosat_var var2, bool sign2)
Definition: TwoSAT.h:95
Minisat::Internal::var
int var(Lit p)
Definition: SolverTypes.h:61
ogdf::twosat_var::operator!=
bool operator!=(const twosat_var &rhs) const
Definition: TwoSAT.h:60
ogdf::TwoSAT::m_assignment
std::vector< bool > m_assignment
Definition: TwoSAT.h:72
ogdf::TwoSAT::clauseCount
int clauseCount() const
Definition: TwoSAT.h:105
ogdf::TwoSAT::end
const_iterator end() const
Definition: TwoSAT.h:143
ogdf::TwoSAT::rbegin
const_reverse_iterator rbegin() const
Definition: TwoSAT.h:145
ogdf::twosat_var::twosat_var
twosat_var(int val)
Definition: TwoSAT.h:54
ogdf::TwoSAT::getNode
node getNode(twosat_var var, bool sign) const
Definition: TwoSAT.h:165
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:240
ogdf::TwoSAT::rend
const_reverse_iterator rend() const
Definition: TwoSAT.h:147
simple_graph_alg.h
Declaration of simple graph algorithms.
ogdf::TwoSAT
A simple solver for TwoSAT instances, representing the instance as implication graph and solving it v...
Definition: TwoSAT.h:71
ogdf::twosat_var
In debug mode, twosat_var is a class instead of a simple int to prevent unintened use of the default ...
Definition: TwoSAT.h:46