///|
pub fn order_run(g : Graph) -> Unit {
let max_rank_value = max_rank(g)
let down_layer_graphs = order_build_layer_graphs(
g,
range(1, limit=max_rank_value + 1),
"in_edges",
)
let up_layer_graphs = order_build_layer_graphs(
g,
range(max_rank_value - 1, limit=-1, step=-1),
"out_edges",
)
let mut layering = order_init_order(g)
order_assign_order(g, layering)
let mut best_cc = 999_999_999_999_999_999.0
let mut best = order_copy_layering(layering)
let mut i = 0
let mut last_best = 0
while last_best < 4 {
let layer_graphs = if i % 2 == 1 {
down_layer_graphs
} else {
up_layer_graphs
}
order_sweep_layer_graphs(layer_graphs, i % 4 >= 2)
layering = build_layer_matrix(g)
let cc = order_cross_count(g, layering)
if cc < best_cc {
last_best = 0
best = order_copy_layering(layering)
best_cc = cc
}
i = i + 1
last_best = last_best + 1
}
order_assign_order(g, best)
}
///|
fn order_build_layer_graphs(
g : Graph,
ranks : Array[Int],
relationship : String,
) -> Array[Graph] {
let out : Array[Graph] = []
for rank in ranks {
out.push(order_build_layer_graph(g, rank, relationship))
}
out
}
///|
fn order_sweep_layer_graphs(
layer_graphs : Array[Graph],
bias_right : Bool,
) -> Unit {
let cg = Graph::new()
for lg in layer_graphs {
let root = lg.graph().get_string_or("root", "")
let sorted = order_sort_subgraph(lg, root, cg, bias_right~)
for i = 0; i < sorted.vs.length(); i = i + 1 {
lg.node(sorted.vs[i]).set_int("order", i)
}
order_add_subgraph_constraints(lg, cg, sorted.vs)
}
}
///|
fn order_assign_order(g : Graph, layering : Array[Array[String]]) -> Unit {
for layer in layering {
for i = 0; i < layer.length(); i = i + 1 {
let v = layer[i]
if v == "" {
continue
}
g.node(v).set_int("order", i)
}
}
}
///|
fn order_copy_layering(layering : Array[Array[String]]) -> Array[Array[String]] {
layering.map(layer => layer.copy())
}