pub mod add_subgraph_constraints;
pub mod barycenter;
pub mod build_layer_graph;
pub mod cross_count;
pub mod init_order;
pub mod resolve_conflicts;
pub mod sort;
pub mod sort_subgraph;
use self::add_subgraph_constraints::add_subgraph_constraints;
use self::build_layer_graph::build_layer_graph;
use self::cross_count::cross_count;
use self::init_order::init_order;
use self::sort_subgraph::sort_subgraph;
use crate::graph::{EdgeLabel, Graph};
use crate::util::{build_layer_matrix, max_rank, range};
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct OrderConstraint {
pub left: String,
pub right: String,
}
pub fn order(graph: &mut Graph, constraints: &[OrderConstraint], disable_optimal: bool) {
let mr = max_rank(graph);
let down_ranks = range(1, Some(mr + 1), None);
let up_ranks = range(mr - 1, Some(-1), Some(-1));
let mut layering = init_order(graph);
assign_order(graph, &layering);
if disable_optimal {
return;
}
let mut best_cc = f64::INFINITY;
let mut best: Vec<Vec<String>> = layering.clone();
let mut last_best = 0usize;
let mut i = 0usize;
while last_best < 4 {
let (ranks, relationship): (&[i32], &str) = if i % 2 == 1 {
(&down_ranks, "inEdges")
} else {
(&up_ranks, "outEdges")
};
let bias_right = i % 4 >= 2;
sweep_layer_graphs_fresh(graph, ranks, relationship, bias_right, constraints);
layering = build_layer_matrix(graph);
let cc = cross_count(graph, &layering);
if cc < best_cc {
last_best = 0;
best = layering.clone();
best_cc = cc;
}
i += 1;
last_best += 1;
}
assign_order(graph, &best);
}
fn build_nodes_by_rank(graph: &Graph) -> HashMap<i32, Vec<String>> {
let mut nodes_by_rank: HashMap<i32, Vec<String>> = HashMap::new();
for v in graph.nodes() {
let node = graph.node(&v);
if let Some(rank) = node.rank {
nodes_by_rank.entry(rank).or_default().push(v.clone());
}
if let (Some(min_r), Some(max_r)) = (node.min_rank, node.max_rank) {
for r in min_r..=max_r {
if node.rank != Some(r) {
nodes_by_rank.entry(r).or_default().push(v.clone());
}
}
}
}
nodes_by_rank
}
fn sweep_layer_graphs_fresh(
main_graph: &mut Graph,
ranks: &[i32],
relationship: &str,
bias_right: bool,
constraints: &[OrderConstraint],
) {
let mut cg = Graph::with_options(true, false, false);
let nodes_by_rank = build_nodes_by_rank(main_graph);
for &rank in ranks {
for con in constraints {
cg.set_edge(&con.left, &con.right, EdgeLabel::default(), None);
}
let nodes = nodes_by_rank.get(&rank).cloned().unwrap_or_default();
let lg = build_layer_graph(main_graph, rank, relationship, &nodes);
let root = lg.graph().root.clone().expect("layer graph must have root");
let sorted = sort_subgraph(&lg, &root, &cg, bias_right);
for (i, v) in sorted.vs.iter().enumerate() {
if lg.has_node(v) {
if let Some(node) = main_graph.node_opt_mut(v) {
node.order = Some(i as i32);
}
}
}
add_subgraph_constraints(&lg, &mut cg, &sorted.vs);
}
}
fn assign_order(graph: &mut Graph, layering: &[Vec<String>]) {
for layer in layering {
for (i, v) in layer.iter().enumerate() {
if let Some(node) = graph.node_opt_mut(v) {
node.order = Some(i as i32);
}
}
}
}