snark_tool/service/colour/recursive/
bfs_basic.rs1use crate::graph::edge::Edge;
2use crate::graph::graph::Graph;
3use crate::graph::vertex::Vertex;
4use crate::service::colour::colouriser::Colouriser;
5use crate::service::graph_traversal::bfs::BfsOfGraph;
6
7#[derive(Debug, Clone)]
11pub struct BFSColouriserBasic {}
12
13struct BFSColouriserGraph<'a, G: Graph> {
14 vertices: Vec<[(usize, usize); 3]>,
15 bfs: BfsOfGraph<'a, G>,
16}
17
18impl Colouriser for BFSColouriserBasic {
19 fn is_colorable<G: Graph>(graph: &G) -> bool {
20 let mut color_graph = BFSColouriserGraph::new(graph);
21 color_graph.color()
22 }
23
24 fn new() -> Self {
25 BFSColouriserBasic {}
26 }
27}
28
29impl<'a, G: Graph> BFSColouriserGraph<'a, G> {
30 pub fn new(graph: &'a G) -> Self {
31 let mut vertices = Vec::with_capacity(graph.size());
32 for vertex in graph.vertices() {
34 let mut neighbors = [(0, 0); 3];
35 let mut i = 0;
36 for edge in graph.edges_of_vertex(vertex.index()) {
37 neighbors[i].1 = 0;
40 if edge.from() == vertex.index() {
41 neighbors[i].0 = edge.to();
42 } else {
43 neighbors[i].0 = edge.from();
44 }
45 i += 1;
46 }
47 vertices.push(neighbors);
48 }
49 let first_vertex = 0;
50 let colors = vec![3, 4, 5];
51 let bfs = BfsOfGraph::new(graph, first_vertex);
52
53 let mut color_graph = BFSColouriserGraph { vertices, bfs };
54
55 color_graph.bfs.next();
57 color_graph.set_edge_color(
58 first_vertex,
59 color_graph.vertices[first_vertex][0].0,
60 colors[0],
61 );
62 color_graph.set_edge_color(
63 first_vertex,
64 color_graph.vertices[first_vertex][1].0,
65 colors[1],
66 );
67 color_graph.set_edge_color(
68 first_vertex,
69 color_graph.vertices[first_vertex][2].0,
70 colors[2],
71 );
72
73 color_graph
74 }
75
76 fn color(&mut self) -> bool {
77 if let Some(next) = self.bfs.next() {
78 let actual = next.index();
79
80 let mut color_sum = 0;
82 let mut first_neighbor = 0;
83 let mut second_neighbor = 0;
84 for neighbor in self.vertices[next.index()].iter() {
85 color_sum += neighbor.1;
86
87 if neighbor.1 == 0 {
88 second_neighbor = first_neighbor;
89 first_neighbor = neighbor.0;
90 }
91 }
92
93 match color_sum {
94 3 => {
96 self.set_edge_color(actual, first_neighbor, 4);
97 self.set_edge_color(actual, second_neighbor, 5);
98 if self.are_vertices_without_conflict(first_neighbor, second_neighbor) {
99 if self.color() {
100 return true;
101 }
102 }
103 self.set_edge_color(actual, first_neighbor, 5);
104 self.set_edge_color(actual, second_neighbor, 4);
105 if self.are_vertices_without_conflict(first_neighbor, second_neighbor) {
106 if self.color() {
107 return true;
108 }
109 }
110 self.set_edge_color(actual, first_neighbor, 0);
111 self.set_edge_color(actual, second_neighbor, 0);
112 }
113 4 => {
114 self.set_edge_color(actual, first_neighbor, 3);
115 self.set_edge_color(actual, second_neighbor, 5);
116 if self.are_vertices_without_conflict(first_neighbor, second_neighbor) {
117 if self.color() {
118 return true;
119 }
120 }
121 self.set_edge_color(actual, first_neighbor, 5);
122 self.set_edge_color(actual, second_neighbor, 3);
123 if self.are_vertices_without_conflict(first_neighbor, second_neighbor) {
124 if self.color() {
125 return true;
126 }
127 }
128 self.set_edge_color(actual, first_neighbor, 0);
129 self.set_edge_color(actual, second_neighbor, 0);
130 }
131 5 => {
132 self.set_edge_color(actual, first_neighbor, 3);
133 self.set_edge_color(actual, second_neighbor, 4);
134 if self.are_vertices_without_conflict(first_neighbor, second_neighbor) {
135 if self.color() {
136 return true;
137 }
138 }
139 self.set_edge_color(actual, first_neighbor, 4);
140 self.set_edge_color(actual, second_neighbor, 3);
141 if self.are_vertices_without_conflict(first_neighbor, second_neighbor) {
142 if self.color() {
143 return true;
144 }
145 }
146 self.set_edge_color(actual, first_neighbor, 0);
147 self.set_edge_color(actual, second_neighbor, 0);
148 }
149 7 => {
151 self.set_edge_color(actual, first_neighbor, 5);
152 if self.is_vertex_without_conflict(&self.vertices[first_neighbor]) {
153 if self.color() {
154 return true;
155 }
156 }
157 self.set_edge_color(actual, first_neighbor, 0);
158 }
159 8 => {
160 self.set_edge_color(actual, first_neighbor, 4);
161 if self.is_vertex_without_conflict(&self.vertices[first_neighbor]) {
162 if self.color() {
163 return true;
164 }
165 }
166 self.set_edge_color(actual, first_neighbor, 0);
167 }
168 9 => {
169 self.set_edge_color(actual, first_neighbor, 3);
170 if self.is_vertex_without_conflict(&self.vertices[first_neighbor]) {
171 if self.color() {
172 return true;
173 }
174 }
175 self.set_edge_color(actual, first_neighbor, 0);
176 }
177
178 12 => {
179 if self.color() {
180 return true;
181 }
182 }
183 _ => panic!("unknown color sum: {}", color_sum),
184 }
185
186 self.bfs.back();
187 return false;
188 }
189 true
190 }
191
192 fn set_edge_color(&mut self, from: usize, to: usize, color: usize) {
193 for neighbor in self.vertices[from].iter_mut() {
194 if neighbor.0 == to {
195 neighbor.1 = color;
196 break;
197 }
198 }
199 for neighbor in self.vertices[to].iter_mut() {
200 if neighbor.0 == from {
201 neighbor.1 = color;
202 break;
203 }
204 }
205 }
206
207 fn is_vertex_without_conflict(&self, neighbors: &[(usize, usize); 3]) -> bool {
208 is_without_conflict(neighbors[0].1, neighbors[1].1, neighbors[2].1)
209 }
210
211 fn are_vertices_without_conflict(&self, first: usize, second: usize) -> bool {
212 self.is_vertex_without_conflict(&self.vertices[first])
213 && self.is_vertex_without_conflict(&self.vertices[second])
214 }
215}
216
217fn is_without_conflict(color1: usize, color2: usize, color3: usize) -> bool {
218 if (color1 == color2) && (color1 > 1) {
219 return false;
220 }
221 if (color1 == color3) && (color1 > 1) {
222 return false;
223 }
224 if (color3 == color2) && (color3 > 1) {
225 return false;
226 }
227 return true;
228}