From 1fae5ee6f46fbcbb6839a5211d9447e32078f386 Mon Sep 17 00:00:00 2001 From: codeboss <2422523675@qq.com> Date: Sun, 13 Oct 2024 22:48:01 +0800 Subject: [PATCH] 1 --- StoryPresent/dag_layout.cpp | 162 +++++++++++++++++++++++++++++++----- StoryPresent/dag_layout.h | 8 +- 2 files changed, 149 insertions(+), 21 deletions(-) diff --git a/StoryPresent/dag_layout.cpp b/StoryPresent/dag_layout.cpp index 514445f..3856894 100644 --- a/StoryPresent/dag_layout.cpp +++ b/StoryPresent/dag_layout.cpp @@ -228,11 +228,12 @@ QList> DAGGraph::tidy_graph_nodes() { #include void dags::DAGGraph::graph_layout_layers_forward(const QList>& nodes) { for (auto layer_index = 0; layer_index < maxLayerCount(); ++layer_index) { - this->nodes_sort_forward_within_layer(layer_index, nodes); + auto nodes_within_current_layer = this->nodes_sort_forward_within_layer(layer_index, nodes); + this->current_nodelist_filling_indi(nodes_within_current_layer); this->nodes_sort_with_above(layer_index, nodes); } } -void DAGGraph::nodes_sort_forward_within_layer(int layer_index, const QList>& nodes) { +QList> DAGGraph::nodes_sort_forward_within_layer(int layer_index, const QList>& nodes) { QList> nodes_within_current_layer; std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(nodes_within_current_layer), [=](std::shared_ptr ins) { return ins->layerNumber() == layer_index; }); @@ -277,14 +278,15 @@ void DAGGraph::nodes_sort_forward_within_layer(int layer_index, const QList a, std::shared_ptr b) { return a->sortNumber() < b->sortNumber(); }); - - // 提取当前层次节点排序值 - this->current_nodelist_filling_indi(nodes_within_current_layer); } } + + return nodes_within_current_layer; } bool dags::DAGGraph::current_nodelist_filling_indi(const QList>& nodes_within_current_layer) { + if(!nodes_within_current_layer.size()) + return false; // 提取节点划分档次 QList ordered_values; @@ -295,9 +297,6 @@ bool dags::DAGGraph::current_nodelist_filling_indi(const QList> dags::DAGGraph::layer_adjust_via_next_sib std::sort(curr_layer_nodes.begin(), curr_layer_nodes.end(), [](std::shared_ptra, std::shared_ptr b)->bool { - auto prevs_a = a->getUpstreamNodes(); - auto prevs_b = b->getUpstreamNodes(); + auto prevs_a = a->getUpstreamNodes(); + auto prevs_b = b->getUpstreamNodes(); - if (!prevs_a.size() && !prevs_b.size()) - return a > b; - if (!prevs_a.size()) - return true; - if (!prevs_b.size()) - return false; + if (!prevs_a.size() && !prevs_b.size()) + return a > b; + if (!prevs_a.size()) + return true; + if (!prevs_b.size()) + return false; auto upnode_a = std::min_element(prevs_a.begin(), prevs_a.end(), [](std::shared_ptr a, std::shared_ptr b) { return a->sortNumber() < b->sortNumber(); }); auto upnode_b = std::min_element(prevs_b.begin(), prevs_b.end(), [](std::shared_ptr a, std::shared_ptr b) { return a->sortNumber() < b->sortNumber(); }); - return (*upnode_a)->sortNumber() < (*upnode_b)->sortNumber(); - }); + return (*upnode_a)->sortNumber() < (*upnode_b)->sortNumber(); + }); return curr_layer_nodes; } @@ -435,6 +434,131 @@ void dags::DAGGraph::node_adjust_via_next_sibling(std::shared_ptr>& total_nodes) +{ + int layer_index = 0; + while (this->nodes_revise_springs_within_layer(layer_index, total_nodes)) { + layer_index++; + } +} + +bool dags::DAGGraph::nodes_revise_springs_within_layer(int layer_index, const QList>& total_nodes) +{ + QList> nodes_within_current_layer; + std::copy_if(total_nodes.begin(), total_nodes.end(), std::back_inserter(nodes_within_current_layer), + [=](std::shared_ptr ins) { return ins->layerNumber() == layer_index; }); + std::sort(nodes_within_current_layer.begin(), nodes_within_current_layer.end(), + [](std::shared_ptr a, std::shared_ptr b) { + return a->sortNumber() < b->sortNumber(); + }); + + if (!nodes_within_current_layer.size()) + return false; + + QList, double>> nodes_with_force; + std::transform(nodes_within_current_layer.begin(), nodes_within_current_layer.end(), + std::back_inserter(nodes_with_force), [&](std::shared_ptr ins) { + return std::make_tuple(ins, this->node_evaluate_with_siblings(ins, total_nodes)); + }); + + while (nodes_with_force.size()) { + auto min_it = std::min_element(nodes_with_force.begin(), nodes_with_force.end(), + [](std::tuple, double> a, std::tuple, double> b) { + return std::get<1>(a) < std::get<1>(b); + }); + + auto min_elm = *min_it; + if(std::abs(std::get<1>(min_elm) > 1)){ + auto vinst = std::get<0>(min_elm); + auto prev_sort = vinst->sortNumber().toInt(); + auto target_index = (int) std::get<1>(min_elm) + prev_sort; + + QList> adjust_items; + if (std::get<1>(min_elm) > 0) { + std::copy_if(nodes_within_current_layer.begin(), nodes_within_current_layer.end(), + std::back_inserter(adjust_items), [=](std::shared_ptr ins) { + return ins->sortNumber().toInt() <= target_index; + }); + + adjust_items.removeAll(vinst); + if (adjust_items.size()) { + // 置位调整 + vinst->setSortNumber(target_index); + // 其余调整 + for (auto nde : adjust_items) { + if (nde->sortNumber().toInt() == target_index) { + nde->setSortNumber(--target_index); + } + } + } + } + else if (std::get<1>(min_elm) < 0) { + std::copy_if(nodes_within_current_layer.begin(), nodes_within_current_layer.end(), + std::back_inserter(adjust_items), [=](std::shared_ptr ins) { + return ins->sortNumber().toInt() >= target_index; + }); + + adjust_items.removeAll(vinst); + if (adjust_items.size()) { + // 置位调整 + vinst->setSortNumber(target_index); + // 其余调整 + for (auto nde : adjust_items) { + if (nde->sortNumber().toInt() == target_index) { + nde->setSortNumber(++target_index); + } + } + } + } + + if (!adjust_items.size()) { + vinst->setSortNumber(target_index); + } + } + nodes_with_force.erase(min_it); + } + + return true; +} + +double dags::DAGGraph::node_evaluate_with_siblings(std::shared_ptr node, const QList>& total_nodes) +{ + // 没有上级节点 + if (!node->getUpstreamNodes().size()) { + auto next_layer_nodes = node->layerNode()->nextNodes(); + + QList> next_gnodes; + std::copy_if(total_nodes.begin(), total_nodes.end(), std::back_inserter(next_gnodes), + [&](std::shared_ptr ins) { + auto layer_bool = ins->layerNumber() == node->layerNumber() + 1; + auto type_bool = ins->isFakeNode(); + return layer_bool && !type_bool && next_layer_nodes.contains(ins->layerNode()); + }); + + if (!next_gnodes.size()) + return 0; + + auto min_eit = std::min_element(next_gnodes.begin(), next_gnodes.end(), + [](std::shared_ptr a, std::shared_ptr b) { + return a->sortNumber() < b->sortNumber(); + }); + + auto target_index = (*min_eit)->sortNumber().toInt(); + return target_index - node->sortNumber().toInt(); + } + // 拥有上级节点 + else { + auto prev_gnodes = node->getUpstreamNodes(); + auto force_sum = 0.0; + for (auto nde : prev_gnodes) { + force_sum += nde->sortNumber().toDouble() - node->sortNumber().toDouble(); + } + return force_sum / prev_gnodes.size(); + } + + return 0.0; +} + void dags::DAGGraph::nodes_sort_with_belows(int curr_layer, const QList>& total_nodes) { // 提取所有已知节点 QList> sorting_nodes; @@ -503,7 +627,7 @@ void dags::DAGGraph::backwardsLayoutImpls() { } void dags::DAGGraph::adjustLayoutImpls() { - + //this->graph_revise_layers_forward(this->node_with_layout); } diff --git a/StoryPresent/dag_layout.h b/StoryPresent/dag_layout.h index 413a0fd..2b29a09 100644 --- a/StoryPresent/dag_layout.h +++ b/StoryPresent/dag_layout.h @@ -92,16 +92,20 @@ namespace dags { QList> tidy_graph_nodes(); void graph_layout_layers_forward(const QList>& total_nodes); - void nodes_sort_forward_within_layer(int layer_index, const QList> &nodes); + QList> nodes_sort_forward_within_layer(int layer_index, const QList> &nodes); void graph_adjust_layers_backward(const QList>& total_nodes); QList> layer_adjust_via_next_sibling(int curr_layer, const QList>& total_nodes); void node_adjust_via_next_sibling(std::shared_ptr curr_node, const QList>& total_nodes); + void graph_revise_layers_forward(const QList>& total_nodes); + bool nodes_revise_springs_within_layer(int layer_index, const QList>& nodes); + double node_evaluate_with_siblings(std::shared_ptr node, const QList>& nodes); + + bool current_nodelist_filling_indi(const QList>& ordered_nodes); void nodes_sort_with_above(int curr_layer, const QList>& total_nodes); void nodes_sort_with_belows(int curr_layer, const QList>& total_nodes); - }; }