use crate::graph::edge::Edge;
use crate::graph::graph::Graph;
use crate::service::colour::colouriser::Colouriser;
#[derive(Debug, Clone)]
pub struct DFSColourizerOriginal {}
struct DFSColourizerOriginalGraph {
graph: Vec<usize>,
neighbors: Vec<[usize; 3]>,
one_edge_vert: Vec<usize>,
non_colored_edges_count: Vec<usize>,
non_colored_edges_of_graph: usize,
graph_size: usize,
}
impl Colouriser for DFSColourizerOriginal {
fn is_colorable<G: Graph>(graph: &G) -> bool {
let graph_matrix = vec![0; graph.size() * graph.size()];
let mut colour_graph = DFSColourizerOriginalGraph {
graph: graph_matrix,
neighbors: vec![[0, 0, 0]; graph.size()],
one_edge_vert: vec![],
non_colored_edges_count: vec![0; graph.size()],
non_colored_edges_of_graph: 0,
graph_size: graph.size(),
};
for edge in graph.edges() {
colour_graph.set_edge_color(edge.from(), edge.to(), 1);
}
let mut first_vertex = 0;
let colours = [3, 4, 5];
let mut vertex_coloured = false;
let mut vertex = 0;
let mut colour_position = 0;
while !vertex_coloured {
for neighbor in 0..graph.size() {
if colour_graph.get_edge_color(vertex, neighbor) == 1 {
colour_graph.set_edge_color(vertex, neighbor, colours[colour_position]);
colour_position += 1;
first_vertex = neighbor;
vertex_coloured = true;
}
}
vertex += 1;
}
colour_graph.non_colored_edges_of_graph = 0;
for vertex in 0..graph.size() {
let mut neighbor_position = 0;
colour_graph.non_colored_edges_count[vertex] = 0;
for neighbor in 0..graph.size() {
if colour_graph.get_edge_color(vertex, neighbor) > 0 {
colour_graph.neighbors[vertex][neighbor_position] = neighbor;
neighbor_position += 1;
if colour_graph.get_edge_color(vertex, neighbor) == 1 {
colour_graph.non_colored_edges_of_graph += 1;
colour_graph.non_colored_edges_count[vertex] += 1;
}
}
}
if neighbor_position < 3 {
colour_graph.neighbors[vertex][neighbor_position] = vertex;
}
neighbor_position += 1;
if neighbor_position < 3 {
colour_graph.neighbors[vertex][neighbor_position] = vertex;
}
}
colour_graph.non_colored_edges_of_graph = colour_graph.non_colored_edges_of_graph / 2;
for vertex in 0..graph.size() {
if colour_graph.non_colored_edges_count[vertex] == 1 {
colour_graph.one_edge_vert.push(vertex);
}
}
colour_graph.color(first_vertex)
}
fn new() -> Self {
Self {}
}
}
impl DFSColourizerOriginal {}
impl DFSColourizerOriginalGraph {
fn color(&mut self, vertex: usize) -> bool {
let color_vars = [(4, 5), (3, 5), (3, 4)];
let mut neighbor1 = 0;
let mut neighbor2 = 0;
let mut colored_sum: usize = 0;
for neighbor in self.neighbors[vertex].iter() {
let color = self.get_edge_color(vertex, *neighbor);
if color == 1 {
neighbor2 = neighbor1;
neighbor1 = *neighbor;
} else {
colored_sum += color;
}
}
match self.non_colored_edges_count[vertex] {
0 => {
if self.non_colored_edges_of_graph == 0 {
return true;
} else {
let mut vert = 0;
while (self.non_colored_edges_count[vert] != 1)
&& (self.non_colored_edges_count[vert] != 2)
{
vert += 1;
}
return self.color(vert);
}
}
1 => {
self.non_colored_edges_of_graph -= 1;
self.non_colored_edges_count[vertex as usize] -= 1;
self.non_colored_edges_count[neighbor1 as usize] -= 1;
let mut change = false;
let next_vertex;
if self.non_colored_edges_count[neighbor1 as usize] == 1
&& !self.one_edge_vert.is_empty()
{
change = true;
next_vertex = self.one_edge_vert.pop().unwrap();
} else {
next_vertex = neighbor1;
}
match colored_sum {
0 => {
if self.set_edge_check_and_color_rest(neighbor1, vertex, 3, next_vertex) {
return true;
}
if self.set_edge_check_and_color_rest(neighbor1, vertex, 4, next_vertex) {
return true;
}
if self.set_edge_check_and_color_rest(neighbor1, vertex, 5, next_vertex) {
return true;
}
}
3 => {
if self.set_edge_check_and_color_rest(neighbor1, vertex, 4, next_vertex) {
return true;
}
if self.set_edge_check_and_color_rest(neighbor1, vertex, 5, next_vertex) {
return true;
}
}
4 => {
if self.set_edge_check_and_color_rest(neighbor1, vertex, 3, next_vertex) {
return true;
}
if self.set_edge_check_and_color_rest(neighbor1, vertex, 5, next_vertex) {
return true;
}
}
5 => {
if self.set_edge_check_and_color_rest(neighbor1, vertex, 3, next_vertex) {
return true;
}
if self.set_edge_check_and_color_rest(neighbor1, vertex, 4, next_vertex) {
return true;
}
}
_ => {
if self.set_edge_check_and_color_rest(
neighbor1,
vertex,
12 - colored_sum,
next_vertex,
) {
return true;
}
}
}
if change {
self.one_edge_vert.push(next_vertex);
}
self.non_colored_edges_of_graph += 1;
self.non_colored_edges_count[vertex as usize] += 1;
self.non_colored_edges_count[neighbor1 as usize] += 1;
self.set_edge_color(vertex, neighbor1, 1);
return false;
}
2 => {
self.non_colored_edges_of_graph -= 2;
self.non_colored_edges_count[vertex as usize] -= 2;
self.non_colored_edges_count[neighbor1 as usize] -= 1;
self.non_colored_edges_count[neighbor2 as usize] -= 1;
let mut one_edge_neighbors = 0;
let mut next_from_queue = false;
let next_vertex;
if self.non_colored_edges_count[neighbor1 as usize] == 1 {
one_edge_neighbors += 1;
self.one_edge_vert.push(neighbor1);
}
if self.non_colored_edges_count[neighbor2 as usize] == 1 {
one_edge_neighbors += 1;
self.one_edge_vert.push(neighbor2);
}
if !self.one_edge_vert.is_empty() {
next_from_queue = true;
next_vertex = self.one_edge_vert.pop().unwrap();
} else {
next_vertex = neighbor1;
}
match colored_sum {
0 => {
for num in 3..6 {
self.set_edge_color(vertex, neighbor1, color_vars[num - 3].0);
self.set_edge_color(vertex, neighbor2, color_vars[num - 3].1);
if self.are_vertices_without_conflict(neighbor1, neighbor2)
&& self.color(next_vertex)
{
return true;
}
self.set_edge_color(vertex, neighbor1, color_vars[num - 3].1);
self.set_edge_color(vertex, neighbor2, color_vars[num - 3].0);
if self.are_vertices_without_conflict(neighbor1, neighbor2)
&& self.color(next_vertex)
{
return true;
}
}
}
_ => {
self.set_edge_color(vertex, neighbor1, color_vars[colored_sum - 3].0);
self.set_edge_color(vertex, neighbor2, color_vars[colored_sum - 3].1);
if self.are_vertices_without_conflict(neighbor1, neighbor2)
&& self.color(next_vertex)
{
return true;
}
self.set_edge_color(vertex, neighbor1, color_vars[colored_sum - 3].1);
self.set_edge_color(vertex, neighbor2, color_vars[colored_sum - 3].0);
if self.are_vertices_without_conflict(neighbor1, neighbor2)
&& self.color(next_vertex)
{
return true;
}
}
}
if one_edge_neighbors == 2 {
self.one_edge_vert.pop();
}
if next_from_queue && one_edge_neighbors == 0 {
self.one_edge_vert.push(next_vertex);
}
self.non_colored_edges_of_graph += 2;
self.non_colored_edges_count[vertex as usize] += 2;
self.non_colored_edges_count[neighbor1 as usize] += 1;
self.non_colored_edges_count[neighbor2 as usize] += 1;
self.set_edge_color(vertex, neighbor1, 1);
self.set_edge_color(vertex, neighbor2, 1);
return false;
}
_ => {
panic!("More than 2 uncolored edges");
}
}
}
fn set_edge_color(&mut self, from: usize, to: usize, color: usize) {
self.graph[from * self.graph_size + to] = color;
self.graph[to * self.graph_size + from] = color;
}
fn get_edge_color(&self, from: usize, to: usize) -> usize {
self.graph[from * self.graph_size + to]
}
fn is_vertex_without_conflict(&self, vertex: usize, neighbors: &[usize; 3]) -> bool {
is_without_conflict(
self.get_edge_color(vertex, neighbors[0]),
self.get_edge_color(vertex, neighbors[1]),
self.get_edge_color(vertex, neighbors[2]),
)
}
fn set_color_and_check_validity(&mut self, from: usize, to: usize, color: usize) -> bool {
self.set_edge_color(from, to, color);
self.is_vertex_without_conflict(from, &self.neighbors[from])
}
fn are_vertices_without_conflict(&self, first: usize, second: usize) -> bool {
self.is_vertex_without_conflict(first, &self.neighbors[first])
&& self.is_vertex_without_conflict(second, &self.neighbors[second])
}
fn set_edge_check_and_color_rest(
&mut self,
from: usize,
to: usize,
color: usize,
next_vertex: usize,
) -> bool {
self.set_color_and_check_validity(from, to, color) && self.color(next_vertex)
}
}
fn is_without_conflict(color1: usize, color2: usize, color3: usize) -> bool {
if (color1 == color2) && (color1 > 1) {
return false;
}
if (color1 == color3) && (color1 > 1) {
return false;
}
if (color3 == color2) && (color3 > 1) {
return false;
}
return true;
}