Skip to content

Commit

Permalink
Testing out heuristics
Browse files Browse the repository at this point in the history
  • Loading branch information
LHolten committed Jun 6, 2021
1 parent ba943e5 commit f03ffdc
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 96 deletions.
62 changes: 53 additions & 9 deletions cluster-lib/src/branch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{cmp::min, usize};
use std::usize;

use crate::search::Solver;

Expand All @@ -14,29 +14,73 @@ impl Solver {
// there is at least one conflict
pub fn best_edge(&mut self) -> EdgeMod {
let mut best = EdgeMod::Nothing;
let mut best_cost = i32::MAX;
let mut best_cost = -i32::MAX;

for (i1, v1) in self.graph.all(0) {
for (_, v2) in self.graph.all(i1) {
let e12 = self.graph[v1][v2].weight > 0;
if self.graph[v1][v2].fixed {
continue;
}
// if self.edge_two[v1][v2] == 0 {
// continue;
// }

let cost = self.edge_markers[v1][v2] - self.edge_two[v1][v2];
if cost >= 0 {
continue;
}
// cost += self.graph[v1][v2].weight.abs();
// let cost = self.edge_one[v1][v2] - self.edge_three[v1][v2];

// if cost > best_cost {
// best_cost = cost;
// best = EdgeMod::Cut(v1, v2)
// }

// if -cost > best_cost {
// best_cost = -cost;
// best = EdgeMod::Merge(v1, v2)
// }

if cost < best_cost {
best_cost = cost;
if self.edge_two[v1][v2] > best_cost {
best_cost = self.edge_two[v1][v2];
if e12 {
best = EdgeMod::Cut(v1, v2)
} else {
best = EdgeMod::Merge(v1, v2)
}
}

// let resolved = self.graph[v1][v2].weight.abs() - self.edge_markers[v1][v2];

// let extra_cut;
// let extra_merge;
// if e12 {
// extra_cut = 0;
// extra_merge = self.edge_two[v1][v2];
// } else {
// extra_cut = self.edge_two[v1][v2];
// extra_merge = 0;
// }

// let cost = self.graph[v1][v2].weight.abs()
// - self.edge_markers[v1][v2]
// - self.edge_two[v1][v2];
// if cost >= 0 {
// continue;
// }
// let mut merge_cost = cost;
// let mut cut_cost = cost;
// if e12 {
// merge_cost -= self.edge_three[v1][v2]
// } else {
// cut_cost -= self.edge_one[v1][v2]
// }

// if extra_cut > best_cost {
// best_cost = extra_cut;
// best = EdgeMod::Merge(v1, v2)
// }
// if extra_merge > best_cost {
// best_cost = extra_merge;
// best = EdgeMod::Cut(v1, v2)
// }
}
}
best
Expand Down
20 changes: 13 additions & 7 deletions cluster-lib/src/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,26 @@ pub fn load<F: Read>(file: F) -> io::Result<Graph> {
}
}

graph.add_indirect_edges();
// graph.add_indirect_edges();

Ok(graph)
}

impl Graph {
fn add_indirect_edges(&mut self) {
for vertex1 in self.active.clone() {
for vertex2 in self.active.clone() {
if self[vertex1][vertex2].weight < 0
&& self.two_edges(vertex1, vertex2, 0).count() <= 1
{
self[vertex1][vertex2] = Edge::none()
for v1 in self.active.clone() {
'l: for v2 in self.active.clone() {
if self[v1][v2].weight > 0 {
continue;
}
for (j1, n1) in self.two_edges(v1, v2, 0) {
for (_, n2) in self.two_edges(v1, v2, j1) {
if self[n1][n2].weight > 0 {
continue 'l;
}
}
}
self[v1][v2] = Edge::none()
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion cluster-lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ mod tests {
];
// let instances_hard = vec![17, 39];
let zero = vec![31, 41, 13];
for instance in zero {
let test = vec![35, 47];
for instance in instances {
let time = Instant::now();
let file_name = format!("../exact/exact{:03}.gr", instance);
let graph = load(File::open(&file_name).unwrap()).unwrap();
Expand Down
81 changes: 36 additions & 45 deletions cluster-lib/src/packing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,77 +6,68 @@ impl Solver {
pub fn pack(&mut self) -> i32 {
for (i1, v1) in self.graph.all(0) {
for (_, v2) in self.graph.all(i1) {
self.edge_markers[v1][v2] = 0;
self.edge_markers[v1][v2] = self.graph[v1][v2].weight.abs();
self.edge_one[v1][v2] = 0;
self.edge_two[v1][v2] = 0;
self.edge_three[v1][v2] = 0;
}
}

let mut cost = 0;
let mut max_cost = 0;
for (i1, v1) in self.graph.all(0) {
for (i2, v2) in self.graph.all(i1) {
if self.graph[v1][v2].weight.abs() == self.edge_markers[v1][v2] {
continue;
}

for (_, v3) in self.graph.all(i2) {
let e12 = self.graph[v1][v2].weight > 0;
let e13 = self.graph[v1][v3].weight > 0;
let e23 = self.graph[v2][v3].weight > 0;

// if e12 & e13 & e23 {
// self.edge_three[v1][v3] += minimum;
// self.edge_three[v2][v3] += minimum;
// self.edge_three[v1][v2] += minimum;
// }

// if !(e12 & e13 & e23) & (e12 ^ e13 ^ e23) {
// self.edge_one[v1][v3] += minimum;
// self.edge_one[v2][v3] += minimum;
// self.edge_one[v1][v2] += minimum;
// }

if !(e12 | e13 | e23) || (e12 ^ e13 ^ e23) {
if !(e12 | e13 | e23) | (e12 ^ e13 ^ e23) {
continue;
}
let mut minimum = i32::MAX;
if e12 {
minimum = min(minimum, self.graph[v1][v2].weight)
}
if e13 {
minimum = min(minimum, self.graph[v1][v3].weight)
}
if e23 {
minimum = min(minimum, self.graph[v2][v3].weight)
}

self.edge_two[v1][v3] += minimum;
self.edge_two[v2][v3] += minimum;
self.edge_two[v1][v2] += minimum;

let new_cost = min(
self.graph[v1][v2].weight.abs() - self.edge_markers[v1][v2],
min(
self.graph[v1][v3].weight.abs() - self.edge_markers[v1][v3],
self.graph[v2][v3].weight.abs() - self.edge_markers[v2][v3],
),
self.edge_markers[v1][v2],
min(self.edge_markers[v1][v3], self.edge_markers[v2][v3]),
);
self.edge_markers[v1][v3] += new_cost;
self.edge_markers[v2][v3] += new_cost;
self.edge_markers[v1][v2] += new_cost;
self.edge_markers[v1][v3] -= new_cost;
self.edge_markers[v2][v3] -= new_cost;
self.edge_markers[v1][v2] -= new_cost;
cost += new_cost;
max_cost += minimum;
}
}
}

for (i1, v1) in self.graph.all(0) {
for (i2, v2) in self.graph.all(i1) {
for (_, v3) in self.graph.all(i2) {
let e12 = self.graph[v1][v2].weight > 0;
let e13 = self.graph[v1][v3].weight > 0;
let e23 = self.graph[v2][v3].weight > 0;
let m12 = min(self.edge_markers[v1][v3], self.edge_markers[v2][v3]);
let m13 = min(self.edge_markers[v1][v2], self.edge_markers[v2][v3]);
let m23 = min(self.edge_markers[v1][v2], self.edge_markers[v1][v3]);

if e12 & e13 & e23 {
self.edge_three[v1][v2] += m12;
self.edge_three[v1][v3] += m13;
self.edge_three[v2][v3] += m23;
}

if !(e12 & e13 & e23) & (e12 ^ e13 ^ e23) {
self.edge_one[v1][v2] += m12;
self.edge_one[v1][v3] += m13;
self.edge_one[v2][v3] += m23;
}

if self.graph[v1][v2].weight.abs() == self.edge_markers[v1][v2] {
break;
if (e12 | e13 | e23) & !(e12 ^ e13 ^ e23) {
self.edge_two[v1][v2] += m12;
self.edge_two[v1][v3] += m13;
self.edge_two[v2][v3] += m23;
}
}
}
}

self.max = max_cost;
cost
}
}
105 changes: 71 additions & 34 deletions cluster-lib/src/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub struct Solver {
pub edge_one: Vec<Vec<i32>>,
pub edge_two: Vec<Vec<i32>>,
pub edge_three: Vec<Vec<i32>>,
pub deletion: Vec<Vec<i32>>,
pub max: i32,
}

Expand Down Expand Up @@ -73,48 +74,84 @@ impl Solver {
}

pub fn search_merge(&mut self, v1: usize, v2: usize) {
let (vv1, cost) = self.graph.merge(v1, v2);
debug_assert!(cost > 0);
let (vv, cost) = self.graph.merge(v1, v2);
// debug_assert!(cost > 0);

let lower = self.pack();
if lower + cost < self.upper {
let two = &self.edge_two;
let marker = &self.edge_markers;
self.graph
.active
.sort_unstable_by_key(|&vv2| marker[vv1][vv2] - two[vv1][vv2]);
self.upper -= cost;
// self.merge_one(lower, 0, vv1);
self.merge_one(lower, vv);
// self.search_graph(lower);
self.upper += cost;
}
self.graph.un_merge(v1, v2, vv);
}

pub fn search_merge_2(&mut self, v1: usize, v2: usize) {
let (vv, cost) = self.graph.merge(v1, v2);
let lower = self.pack();
if lower + cost < self.upper {
self.upper -= cost;
self.search_graph(lower);
self.upper += cost;
}
self.graph.un_merge(v1, v2, vv1);
self.graph.un_merge(v1, v2, vv);
}

pub fn merge_one(&mut self, lower: i32, v1: usize) {
let mut best = EdgeMod::Nothing;
let mut best_cost = 0;

for (i1, v2) in self.graph.all(0) {
if v1 == v2 {
for (_, v2) in self.graph.all(i1) {
if self.edge_two[v1][v2] > best_cost {
debug_assert!(!self.graph[v1][v2].fixed);
best_cost = self.edge_two[v1][v2];
if self.graph[v1][v2].weight > 0 {
best = EdgeMod::Cut(v1, v2)
} else {
best = EdgeMod::Merge(v1, v2)
}
}
}
break;
}
let (v1, v2) = (v2, v1);
if self.edge_two[v1][v2] > best_cost {
debug_assert!(!self.graph[v1][v2].fixed);
best_cost = self.edge_two[v1][v2];
if self.graph[v1][v2].weight > 0 {
best = EdgeMod::Cut(v1, v2)
} else {
best = EdgeMod::Merge(v1, v2)
}
}
}

match best {
EdgeMod::Merge(v1, v2) => {
self.search_merge_2(v1, v2);
self.search_cut_2(v1, v2)
}
EdgeMod::Cut(v1, v2) => {
self.search_cut_2(v1, v2);
self.search_merge_2(v1, v2)
}
EdgeMod::Nothing => self.search_graph(lower),
}
}

// pub fn merge_one(&mut self, lower: i32, i1: usize, v1: usize) {
// let first = self.graph.positive(v1, i1).next();
// if let Some((i2, v2)) = first {
// let edge = self.graph.cut(v1, v2);
// let lower = self.pack();
// if lower + max(0, edge.weight) < self.upper {
// self.upper -= max(0, edge.weight);
// self.merge_one(lower, i2, v1);
// self.upper += max(0, edge.weight);
// }
// self.graph.un_cut(v1, v2, edge);

// let (v_merge_2, cost2) = self.graph.merge(v1, v2);
// let lower = self.pack();
// if lower + cost2 < self.upper {
// self.upper -= cost2;
// self.search_graph(lower);
// self.upper += cost2;
// }
// self.graph.un_merge(v1, v2, v_merge_2);
// } else {
// self.search_graph(lower)
// }
// }
pub fn search_cut_2(&mut self, v1: usize, v2: usize) {
let edge = self.graph.cut(v1, v2);
let lower = self.pack();
if lower + max(0, edge.weight) < self.upper {
self.upper -= max(0, edge.weight);
self.merge_one(lower, v1);
self.upper += max(0, edge.weight);
}
self.graph.un_cut(v1, v2, edge);
}

pub fn search_cut(&mut self, v1: usize, v2: usize) {
let edge = self.graph.cut(v1, v2);
Expand All @@ -140,7 +177,7 @@ impl Solver {
EdgeMod::Nothing => {
// println!("{}", upper);
self.best.clone_from(&self.graph);
assert_eq!(lower, self.max);
// assert_eq!(lower, self.max);
// self.best.check_easy();
self.upper = lower
}
Expand Down

0 comments on commit f03ffdc

Please sign in to comment.