-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAdjacencyMatrix.cpp
More file actions
192 lines (170 loc) · 6.42 KB
/
AdjacencyMatrix.cpp
File metadata and controls
192 lines (170 loc) · 6.42 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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#include "AdjacencyMatrix.h"
#include "BitMapsForScoreVector.h"
#include <cassert>
#include <iostream>
namespace csc{
void AdjacencyMatrix::setEdge(size_t from, size_t to) {
adjacency_matr[from][to] = true;
adjacency_matr[to][from] = false;
/*//check that the edge, that is to be set didn't get defined (in any direction) before
assert(!adjacency_matr[from][to]);
assert(!adjacency_matr[to][from]);
adjacency_matr[from][to] = true;*/
}
bool AdjacencyMatrix::isTournamentGraph() const {
for(size_t i=0; i < num_vertices; i++){
for(size_t j=i+1; j < num_vertices; j++){
if(!AdjacencyMatrix::doVerticesHaveOneDirectedEdge(i, j)){
std::cout << "Vertices " << i << " and " << j << "do not have exactly one directed edge between each other \n";
return false;
}
}
}
for(size_t i=0; i < num_vertices; i++){
if(adjacency_matr[i][i]){
std::cout << "Vertex " << i << " has a reflexive edge\n";
return false;
}
}
return true;
}
bool AdjacencyMatrix::doVerticesHaveOneDirectedEdge(size_t vertex1, size_t vertex2) const {
return adjacency_matr[vertex1][vertex2] xor adjacency_matr[vertex2][vertex1];
}
void AdjacencyMatrix::findCyclesWithStartVertex(vertex v, std::vector<vertex>& blocked, std::vector<vertex>& blockList,
std::vector<vertex>& stack, std::vector<cycle>& allCycles) const {
stack.push_back(v);
blocked[v] = 1;
for(vertex neighbour = 0; neighbour < num_vertices; neighbour++){
if(adjacency_matr[v][neighbour]){
if (neighbour == stack.front()) { // Found a cycle
allCycles.push_back(stack);
} else if (!blocked[neighbour]) {
findCyclesWithStartVertex(neighbour, blocked, blockList, stack, allCycles);
}
}
}
stack.pop_back();
blocked[v] = 0;
}
//I still need to convince myself, that this function does in fact do as I claim
std::vector<cycle> AdjacencyMatrix::findCycles() const{
assert(isTournamentGraph());
std::vector<cycle> allCycles;
std::vector<vertex> vertex_stack;
for (int i = 0; i < num_vertices; ++i) {
std::vector<vertex> blocked(num_vertices, 0);
std::vector<vertex> blockList(num_vertices);
findCyclesWithStartVertex(i, blocked, blockList, vertex_stack, allCycles);
}
return allCycles;
}
bool AdjacencyMatrix::isForwardCycle(const cycle& c){
assert(c.size() >= 3);
vertex prev;
vertex next;
for(size_t i = 1; i < c.size(); i++){
prev = c[i-1];
next = c[i];
if(!adjacency_matr[prev][next]){
return false;
}
}
if(!adjacency_matr[c.back()][c[0]]){
return false;
}
return true;
}
bool AdjacencyMatrix::isBackwardsCycle(const cycle& c){
assert(c.size() >= 3);
vertex prev;
vertex next;
for(size_t i = c.size()-1; i >= 1; i--){
prev = c[i];
next = c[i-1];
if(!adjacency_matr[prev][next]){
return false;
}
}
if(!adjacency_matr[c[0]][c.back()]){
return false;
}
return true;
}
bool AdjacencyMatrix::isCycle(const cycle& c) {
return isForwardCycle(c) || isBackwardsCycle(c);
}
std::pair<vertex, vertex> AdjacencyMatrix::edgeFromEdgeNumber(size_t edgeNumber){
vertex from = 1;
auto num_new_edges = num_vertices-2;
while(edgeNumber >= num_new_edges){
edgeNumber -= num_new_edges;
num_new_edges -= 1;
from += 1;
}
return std::pair<vertex, vertex >{from,from+edgeNumber+1};
}
void AdjacencyMatrix::setEdgesAccordingToIndex(size_t index) {
size_t number_remaining_edges = (num_vertices-1)*(num_vertices-2) /2;
for(size_t edgeNumber = 0; edgeNumber < number_remaining_edges; edgeNumber++){
auto [v1, v2] = edgeFromEdgeNumber(edgeNumber);
if((index >> edgeNumber) & 0b1){
setEdge(v1, v2);
}else{
setEdge(v2, v1);
}
}
assert(isTournamentGraph());
}
void AdjacencyMatrix::print() const {
for(auto& row: adjacency_matr){
for(auto entry: row){
if(entry){
std::cout << "1 ";
}else{
std::cout << "0 ";
}
}
std::cout << "\n";
}
}
void AdjacencyMatrix::setBipartitEdges(const BitMapsForScoreVector &bitmaps, const size_t number_dominated) {
for(size_t i_bitmap=0; i_bitmap < bitmaps.bitmaps.size(); i_bitmap++){
const auto& bitmap = bitmaps.bitmaps[i_bitmap];
const vertex addressed_vertex = i_bitmap + 2; //the first bitmap (i_bitmap=0) corresponds to node 2
for(size_t i_edge=0; i_edge < bitmap.current().size(); i_edge++){
const vertex target = i_edge + number_dominated + 1; //TODO: step through with debug to see if this is correct
if(bitmap.current()[i_edge]){
setEdge(addressed_vertex, target);
}else{
setEdge(target, addressed_vertex);
}
}
}
}
void AdjacencyMatrix::setNonBipartitEdgesAccordingToIndex(size_t index, size_t number_dominated) {
size_t counter = 0;
//setEdges in dominated-subgraph
for(vertex v1 = 1; v1 < number_dominated; v1++){
for(vertex v2 = v1+1; v2 <= number_dominated; v2++){
if((index>>counter)&0b1){
setEdge(v1, v2);
}else{
setEdge(v2, v1);
}
counter++;
}
}
//setEdges in dominator-subgraph
for(vertex v1 = number_dominated+1; v1 < num_vertices-1; v1++){
for(vertex v2 = v1+1; v2 < num_vertices; v2++){
if((index>>counter)&0b1){
setEdge(v1, v2);
}else{
setEdge(v2, v1);
}
counter++;
}
}
}
}