void VarEdgeInserterDynCore::ExpandedGraph::constructDual(node s, node t) { m_dual.clear(); FaceArray<node> faceNode(m_E); // constructs nodes (for faces in exp) for (face f : m_E.faces) { faceNode[f] = m_dual.newNode(); } // construct dual edges (for primal edges in exp) for (node v : m_exp.nodes) { for (adjEntry adj : v->adjEdges) { // cannot cross edges that does not correspond to real edges adjEntry adjG = m_expToG[adj]; if (adjG == nullptr) continue; // Do not insert edges into dual if crossing the original edge // is forbidden if (m_pForbidden && (*m_pForbidden)[m_gc.original(m_BC.dynamicSPQRForest().original(m_expToG[adj]->theEdge()))] == true) continue; node vLeft = faceNode[m_E.leftFace(adj)]; node vRight = faceNode[m_E.rightFace(adj)]; m_primalEdge[m_dual.newEdge(vLeft, vRight)] = adj; } } // augment dual by m_vS and m_vT m_vS = m_dual.newNode(); if (m_GtoExp[s] != nullptr) { for (adjEntry adj : m_GtoExp[s]->adjEdges) m_dual.newEdge(m_vS, faceNode[m_E.rightFace(adj)]); } else { m_dual.newEdge(m_vS, faceNode[m_E.rightFace(m_eS->adjSource())]); m_dual.newEdge(m_vS, faceNode[m_E.rightFace(m_eS->adjTarget())]); } m_vT = m_dual.newNode(); if (m_GtoExp[t] != nullptr) { for (adjEntry adj : m_GtoExp[t]->adjEdges) m_dual.newEdge(faceNode[m_E.rightFace(adj)], m_vT); } else { m_dual.newEdge(faceNode[m_E.rightFace(m_eT->adjSource())], m_vT); m_dual.newEdge(faceNode[m_E.rightFace(m_eT->adjTarget())], m_vT); } }
void EmbedderOptimalFlexDraw::optimizeOverEmbeddings( StaticPlanarSPQRTree &T, node parent, node mu, int bends, NodeArray<int> cost[], NodeArray<long long> embedding[]) { cost[bends][mu] = numeric_limits<int>::max(); long long embeddingsCount = T.numberOfNodeEmbeddings(mu); for (long long currentEmbedding = 0; currentEmbedding < embeddingsCount; ++currentEmbedding) { T.embed(mu, currentEmbedding); Skeleton &skeleton = T.skeleton(mu); Graph skeletonGraph = skeleton.getGraph(); ConstCombinatorialEmbedding skeletonEmbedding(skeletonGraph); NodeArray<node> vertexNode(skeletonGraph); EdgeArray<node> edgeNode(skeletonGraph); FaceArray<node> faceNode(skeletonEmbedding); Graph N; EdgeArray<int> upper(N); EdgeArray<int> perUnitCost(N); NodeArray<int> supply(N); createNetwork( parent, mu, bends, cost, embedding, skeleton, edgeNode, N, upper, perUnitCost, supply); EdgeArray<int> lower(N, 0); EdgeArray<int> flow(N); NodeArray<int> dual(N); m_minCostFlowComputer.get().call(N, lower, upper, perUnitCost, supply, flow, dual); int currentCost = 0; for (edge e = N.firstEdge(); e != nullptr; e = e->succ()) currentCost += perUnitCost[e] * flow[e]; for (adjEntry adj = mu->firstAdj(); adj != nullptr; adj = adj->succ()) currentCost += cost[0][adj->twinNode()]; if (currentCost < cost[bends][mu]) { cost[bends][mu] = currentCost; embedding[bends][mu] = currentEmbedding; } } }
void ExpandedGraph2::constructDual(node s, node t, GraphCopy &GC, const EdgeArray<bool> *forbiddenEdgeOrig) { m_dual.clear(); FaceArray<node> faceNode(m_E); // constructs nodes (for faces in exp) face f; forall_faces(f,m_E) { faceNode[f] = m_dual.newNode(); } // construct dual edges (for primal edges in exp) node v; forall_nodes(v,m_exp) { adjEntry adj; forall_adj(adj,v) { // cannot cross edges that does not correspond to real edges adjEntry adjG = m_expToG[adj]; if(adjG == 0) continue; // Do not insert edges into dual if crossing the original edge // is forbidden if(forbiddenEdgeOrig && (*forbiddenEdgeOrig)[GC.original(m_BC.dynamicSPQRForest().original(m_expToG[adj]->theEdge()))] == true) continue; node vLeft = faceNode[m_E.leftFace (adj)]; node vRight = faceNode[m_E.rightFace(adj)]; m_primalEdge[m_dual.newEdge(vLeft,vRight)] = adj; }
void EmbedderOptimalFlexDraw::createNetwork( node parent, node mu, int bends, NodeArray<int> cost[], NodeArray<long long> embedding[], Skeleton &skeleton, EdgeArray<node> &edgeNode, Graph &N, EdgeArray<int> &upper, EdgeArray<int> &perUnitCost, NodeArray<int> &supply) { Graph skeletonGraph = skeleton.getGraph(); ConstCombinatorialEmbedding skeletonEmbedding(skeletonGraph); NodeArray<node> vertexNode(skeletonGraph); FaceArray<node> faceNode(skeletonEmbedding); for (node v = skeletonGraph.firstNode(); v != nullptr; v = v->succ()) { vertexNode[v] = N.newNode(); supply[vertexNode[v]] = 4 - skeleton.original(v)->degree() - v->degree(); } if (parent != nullptr) { node s = skeleton.referenceEdge()->source(); node t = skeleton.referenceEdge()->target(); supply[vertexNode[s]] = 2 - s->degree(); supply[vertexNode[t]] = 2 - t->degree(); } for (edge e = skeletonGraph.firstEdge(); e != nullptr; e = e->succ()) { if (skeleton.isVirtual(e)) { edgeNode[e] = N.newNode(); PertinentGraph H; skeleton.owner().pertinentGraph(skeleton.twinTreeNode(e), H); node s = H.original(e)->source(); node t = H.original(e)->target(); supply[edgeNode[e]] = s->degree() + t->degree() - 2; } } for (face f = skeletonEmbedding.firstFace(); f != nullptr; f = f->succ()) { faceNode[f] = N.newNode(); supply[faceNode[f]] = 4; } if (parent != nullptr) { face f1 = nullptr; face f2 = nullptr; for (adjEntry adj : skeletonEmbedding.externalFace()->entries) { if (adj->theEdge() == skeleton.referenceEdge()) { f1 = skeletonEmbedding.rightFace(adj); f2 = skeletonEmbedding.leftFace(adj); break; } } PertinentGraph H; skeleton.owner().pertinentGraph(mu, H); node s = skeleton.referenceEdge()->source(); node t = skeleton.referenceEdge()->target(); supply[faceNode[f1]] = H.original(s)->degree() + H.original(t)->degree() - 2 + bends; supply[faceNode[f2]] = -bends; } else { supply[faceNode[skeletonEmbedding.externalFace()]] = -4; } for (face f = skeletonEmbedding.firstFace(); f != nullptr; f = f->succ()) { for (adjEntry adj = f->firstAdj(); adj != nullptr; adj = adj->succ()) { edge e1 = N.newEdge(faceNode[f], vertexNode[adj->theNode()]); upper[e1] = 1; perUnitCost[e1] = 0; edge e2 = N.newEdge(vertexNode[adj->theNode()], faceNode[f]); upper[e2] = 1; perUnitCost[e2] = 0; } } for (face f = skeletonEmbedding.firstFace(); f != nullptr; f = f->succ()) { for (adjEntry adj = f->firstAdj(); adj != nullptr; adj = adj->succ()) { edge e = N.newEdge(edgeNode[adj->theEdge()], faceNode[f]); upper[e] = numeric_limits<int>::max(); perUnitCost[e] = 0; } } for (face f = skeletonEmbedding.firstFace(); f != nullptr; f = f->succ()) { for (adjEntry adj = f->firstAdj(); adj != nullptr; adj = adj->succ()) { if (skeleton.isVirtual(adj->theEdge())) { node mu = skeleton.twinTreeNode(adj->theEdge()); edge e0 = N.newEdge(faceNode[f], edgeNode[adj->theEdge()]); upper[e0] = 1; perUnitCost[e0] = cost[0][mu]; edge e1 = N.newEdge(faceNode[f], edgeNode[adj->theEdge()]); upper[e1] = 1; perUnitCost[e0] = cost[1][mu] - cost[0][mu]; edge e2 = N.newEdge(faceNode[f], edgeNode[adj->theEdge()]); upper[e2] = 1; perUnitCost[e2] = cost[2][mu] - cost[1][mu]; edge e3 = N.newEdge(faceNode[f], edgeNode[adj->theEdge()]); upper[e3] = 1; perUnitCost[e3] = cost[3][mu] - cost[2][mu]; for (adjEntry adj= mu->firstAdj(); adj != nullptr; adj = adj->succ()) { if (adj->twinNode() != mu) { perUnitCost[e0] -= cost[0][adj->twinNode()]; perUnitCost[e1] -= cost[0][adj->twinNode()]; perUnitCost[e2] -= cost[0][adj->twinNode()]; perUnitCost[e3] -= cost[0][adj->twinNode()]; } } } else { edge e0 = N.newEdge(faceNode[f], edgeNode[adj->theEdge()]); upper[e0] = 1; perUnitCost[e0] = m_cost[0][adj->theEdge()]; edge e1 = N.newEdge(faceNode[f], edgeNode[adj->theEdge()]); upper[e1] = 1; perUnitCost[e1] = m_cost[1][adj->theEdge()] - m_cost[0][adj->theEdge()]; edge e2 = N.newEdge(faceNode[f], edgeNode[adj->theEdge()]); upper[e2] = 1; perUnitCost[e2] = m_cost[2][adj->theEdge()] - m_cost[1][adj->theEdge()]; edge e3 = N.newEdge(faceNode[f], edgeNode[adj->theEdge()]); upper[e3] = 1; perUnitCost[e3] = m_cost[3][adj->theEdge()] - m_cost[2][adj->theEdge()]; } } } }
void VarEdgeInserterDynUMLCore::ExpandedGraphUML::constructDual(node s, node t) { VarEdgeInserterDynUMLCore::BCandSPQRtreesUML &BC = dynamic_cast<VarEdgeInserterDynUMLCore::BCandSPQRtreesUML&>(m_BC); m_dual.clear(); FaceArray<node> faceNode(m_E); // constructs nodes (for faces in exp) for (face f : m_E.faces) { faceNode[f] = m_dual.newNode(); } #ifdef OGDF_DEBUG edge eDual; #endif // construct dual edges (for primal edges in exp) for (node v : m_exp.nodes) { for (adjEntry adj : v->adjEdges) { // cannot cross edges that does not correspond to real edges adjEntry adjG = m_expToG[adj]; if (adjG == nullptr) continue; node vLeft = faceNode[m_E.leftFace(adj)]; node vRight = faceNode[m_E.rightFace(adj)]; edge e = m_dual.newEdge(vLeft, vRight); m_primalEdge[e] = adj; // mark dual edges corresponding to generalizations if (adjG && BC.typeOf(adjG->theEdge()) == Graph::generalization) m_primalIsGen[e] = true; OGDF_ASSERT(m_primalEdge[e] == nullptr || m_expToG[m_primalEdge[e]] != nullptr); } } // augment dual by m_vS and m_vT m_vS = m_dual.newNode(); if (m_GtoExp[s] != nullptr) { for (adjEntry adj : m_GtoExp[s]->adjEdges) { #ifdef OGDF_DEBUG eDual = #endif m_dual.newEdge(m_vS, faceNode[m_E.rightFace(adj)]); OGDF_ASSERT(m_primalEdge[eDual] == nullptr || m_expToG[m_primalEdge[eDual]] != nullptr); } } else { #ifdef OGDF_DEBUG eDual = #endif m_dual.newEdge(m_vS, faceNode[m_E.rightFace(m_eS->adjSource())]); OGDF_ASSERT(m_primalEdge[eDual] == nullptr || m_expToG[m_primalEdge[eDual]] != nullptr); #ifdef OGDF_DEBUG eDual = #endif m_dual.newEdge(m_vS, faceNode[m_E.rightFace(m_eS->adjTarget())]); OGDF_ASSERT(m_primalEdge[eDual] == nullptr || m_expToG[m_primalEdge[eDual]] != nullptr); } m_vT = m_dual.newNode(); if (m_GtoExp[t] != nullptr) { for (adjEntry adj : m_GtoExp[t]->adjEdges) { #ifdef OGDF_DEBUG eDual = #endif m_dual.newEdge(faceNode[m_E.rightFace(adj)], m_vT); OGDF_ASSERT(m_primalEdge[eDual] == nullptr || m_expToG[m_primalEdge[eDual]] != nullptr); } } else { #ifdef OGDF_DEBUG eDual = #endif m_dual.newEdge(faceNode[m_E.rightFace(m_eT->adjSource())], m_vT); OGDF_ASSERT(m_primalEdge[eDual] == nullptr || m_expToG[m_primalEdge[eDual]] != nullptr); #ifdef OGDF_DEBUG eDual = #endif m_dual.newEdge(faceNode[m_E.rightFace(m_eT->adjTarget())], m_vT); OGDF_ASSERT(m_primalEdge[eDual] == nullptr || m_expToG[m_primalEdge[eDual]] != nullptr); } }