WsParser_VS/StoryPresent/dag_layout.cpp

754 lines
25 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "dag_layout.h"
using namespace dags;
using namespace graph_data;
DAGLayerHelper::DAGLayerHelper(const Node& bind)
: bind_node(bind) {
}
Node DAGLayerHelper::bindPoint() const {
return this->bind_node;
}
int& dags::DAGLayerHelper::inputCount() {
return this->input_count;
}
int dags::DAGLayerHelper::layerValue() const {
return this->layer_v;
}
void dags::DAGLayerHelper::setLayerValue(int v) {
this->layer_v = v;
}
void DAGLayerHelper::nextAppend(std::shared_ptr<DAGLayerHelper> inst) {
if (this->next_points.contains(inst))
return;
this->next_points.append(inst);
inst->input_count++;
}
QList<std::shared_ptr<DAGLayerHelper>> DAGLayerHelper::nextNodes() const {
return this->next_points;
}
DAGOrderHelper::DAGOrderHelper(std::shared_ptr<DAGLayerHelper> bind) : layer_bind(bind) {
this->layer_number = bind->layerValue();
}
DAGOrderHelper::DAGOrderHelper(std::shared_ptr<DAGLayerHelper> f, std::shared_ptr<DAGLayerHelper> t)
: relate_bind(f), towards_to(t) {
}
bool DAGOrderHelper::isFakeNode() const {
return !this->layer_bind;
}
std::shared_ptr<DAGLayerHelper> dags::DAGOrderHelper::layerNode() const {
return this->layer_bind;
}
std::shared_ptr<DAGLayerHelper> dags::DAGOrderHelper::tailsNode() const {
return this->relate_bind;
}
std::shared_ptr<DAGLayerHelper> dags::DAGOrderHelper::headsNode() const {
return this->towards_to;
}
int dags::DAGOrderHelper::layerNumber() const {
return this->layer_number;
}
void dags::DAGOrderHelper::setLayerNumber(int v) {
this->layer_number = v;
}
QVariant dags::DAGOrderHelper::sortNumber() const {
return this->sort_number;
}
void dags::DAGOrderHelper::setSortNumber(double v) {
this->sort_number = v;
}
QList<std::shared_ptr<DAGOrderHelper>> DAGOrderHelper::getUpstreamNodes() const {
return this->__prev_layer_nodes;
}
void DAGOrderHelper::appendUpstreamNode(std::shared_ptr<DAGOrderHelper> inst) {
this->__prev_layer_nodes.append(inst);
}
void DAGGraph::rebuildFromEdges(const QList<Arrow>& arrow_list) {
for (auto& arr : arrow_list) {
auto start = arr.startPoint();
std::shared_ptr<DAGLayerHelper> start_helper;
if (this->graph_inst.contains(start.name())) {
start_helper = this->graph_inst[start.name()];
}
else {
start_helper = std::make_shared<DAGLayerHelper>(start);
this->graph_inst[start.name()] = start_helper;
}
auto end = arr.endPoint();
std::shared_ptr< DAGLayerHelper> end_helper;
if (this->graph_inst.contains(end.name())) {
end_helper = this->graph_inst[end.name()];
}
else {
end_helper = std::make_shared<DAGLayerHelper>(end);
this->graph_inst[end.name()] = end_helper;
}
start_helper->nextAppend(end_helper);
}
}
QList<std::shared_ptr<DAGOrderHelper>> dags::DAGGraph::nodeWithLayout() const {
return this->node_with_layout;
}
int dags::DAGGraph::maxLayerCount() const {
return this->max_layer_count;
}
std::shared_ptr<DAGLayerHelper> DAGGraph::spawns_peak(QList<std::shared_ptr<DAGLayerHelper>>& ref_set) {
for (auto inst : ref_set) {
if (!inst->inputCount()) {
for (auto it_nxt : inst->nextNodes()) {
it_nxt->inputCount()--;
if (!ref_set.contains(it_nxt))
ref_set << it_nxt;
}
ref_set.removeAll(inst);
this->graph_inst.remove(inst->bindPoint().name());
return inst;
}
}
for (auto inst : this->graph_inst.values()) {
if (!inst->inputCount()) {
if (ref_set.contains(inst))
ref_set.removeAll(inst);
for (auto it_nxt : inst->nextNodes()) {
it_nxt->inputCount()--;
if (!ref_set.contains(it_nxt))
ref_set << it_nxt;
}
this->graph_inst.remove(inst->bindPoint().name());
return inst;
}
}
if (this->graph_inst.size()) {
throw "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޻<EFBFBD>ͼ<EFBFBD>з<EFBFBD><EFBFBD>ֻ<EFBFBD><EFBFBD>λ<EFBFBD>·<EFBFBD><EFBFBD>";
}
return std::shared_ptr<DAGLayerHelper>();
}
void DAGGraph::graph_recovery(const QList<std::shared_ptr<DAGLayerHelper>>& sort_seqs) {
for (auto it : sort_seqs) {
it->inputCount() = 0;
}
for (auto it : sort_seqs) {
for (auto nxt : it->nextNodes()) {
nxt->inputCount()++;
}
}
this->graph_inst.clear();
for (auto it : sort_seqs) {
this->graph_inst[it->bindPoint().name()] = it;
}
}
int DAGGraph::node_layering(const std::shared_ptr<DAGLayerHelper>& inst, int layer_current) {
auto max_remains = layer_current;
if (!layer_current || inst->layerValue() < layer_current) {
inst->setLayerValue(layer_current);
for (auto fork : inst->nextNodes()) {
max_remains = std::max(this->node_layering(fork, inst->layerValue() + 1), max_remains);
}
}
return max_remains + 1;
}
int DAGGraph::node_layering_adj(std::shared_ptr<DAGLayerHelper> inst) {
if (inst->inputCount() > 1)
return inst->layerValue() - 1;
if (!inst->nextNodes().size())
return inst->layerValue() - 1;
auto layer_number = INT_MAX;
for (auto cinst : inst->nextNodes()) {
layer_number = std::min(layer_number, this->node_layering_adj(cinst));
}
inst->setLayerValue(layer_number);
return inst->layerValue() - 1;
}
QList<std::shared_ptr<DAGOrderHelper>> DAGGraph::tidy_graph_nodes() {
QHash<QString, std::shared_ptr<DAGOrderHelper>> nodes_temp;
for (auto node : this->graph_inst.values()) {
nodes_temp[node->bindPoint().name()] = std::make_shared<DAGOrderHelper>(node);
}
QList<std::shared_ptr<DAGOrderHelper>> temp_array(nodes_temp.values());
for (auto node : this->graph_inst.values()) {
for (auto next : node->nextNodes()) {
auto node_links = QList<std::shared_ptr<DAGOrderHelper>>{
nodes_temp[node->bindPoint().name()]
};
for (auto layer_index = node->layerValue() + 1; layer_index < next->layerValue(); ++layer_index) {
node_links.append(std::make_shared<DAGOrderHelper>(node, next));
node_links.last()->setLayerNumber(layer_index);
}
node_links.append(nodes_temp[next->bindPoint().name()]);
for (auto idx = 1; idx < node_links.size(); ++idx) {
auto start_point = node_links[idx - 1];
auto end_point = node_links[idx];
end_point->appendUpstreamNode(start_point);
}
temp_array.append(node_links.mid(1, node_links.size() - 2));
}
}
return temp_array;
}
#include <QDebug>
void DAGGraph::graph_layer_nodes_sort_forward(int layer_index, const QList<std::shared_ptr<DAGOrderHelper>>& nodes) {
QList<std::shared_ptr<DAGOrderHelper>> nodes_within_current_layer;
std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(nodes_within_current_layer),
[=](std::shared_ptr<DAGOrderHelper> ins) { return ins->layerNumber() == layer_index; });
if (nodes_within_current_layer.size()) {
// <20><><EFBFBD>㵱ǰ<E3B5B1><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>нڵ<D0BD><DAB5><EFBFBD><EFBFBD><EFBFBD>
if (!layer_index) {
for (auto idx = 0; idx < nodes_within_current_layer.size(); ++idx) {
auto target_node = nodes_within_current_layer[idx];
if (target_node->sortNumber().isNull())
target_node->setSortNumber(idx + 1);
}
}
else if (layer_index > 0) {
QList<std::shared_ptr<DAGOrderHelper>> nodes_fixed;
for (auto target_node : nodes_within_current_layer) {
auto upstream_list = target_node->getUpstreamNodes();
std::sort(upstream_list.begin(), upstream_list.end(),
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) { return a->sortNumber() < b->sortNumber(); });
if (upstream_list.size()) {
auto sort_anchor = upstream_list[(upstream_list.size() - 1) / 2];
target_node->setSortNumber(sort_anchor->sortNumber().toInt());
nodes_fixed << sort_anchor;
}
}
QList<std::shared_ptr<DAGOrderHelper>> nodes_hangout;
std::copy_if(nodes_within_current_layer.begin(), nodes_within_current_layer.end(),
std::back_inserter(nodes_hangout), [](std::shared_ptr<DAGOrderHelper> ins) {
return ins->sortNumber().isNull();
});
if (nodes_hangout.size()) {
auto min_anchor = std::min_element(nodes_fixed.begin(), nodes_fixed.end(),
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) { return a->sortNumber() < b->sortNumber(); });
for (int idx = 0; idx < nodes_hangout.size(); ++idx) {
nodes_hangout[idx]->setSortNumber((*min_anchor)->sortNumber().toInt() - idx - 1);
}
}
std::sort(nodes_within_current_layer.begin(), nodes_within_current_layer.end(),
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) {
return a->sortNumber() < b->sortNumber();
});
// <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0><EFBFBD>νڵ<CEBD><DAB5><EFBFBD><EFBFBD><EFBFBD>ֵ
this->current_nodelist_filling_indi(nodes_within_current_layer);
}
this->nodes_sort_with_above(layer_index, nodes);
this->graph_layer_nodes_sort_forward(layer_index + 1, nodes);
}
}
/*
bool dags::DAGGraph::current_layer_filling_indi(int layer_index, const QList<std::shared_ptr<DAGOrderHelper>>& nodes)
{
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>νڵ<CEBD>
QList<std::shared_ptr<DAGOrderHelper>> nodes_within_current_layer;
std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(nodes_within_current_layer),
[=](std::shared_ptr<DAGOrderHelper> ins) { return ins->layerNumber() == layer_index; });
if (!nodes_within_current_layer.size())
return false;
std::sort(nodes_within_current_layer.begin(), nodes_within_current_layer.end(),
[](std::shared_ptr<DAGOrderHelper>a, std::shared_ptr<DAGOrderHelper> b)->bool {
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;
auto upnode_a = std::min_element(prevs_a.begin(), prevs_a.end(),
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) { return a->sortNumber() < b->sortNumber(); });
auto upnode_b = std::min_element(prevs_b.begin(), prevs_b.end(),
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) { return a->sortNumber() < b->sortNumber(); });
return (*upnode_a)->sortNumber() < (*upnode_b)->sortNumber();
});
this->current_nodelist_filling_indi(nodes_within_current_layer);
}
*/
bool dags::DAGGraph::current_nodelist_filling_indi(const QList<std::shared_ptr<DAGOrderHelper>>& nodes_within_current_layer)
{
// <20><>ȡ<EFBFBD>ڵ㻮<DAB5>ֵ<EFBFBD><D6B5><EFBFBD>
QList<int> ordered_values;
std::transform(nodes_within_current_layer.begin(), nodes_within_current_layer.end(),
std::back_inserter(ordered_values), [=](std::shared_ptr<DAGOrderHelper> ins) {
return ins->sortNumber().toInt();
});
ordered_values = ordered_values.toSet().toList();
std::sort(ordered_values.begin(), ordered_values.end());
if (ordered_values.size() == nodes_within_current_layer.size())
return false;
// <20><><EFBFBD><EFBFBD>
ordered_values << ordered_values.last() + 1;
for (auto idx = 1; idx < ordered_values.size(); ++idx) {
auto prev_sortv = ordered_values[idx - 1];
auto curr_sortv = ordered_values[idx];
QList<std::shared_ptr<DAGOrderHelper>> pick_ups;
std::copy_if(nodes_within_current_layer.begin(), nodes_within_current_layer.end(), std::back_inserter(pick_ups),
[=](std::shared_ptr<DAGOrderHelper> ins) { return ins->sortNumber() >= prev_sortv && ins->sortNumber() < curr_sortv; });
for (int idx = 0; idx < std::min(curr_sortv - prev_sortv, pick_ups.size()); idx++) {
auto target_node = pick_ups[idx];
target_node->setSortNumber(prev_sortv + idx);
}
if (curr_sortv - prev_sortv < pick_ups.size()) {
auto npicks = pick_ups.mid(curr_sortv - prev_sortv);
auto inc_span = 1.0 / (npicks.size() + 4);
for (auto idx = 0; idx < npicks.size(); ++idx) {
auto nsortv = curr_sortv - 1 + (idx + 1) * inc_span;
npicks[idx]->setSortNumber(nsortv);
}
}
}
return true;
}
void dags::DAGGraph::nodes_sort_with_above(int layer_index, const QList<std::shared_ptr<DAGOrderHelper>>& nodes)
{
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪<EFBFBD>ڵ<EFBFBD>
QList<std::shared_ptr<DAGOrderHelper>> sorting_nodes;
std::copy_if(nodes.begin(), nodes.end(), std::back_inserter(sorting_nodes),
[&](std::shared_ptr<DAGOrderHelper> n) { return n->layerNumber() <= layer_index; });
// <20><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
QList<double> sort_values;
std::transform(sorting_nodes.begin(), sorting_nodes.end(), std::back_inserter(sort_values),
[](std::shared_ptr<DAGOrderHelper> n)->double { return n->sortNumber().toDouble(); });
sort_values = sort_values.toSet().toList();
std::sort(sort_values.begin(), sort_values.end());
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
auto temp_anchor = std::make_pair<double, int>(DBL_MAX, -1);
for (int nidx = 0; nidx < sort_values.size(); ++nidx) {
auto value_span = std::abs(sort_values[nidx]);
if (value_span <= temp_anchor.first)
temp_anchor = std::make_pair(value_span, nidx);
}
// <20><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>
for (int sorting_idx = 0; sorting_idx < sorting_nodes.size(); ++sorting_idx) {
auto node = sorting_nodes[sorting_idx];
auto node_sortv = node->sortNumber().toDouble();
auto sort_idx = sort_values.indexOf(node_sortv);
node->setSortNumber(sort_idx - temp_anchor.second);
}
//for (auto n : sorting_nodes) {
// qDebug() << n->layerNumber() << n->sortNumber().toDouble();
//}
//qDebug() << "==============================";
}
void dags::DAGGraph::graph_adjust_after_layout(const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes)
{
auto layer_index = this->maxLayerCount() - 1;
while (layer_index > -1) {
auto nlist = this->layer_adjust_via_next_sibling(layer_index, total_nodes);
if (this->current_nodelist_filling_indi(nlist))
this->nodes_sort_with_belows(layer_index, total_nodes);
layer_index--;
};
}
QList<std::shared_ptr<DAGOrderHelper>> dags::DAGGraph::layer_adjust_via_next_sibling(int curr_layer, const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes)
{
QList<std::shared_ptr<DAGOrderHelper>> curr_layer_nodes;
std::copy_if(total_nodes.begin(), total_nodes.end(), std::back_inserter(curr_layer_nodes),
[&](std::shared_ptr<DAGOrderHelper> inst) { return inst->layerNumber() == curr_layer; });
for (auto node : curr_layer_nodes) {
this->node_adjust_via_next_sibling(node, total_nodes);
}
std::sort(curr_layer_nodes.begin(), curr_layer_nodes.end(),
[](std::shared_ptr<DAGOrderHelper>a, std::shared_ptr<DAGOrderHelper> b)->bool {
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;
auto upnode_a = std::min_element(prevs_a.begin(), prevs_a.end(),
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) { return a->sortNumber() < b->sortNumber(); });
auto upnode_b = std::min_element(prevs_b.begin(), prevs_b.end(),
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) { return a->sortNumber() < b->sortNumber(); });
return (*upnode_a)->sortNumber() < (*upnode_b)->sortNumber();
});
return curr_layer_nodes;
}
void dags::DAGGraph::node_adjust_via_next_sibling(std::shared_ptr<DAGOrderHelper> curr_node, const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD><CEB5><EFBFBD><EFBFBD>ο<EFBFBD><CEBF>ڵ<EFBFBD>
QList<std::shared_ptr<DAGOrderHelper>> next_layer_nodes;
std::copy_if(total_nodes.begin(), total_nodes.end(), std::back_inserter(next_layer_nodes),
[&](std::shared_ptr<DAGOrderHelper> inst) {
if (inst->layerNumber() == curr_node->layerNumber() + 1) {
if (curr_node->isFakeNode()) {
if (inst->isFakeNode()) {
return curr_node->tailsNode() == inst->tailsNode() && curr_node->headsNode() == inst->headsNode();
}
return curr_node->headsNode() == inst->layerNode();
}
else {
if (inst->isFakeNode()) {
return curr_node->layerNode() == inst->tailsNode();
}
else {
auto next_vnodes = curr_node->layerNode()->nextNodes();
return next_vnodes.contains(inst->layerNode());
}
}
}
return false;
});
std::sort(next_layer_nodes.begin(), next_layer_nodes.end(),
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) {
return a->sortNumber() < b->sortNumber();
});
if (next_layer_nodes.size()) {
curr_node->setSortNumber(next_layer_nodes.first()->sortNumber().toDouble());
}
}
void dags::DAGGraph::nodes_sort_with_belows(int curr_layer, const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes)
{
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪<EFBFBD>ڵ<EFBFBD>
QList<std::shared_ptr<DAGOrderHelper>> sorting_nodes;
std::copy_if(total_nodes.begin(), total_nodes.end(), std::back_inserter(sorting_nodes),
[=](std::shared_ptr<DAGOrderHelper> ins) { return ins->layerNumber() >= curr_layer; });
// <20><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
QList<double> sort_values;
std::transform(sorting_nodes.begin(), sorting_nodes.end(), std::back_inserter(sort_values),
[](std::shared_ptr<DAGOrderHelper> n)->double { return n->sortNumber().toDouble(); });
sort_values = sort_values.toSet().toList();
std::sort(sort_values.begin(), sort_values.end());
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
auto temp_anchor = std::make_pair<double, int>(DBL_MAX, -1);
for (int nidx = 0; nidx < sort_values.size(); ++nidx) {
auto value_span = std::abs(sort_values[nidx]);
if (value_span <= temp_anchor.first)
temp_anchor = std::make_pair(value_span, nidx);
}
// <20><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>
for (int sorting_idx = 0; sorting_idx < sorting_nodes.size(); ++sorting_idx) {
auto node = sorting_nodes[sorting_idx];
auto sort_idx = sort_values.indexOf(node->sortNumber().toDouble());
node->setSortNumber(sort_idx - temp_anchor.second);
}
}
void dags::DAGGraph::node_adjust_ingraph_forward(const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes)
{
int layer_index = 0;
while (this->node_adjust_inlayer_forward(layer_index, total_nodes)) {
layer_index++;
}
for (auto idx = 0; idx < layer_index; ++idx) {
this->sort_index_partition_indi(idx, total_nodes);
this->nodes_sort_with_above(idx, total_nodes);
}
}
bool dags::DAGGraph::node_adjust_inlayer_forward(int curr_layer, const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes)
{
// <20><>ѡ<EFBFBD><D1A1>ǰ<EFBFBD><C7B0><EFBFBD>νڵ<CEBD>
QList<std::shared_ptr<DAGOrderHelper>> curr_layer_nodes;
std::copy_if(total_nodes.begin(), total_nodes.end(), std::back_inserter(curr_layer_nodes),
[&](std::shared_ptr<DAGOrderHelper> inst) { return inst->layerNumber() == curr_layer; });
if (!curr_layer_nodes.size())
return false;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5>
QList<std::tuple<std::shared_ptr<DAGOrderHelper>, qlonglong, qlonglong, qlonglong, qlonglong>> orders_helper;
std::transform(curr_layer_nodes.begin(), curr_layer_nodes.end(), std::back_inserter(orders_helper),
[&](std::shared_ptr<DAGOrderHelper> ins) {
auto val_n = this->node_evaluate_with_downstream(ins, total_nodes);
auto val_p = this->node_evaluate_with_upstream(ins, total_nodes);
return std::make_tuple(ins, val_n.first, val_n.second, val_p.first, val_p.second);
});
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>νڵ<CEBD>
std::sort(orders_helper.begin(), orders_helper.end(), [](
std::tuple<std::shared_ptr<DAGOrderHelper>, qlonglong, qlonglong, qlonglong, qlonglong> a,
std::tuple<std::shared_ptr<DAGOrderHelper>, qlonglong, qlonglong, qlonglong, qlonglong> b)
{
if (std::get<1>(a) == std::get<1>(b)) {
if (std::get<2>(a) == std::get<2>(b)) {
if (std::get<3>(a) == std::get<3>(b)) {
return std::get<4>(a) < std::get<4>(b);
}
return std::get<3>(a) < std::get<3>(b);
}
return std::get<2>(a) < std::get<2>(b);
}
return std::get<1>(a) < std::get<1>(b);
});
QList<int> sort_values;
std::transform(curr_layer_nodes.begin(), curr_layer_nodes.end(), std::back_inserter(sort_values),
[](std::shared_ptr<DAGOrderHelper> ins) { return ins->sortNumber().toInt(); });
std::sort(sort_values.begin(), sort_values.end());
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>
for (auto idx = 0; idx < sort_values.size(); ++idx) {
std::get<0>(orders_helper[idx])->setSortNumber(sort_values[idx]);
}
return true;
}
bool dags::DAGGraph::sort_index_partition_indi(int layer_index, const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes)
{
// <20><>ȡ<EFBFBD><C8A1><EFBFBD>νڵ<CEBD>
QList<std::shared_ptr<DAGOrderHelper>> nodes_within_current_layer;
std::copy_if(total_nodes.begin(), total_nodes.end(), std::back_inserter(nodes_within_current_layer),
[=](std::shared_ptr<DAGOrderHelper> inst) {
return layer_index == inst->layerNumber();
});
// <20><><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
std::sort(nodes_within_current_layer.begin(), nodes_within_current_layer.end(),
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) {
return a->sortNumber() < b->sortNumber();
});
if (!nodes_within_current_layer.size())
return false;
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5>
QList<std::pair<std::shared_ptr<DAGOrderHelper>, QVariant>> sort_helper;
for (auto& inst : nodes_within_current_layer) {
auto prev_nodes = inst->getUpstreamNodes();
if (!prev_nodes.size()) {
sort_helper.append(std::make_pair(inst, QVariant()));
continue;
}
auto anchor_it = std::min_element(prev_nodes.begin(), prev_nodes.end(),
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) {
return a->layerNumber() < b->layerNumber();
});
sort_helper.append(std::make_pair(*anchor_it, (*anchor_it)->sortNumber()));
}
QVariant start_value;
for (auto idx = 0; idx < sort_helper.size(); ++idx) {
auto curr_u = sort_helper[idx];
if (!curr_u.second.isNull()) {
start_value = curr_u.second;
if (idx > 0) {
auto u = sort_helper[0];
sort_helper[0] = std::make_pair(u.first, start_value.toInt() - 1);
}
break;
}
}
if (start_value.isNull())
return false;
for (int idx = 1; idx < sort_helper.size(); ++idx) {
auto prev_u = sort_helper[idx - 1];
auto curr_u = sort_helper[idx];
if (curr_u.second.isNull()) {
sort_helper[idx] = std::make_pair(curr_u.first, prev_u.second);
}
if (curr_u.second < prev_u.second) {
sort_helper[idx] = std::make_pair(curr_u.first, prev_u.second);
}
}
std::for_each(sort_helper.begin(), sort_helper.end(),
[](std::pair<std::shared_ptr<DAGOrderHelper>, QVariant> u) {
u.first->setSortNumber(u.second.toDouble());
});
this->current_nodelist_filling_indi(nodes_within_current_layer);
return true;
}
std::pair<qlonglong, qlonglong> dags::DAGGraph::node_evaluate_with_downstream(std::shared_ptr<DAGOrderHelper> node, const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes)
{
decltype(node) next_node;
if (node->isFakeNode()) {
auto n_data = node->headsNode();
next_node = *std::find_if(total_nodes.begin(), total_nodes.end(), [&](decltype(node) n) {
if (!n->isFakeNode()) {
return n->layerNode() == n_data;
}
return false;
});
}
else {
auto n_datas = node->layerNode()->nextNodes();
if (!n_datas.size())
return std::make_pair(node->layerNumber(), node->sortNumber().toLongLong());
QList<std::shared_ptr<DAGOrderHelper>> next_nodes;
std::transform(n_datas.begin(), n_datas.end(), std::back_inserter(next_nodes),
[&](std::shared_ptr<DAGLayerHelper> inst) {
auto rst = std::find_if(total_nodes.begin(), total_nodes.end(), [&](decltype(node) n) {
if (!n->isFakeNode()) {
return n->layerNode() == inst;
}
return false;
});
return *rst;
});
next_node = *std::min_element(next_nodes.begin(), next_nodes.end(),
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) {
if (a->layerNumber() == b->layerNumber())
return a->sortNumber() < b->sortNumber();
return a->layerNumber() < b->layerNumber();
});
}
return std::make_pair(next_node->layerNumber(), next_node->sortNumber().toLongLong());
}
std::pair<qlonglong, qlonglong> dags::DAGGraph::node_evaluate_with_upstream(std::shared_ptr<DAGOrderHelper> node, const QList<std::shared_ptr<DAGOrderHelper>>& total_nodes)
{
auto prim_nodes = node->getUpstreamNodes();
if (!prim_nodes.size())
return std::make_pair(node->layerNumber(), node->sortNumber().toLongLong());
QList<std::shared_ptr<DAGOrderHelper>> prev_nodes;
std::transform(prim_nodes.begin(), prim_nodes.end(), std::back_inserter(prev_nodes),
[&](std::shared_ptr<DAGOrderHelper> ins) {
if (!ins->isFakeNode()) {
return ins;
}
auto prev_data = ins->tailsNode();
auto target_it = std::find_if(total_nodes.begin(), total_nodes.end(),
[&](std::shared_ptr<DAGOrderHelper> nins) {
if (!nins->isFakeNode())
return nins->layerNode() == prev_data;
return false;
});
return *target_it;
});
auto prev_it = std::min_element(prev_nodes.begin(), prev_nodes.end(),
[](std::shared_ptr<DAGOrderHelper> a, std::shared_ptr<DAGOrderHelper> b) {
if (a->layerNumber() == b->layerNumber())
return a->sortNumber() < b->sortNumber();
return a->layerNumber() < b->layerNumber();
});
return std::make_pair((*prev_it)->layerNumber(), (*prev_it)->sortNumber().toLongLong());
}
void dags::DAGGraph::primitiveGraphLayout() {
QList<std::shared_ptr<DAGLayerHelper>> sort_seqs;
QList<std::shared_ptr<DAGLayerHelper>> refs;
while (1) {
auto peaks = this->spawns_peak(refs);
if (!peaks)
break;
sort_seqs.append(peaks);
}
this->graph_recovery(sort_seqs);
for (auto item : sort_seqs) {
if (!item->inputCount()) {
this->max_layer_count = std::max(this->max_layer_count, this->node_layering(item, 0));
}
}
for (auto item : sort_seqs) {
if (!item->inputCount()) {
this->node_layering_adj(item);
}
}
auto tidy_nodes = this->tidy_graph_nodes();
this->graph_layer_nodes_sort_forward(0, tidy_nodes);
this->node_with_layout = tidy_nodes;
}
void dags::DAGGraph::forwardsLayoutImpls()
{
this->graph_layer_nodes_sort_forward(0, this->node_with_layout);
}
void dags::DAGGraph::backwardsLayoutImpls()
{
this->graph_adjust_after_layout(this->node_with_layout);
}
void dags::DAGGraph::adjustLayoutImpls()
{
this->node_adjust_ingraph_forward(this->node_with_layout);
}