129 const T& delta_d,
adjEntry& adjExternal,
const node& n =
nullptr);
165 const T& delta_d,
adjEntry& adjExternal);
201 const T& delta_d,
adjEntry& adjExternal);
240 const T& delta_d,
adjEntry& adjExternal,
const node& n =
nullptr);
279 const T& delta_d,
adjEntry& adjExternal);
296 if (G.numberOfEdges() <= 2) {
297 edge e = G.firstEdge();
305 compute(G, nodeLength, edgeLength, &spqrTree, edgeLengthSkel);
313 T sizeMu = largestFaceInSkeleton(spqrTree, mu, nodeLength, edgeLengthSkel);
314 if (sizeMu > biggestFace) {
315 biggestFace = sizeMu;
324 bool alreadySeenMu =
false;
325 for (
int j = 0; j < i && !alreadySeenMu; j++) {
326 if (mus[i] == mus[j]) {
327 alreadySeenMu =
true;
337 largestFaceContainingNode(spqrTree, mus[i], n, nodeLength, edgeLengthSkel);
338 if (sizeInMu > biggestFace) {
339 biggestFace = sizeInMu;
352 bottomUpThickness(spqrTree, bigFaceMu, thickness, nodeLength, edgeLengthSkel);
357 adjExternal =
nullptr;
360 expandEdge(spqrTree, treeNodeTreated, bigFaceMu,
nullptr, nodeLength, edgeLengthSkel, thickness,
361 newOrder, adjBeforeNodeArraySource, adjBeforeNodeArrayTarget, 0, 0, adjExternal, n);
363 for (
node v : G.nodes) {
364 G.sort(v, newOrder[v]);
376 const T& delta_d,
adjEntry& adjExternal) {
386 if (!treeNodeTreated[twinNT]) {
389 m_leftNode = twinE->
source();
391 m_leftNode = twinE->
target();
395 adjBeforeNodeArraySource[twinNT] =
before;
397 adjBeforeNodeArrayTarget[twinNT] =
before;
401 expandEdge(spqrTree, treeNodeTreated, twinNT, m_leftNode, nodeLength, edgeLength,
402 thickness, newOrder, adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
403 delta_u, delta_d, adjExternal);
406 if (ae->
theEdge() == referenceEdge) {
409 adjBeforeNodeArraySource[mu] =
before;
413 adjBeforeNodeArrayTarget[mu] =
before;
419 before = adjBeforeNodeArraySource[twinNT];
421 before = adjBeforeNodeArrayTarget[twinNT];
429 if (origNode == origEdge->
source()) {
452 const T& delta_d,
adjEntry& adjExternal,
const node& n ) {
453 treeNodeTreated[mu] =
true;
455 switch (spqrTree.
typeOf(mu)) {
457 expandEdgeSNode(spqrTree, treeNodeTreated, mu, leftNode, nodeLength, edgeLength, thickness,
458 newOrder, adjBeforeNodeArraySource, adjBeforeNodeArrayTarget, delta_u, delta_d,
462 expandEdgePNode(spqrTree, treeNodeTreated, mu, leftNode, nodeLength, edgeLength, thickness,
463 newOrder, adjBeforeNodeArraySource, adjBeforeNodeArrayTarget, delta_u, delta_d,
467 expandEdgeRNode(spqrTree, treeNodeTreated, mu, leftNode, nodeLength, edgeLength, thickness,
468 newOrder, adjBeforeNodeArraySource, adjBeforeNodeArrayTarget, delta_u, delta_d,
483 const T& delta_d,
adjEntry& adjExternal) {
487 if (leftNode ==
nullptr) {
490 startAdjEntry = e->adjSource();
496 startAdjEntry = leftNode->
lastAdj();
498 startAdjEntry = leftNode->
firstAdj();
502 if (adjExternal ==
nullptr) {
512 if (referenceEdge && leftNode == referenceEdge->
source()) {
513 before = adjBeforeNodeArraySource[mu];
514 }
else if (referenceEdge) {
515 before = adjBeforeNodeArrayTarget[mu];
519 bool firstStep =
true;
520 while (firstStep || ae != startAdjEntry) {
524 if (ae->
theEdge() == referenceEdge) {
526 adjBeforeNodeArraySource[mu] =
before;
528 adjBeforeNodeArrayTarget[mu] =
before;
535 adjBeforeNodeArrayTarget[twinTN] = adjBeforeNodeArraySource[mu];
537 adjBeforeNodeArrayTarget[twinTN] = adjBeforeNodeArrayTarget[mu];
541 adjBeforeNodeArraySource[twinTN] = adjBeforeNodeArraySource[mu];
543 adjBeforeNodeArraySource[twinTN] = adjBeforeNodeArrayTarget[mu];
548 adjEntryForNode(ae,
before, spqrTree, treeNodeTreated, mu, m_leftNode, nodeLength,
549 edgeLength, thickness, newOrder, adjBeforeNodeArraySource,
550 adjBeforeNodeArrayTarget, delta_u, delta_d, adjExternal);
559 if (!referenceEdge) {
562 before = adjBeforeNodeArraySource[mu];
564 before = adjBeforeNodeArrayTarget[mu];
568 if (ae->
theEdge() == referenceEdge) {
570 adjBeforeNodeArraySource[mu] = beforeSource;
572 adjBeforeNodeArrayTarget[mu] = beforeSource;
575 adjEntryForNode(ae,
before, spqrTree, treeNodeTreated, mu, m_leftNode, nodeLength,
576 edgeLength, thickness, newOrder, adjBeforeNodeArraySource,
577 adjBeforeNodeArrayTarget, delta_u, delta_d, adjExternal);
596 const T& delta_d,
adjEntry& adjExternal) {
600 edge altReferenceEdge =
nullptr;
602 node m_leftNode = leftNode;
606 m_leftNode = *(nodeList.
begin());
610 if (referenceEdge ==
nullptr) {
613 altReferenceEdge = e;
628 if (e == referenceEdge || e == altReferenceEdge) {
636 if (edgeLength[mu][e] > edgeLength[mu][*it]) {
655 for (
int i = 0; i < 2; ++i) {
662 before = beforeAltRefEdge;
666 if (n == referenceEdge->
source()) {
667 before = adjBeforeNodeArraySource[mu];
669 before = adjBeforeNodeArrayTarget[mu];
680 if (referenceEdge->
source() == m_rightNode) {
681 beforeRight = adjBeforeNodeArraySource[mu];
683 beforeRight = adjBeforeNodeArrayTarget[mu];
686 bool insertBeforeLast =
false;
687 bool oneEdgeInE_a =
false;
691 for (
int looper = 0; looper < graphEdges.
size(); looper++) {
692 edge e = *(graphEdges.
get(looper));
694 if (!lastPos.
valid()) {
695 lastPos = rightEdgeOrder.
pushBack(e);
696 }
else if (insertBeforeLast) {
703 if (delta_u + sum_E_a < delta_d + sum_E_b) {
715 T delta_u_nu = delta_u + sum_E_a;
716 T delta_d_nu = delta_d + sum_E_b;
722 adjEntryForNode(ae, tmp_before, spqrTree, treeNodeTreated, mu, m_leftNode,
723 nodeLength, edgeLength, thickness, tmp_newOrder,
724 adjBeforeNodeArraySource, adjBeforeNodeArrayTarget, delta_d_nu,
725 delta_u_nu, adjExternal);
732 if (nOG_tmp_adjList.
size() == 0) {
737 if (nOG == leftOrg) {
739 }
else if (nOG == rightOrg && referenceEdge) {
740 m_before = &beforeRight;
746 ae_it.valid(); ++ae_it) {
748 if (!m_before->
valid()) {
749 *m_before = newOrder[nOG].pushBack(adjaEnt);
751 *m_before = newOrder[nOG].insertBefore(adjaEnt, *m_before);
754 if (nOG == leftOrg || nOG == rightOrg) {
756 adjBeforeNodeArraySource[nu] = *m_before;
758 adjBeforeNodeArrayTarget[nu] = *m_before;
763 if (nOG != leftOrg && (nOG != rightOrg || !referenceEdge)) {
768 sum_E_a += thickness[nu];
771 adjEntryForNode(ae, beforeU, spqrTree, treeNodeTreated, mu, m_leftNode,
772 nodeLength, edgeLength, thickness, newOrder, adjBeforeNodeArraySource,
773 adjBeforeNodeArrayTarget, 0, 0, adjExternal);
778 insertBeforeLast =
false;
780 beforeLeft = beforeU;
789 adjBeforeNodeArrayTarget[nu] = beforeRight;
791 adjBeforeNodeArraySource[nu] = beforeRight;
796 T delta_u_nu = delta_u + sum_E_a;
797 T delta_d_nu = delta_d + sum_E_b;
805 adjEntryForNode(ae,
before, spqrTree, treeNodeTreated, mu, m_leftNode,
806 nodeLength, edgeLength, thickness, newOrder, adjBeforeNodeArraySource,
807 adjBeforeNodeArrayTarget, delta_u_nu, delta_d_nu, adjExternal);
815 insertBeforeLast =
true;
823 if ((*it)->source() == n) {
824 ae = (*it)->adjSource();
826 ae = (*it)->adjTarget();
829 adjEntryForNode(ae,
before, spqrTree, treeNodeTreated, mu, m_leftNode, nodeLength,
830 edgeLength, thickness, newOrder, adjBeforeNodeArraySource,
831 adjBeforeNodeArrayTarget, 0, 0, adjExternal);
838 if (n == referenceEdge->
source()) {
839 adjBeforeNodeArraySource[mu] = beforeLeft;
841 adjBeforeNodeArrayTarget[mu] = beforeLeft;
844 if (n == referenceEdge->
source()) {
845 adjBeforeNodeArraySource[mu] =
before;
847 adjBeforeNodeArrayTarget[mu] =
before;
851 if (altReferenceEdge->
source() == n) {
857 adjEntryForNode(ae,
before, spqrTree, treeNodeTreated, mu, m_leftNode, nodeLength,
858 edgeLength, thickness, newOrder, adjBeforeNodeArraySource,
859 adjBeforeNodeArrayTarget, 0, 0, adjExternal);
871 const T& delta_d,
adjEntry& adjExternal,
const node& n ) {
876 face maxFaceContEdge =
nullptr;
882 for (
face f : combinatorialEmbedding.
faces) {
883 bool containsVirtualEdgeOrN =
false;
884 adjEntry this_m_adjExternal =
nullptr;
889 if ((n ==
nullptr && (ae->theEdge() == referenceEdge || !referenceEdge))
890 || S.
original(ae->theNode()) == n) {
891 containsVirtualEdgeOrN =
true;
893 this_m_adjExternal = ae;
897 if (!referenceEdge && !S.
isVirtual(ae->theEdge())) {
898 this_m_adjExternal = ae;
901 sizeOfFace += edgeLength[mu][ae->theEdge()] + nodeLength[S.
original(ae->theNode())];
904 if (containsVirtualEdgeOrN && this_m_adjExternal && sizeOfFace > bigFaceSize) {
905 maxFaceNodes = faceNodes;
906 bigFaceSize = sizeOfFace;
908 m_adjExternal = this_m_adjExternal;
922 adjEntry adjMaxFace = m_adjExternal;
929 if (leftNode == referenceEdge->
source()) {
930 succ_virtualEdge_leftNode = referenceEdge->
adjSource()->
succ();
932 succ_virtualEdge_leftNode = referenceEdge->
adjTarget()->
succ();
934 if (!succ_virtualEdge_leftNode) {
935 succ_virtualEdge_leftNode = leftNode->
firstAdj();
938 bool succVELNAEInExtFace =
false;
940 if (aeExtFace->theEdge() == succ_virtualEdge_leftNode->
theEdge()) {
941 succVELNAEInExtFace =
true;
946 if (!succVELNAEInExtFace) {
949 for (
adjEntry ae = v->firstAdj(); ae; ae = ae->
succ()) {
954 adjMaxFace = adjMaxFace->
twin();
961 start_ae = adjMaxFace;
963 if (start_ae->
theEdge() == referenceEdge) {
968 }
while (start_ae != adjMaxFace);
970 start_ae = adjMaxFace;
977 bool firstStep =
true;
978 bool after_start_ae =
true;
979 for (
adjEntry ae = start_ae; firstStep || ae != start_ae;
980 after_start_ae = after_start_ae && ae->
succ(),
982 : (!ae->faceCycleSucc() ? adjMaxFace : ae->
faceCycleSucc())) {
987 nodeTreated[ae->theNode()] =
true;
991 edge vE = (ae->theEdge() == referenceEdge) ? referenceEdge : ae->theEdge();
992 node nu = (ae->theEdge() == referenceEdge) ? mu : S.
twinTreeNode(ae->theEdge());
994 if (ae->theNode() == vE->
source()) {
995 before = adjBeforeNodeArraySource[nu];
997 before = adjBeforeNodeArrayTarget[nu];
1001 bool after_ae =
true;
1003 if (referenceEdge) {
1004 if (ae->theNode() == referenceEdge->
source()) {
1005 m_start_ae = referenceEdge->
adjSource();
1006 }
else if (ae->theNode() == referenceEdge->
target()) {
1007 m_start_ae = referenceEdge->
adjTarget();
1016 bool hit_stop_twice =
false;
1019 && (ae->theNode() == referenceEdge->
source()
1020 || ae->theNode() == referenceEdge->
target())) {
1021 if (m_start_ae->
succ()) {
1022 m_stop_ae = m_start_ae->
succ();
1025 hit_stop_twice =
true;
1028 m_stop_ae = m_start_ae;
1032 after_ae || (hit_stop_twice && numOfHits != 2) || aeN != m_stop_ae;
1033 after_ae = after_ae && aeN->
succ(),
1034 aeN = after_ae ? aeN->
succ()
1035 : (!aeN->succ() ? ae->theNode()->firstAdj() : aeN->succ()),
1036 numOfHits = (aeN == m_stop_ae) ? numOfHits + 1 : numOfHits) {
1037 node m_leftNode =
nullptr;
1038 if (S.
isVirtual(aeN->theEdge()) && aeN->theEdge() != referenceEdge) {
1044 bool succInExtFace =
false;
1045 bool aeNInExtFace =
false;
1047 aeExtFace = adjMaxFace;
1050 succInExtFace =
true;
1055 if (aeExtFace->
theEdge() == aeN->theEdge()) {
1056 aeNInExtFace =
true;
1057 if (succInExtFace) {
1062 }
while (aeExtFace != adjMaxFace);
1063 if (aeNInExtFace && succInExtFace) {
1064 m_leftNode = aeN->twinNode();
1066 m_leftNode = aeN->theNode();
1070 if (referenceEdge) {
1071 if (aeN->theEdge()->source() == aeN->theNode()) {
1072 if (aeN->theEdge()->target() == referenceEdge->
source()) {
1073 adjBeforeNodeArrayTarget[twinTN] = adjBeforeNodeArraySource[mu];
1074 }
else if (aeN->theEdge()->target() == referenceEdge->
target()) {
1075 adjBeforeNodeArrayTarget[twinTN] = adjBeforeNodeArrayTarget[mu];
1078 if (aeN->theEdge()->source() == referenceEdge->
source()) {
1079 adjBeforeNodeArraySource[twinTN] = adjBeforeNodeArraySource[mu];
1080 }
else if (aeN->theEdge()->source() == referenceEdge->
target()) {
1081 adjBeforeNodeArraySource[twinTN] = adjBeforeNodeArrayTarget[mu];
1087 adjEntryForNode(aeN,
before, spqrTree, treeNodeTreated, mu, m_leftNode, nodeLength,
1088 edgeLength, thickness, newOrder, adjBeforeNodeArraySource,
1089 adjBeforeNodeArrayTarget, 0, 0, adjExternal);
1094 if (!maxFaceNodes.
search(aeN->twinNode()).valid()) {
1095 node orig_aeN_twin_theNode = S.
original(aeN->twinNode());
1096 buffer[aeN->theEdge()] = newOrder[orig_aeN_twin_theNode];
1097 newOrder[orig_aeN_twin_theNode].clear();
1105 bool DGcomputed =
false;
1117 if (nodeTreated[v]) {
1122 nodeTreated[v] =
true;
1124 for (
adjEntry ae = v->firstAdj(); ae; ae = ae->
succ()) {
1125 if (buffer[ae->theEdge()].empty()) {
1128 bool frauenlinks =
false;
1138 for (
adjEntry ae_nBG : nBG->adjEntries) {
1139 adjacencyList[nBG].pushBack(ae_nBG);
1145 for (
adjEntry adj : nBG->adjEntries) {
1146 if (adjEntryTreated[nBG].search(adj).valid()) {
1154 ae_to_face[adj2] = faces.
size();
1155 adjEntryTreated[adj2->
theNode()].pushBack(adj2);
1158 }
while (adj2 != adj);
1176 bool do_break =
false;
1179 if ((*it4) == (*it2)->twin()) {
1192 && !adjFaces[fPG_to_nDG[f1_id]].search(fPG_to_nDG[f2_id]).valid()
1193 && !adjFaces[fPG_to_nDG[f2_id]].search(fPG_to_nDG[f1_id]).valid()) {
1194 adjFaces[fPG_to_nDG[f1_id]].pushBack(fPG_to_nDG[f2_id]);
1195 edge e1 = DG.
newEdge(fPG_to_nDG[f1_id], fPG_to_nDG[f2_id]);
1196 edge e2 = DG.
newEdge(fPG_to_nDG[f2_id], fPG_to_nDG[f1_id]);
1200 for (
auto f1 : *it) {
1201 edge e = f1->theEdge();
1202 for (
auto f2 : *faces.
get(f2_id)) {
1203 if (f2->theEdge() == e
1205 || edgeLength[mu][e] < e_length)) {
1206 e_length = edgeLength[mu][e];
1210 edgeLengthDG[e1] = e_length;
1211 edgeLengthDG[e2] = e_length;
1214 if (*it2 == adjMaxFace) {
1217 if (referenceEdge && *it2 == adjMaxFace->
twin()) {
1225 node f_ext_DG = fPG_to_nDG[f_ext_id];
1226 dist_f_ext.
init(DG);
1227 sssp(DG, f_ext_DG, edgeLengthDG, dist_f_ext);
1228 if (referenceEdge) {
1229 node f_ref_DG = fPG_to_nDG[f_ref_id];
1230 dist_f_ref.
init(DG);
1231 sssp(DG, f_ref_DG, edgeLengthDG, dist_f_ref);
1237 T pi_f_0_f_ext = dist_f_ext[fPG_to_nDG[ae_to_face[ae]]];
1238 T pi_f_1_f_ext = dist_f_ext[fPG_to_nDG[ae_to_face[ae->twin()]]];
1239 if (referenceEdge) {
1240 T pi_f_0_f_ref = dist_f_ref[fPG_to_nDG[ae_to_face[ae]]];
1241 T pi_f_1_f_ref = dist_f_ref[fPG_to_nDG[ae_to_face[ae->twin()]]];
1243 if (delta_u + pi_f_0_f_ref < delta_d + pi_f_0_f_ext) {
1244 min1 = delta_u + pi_f_0_f_ref;
1246 min1 = delta_d + pi_f_0_f_ext;
1249 if (delta_u + pi_f_1_f_ref < delta_d + pi_f_1_f_ext) {
1250 min2 = delta_u + pi_f_1_f_ref;
1252 min2 = delta_d + pi_f_1_f_ext;
1256 delta_u_nu = delta_u;
1257 if (pi_f_0_f_ref < pi_f_0_f_ext) {
1258 delta_u_nu += pi_f_0_f_ref;
1260 delta_u_nu += pi_f_0_f_ext;
1262 delta_d_nu = delta_d;
1263 if (pi_f_1_f_ref < pi_f_1_f_ext) {
1264 delta_d_nu += pi_f_1_f_ref;
1266 delta_d_nu += pi_f_1_f_ext;
1270 delta_u_nu = delta_u;
1271 if (pi_f_1_f_ref < pi_f_1_f_ext) {
1272 delta_u_nu += pi_f_1_f_ref;
1274 delta_u_nu += pi_f_1_f_ext;
1276 delta_d_nu = delta_d;
1277 if (pi_f_0_f_ref < pi_f_0_f_ext) {
1278 delta_d_nu += pi_f_0_f_ref;
1280 delta_d_nu += pi_f_0_f_ext;
1284 min1 = delta_d + pi_f_0_f_ext;
1285 min2 = delta_d + pi_f_1_f_ext;
1288 delta_u_nu = delta_u + pi_f_0_f_ext;
1289 delta_d_nu = delta_d + pi_f_1_f_ext;
1292 delta_u_nu = delta_u + pi_f_1_f_ext;
1293 delta_d_nu = delta_d + pi_f_0_f_ext;
1305 adjEntryForNode(ae, tmp_before, spqrTree, treeNodeTreated, mu, v, nodeLength,
1306 edgeLength, thickness, tmp_newOrder, adjBeforeNodeArraySource,
1307 adjBeforeNodeArrayTarget, delta_u_nu, delta_d_nu, adjExternal);
1311 node m_leftNode = v;
1313 node m_rightNode = ae->twinNode();
1314 node leftOrg = v_original;
1318 if (nOG_tmp_adjList.
size() == 0) {
1323 if (nOG == leftOrg) {
1332 if (!m_before->
valid()) {
1333 *m_before = newOrder[nOG].pushBack(adjaEnt);
1335 *m_before = newOrder[nOG].insertBefore(adjaEnt, *m_before);
1338 if (nOG == leftOrg || nOG == rightOrg) {
1339 if (S.
original(ae->theEdge()->source()) == nOG) {
1340 adjBeforeNodeArraySource[nu] = *m_before;
1342 adjBeforeNodeArrayTarget[nu] = *m_before;
1347 if (nOG != leftOrg) {
1352 adjEntryForNode(ae,
before, spqrTree, treeNodeTreated, mu, v, nodeLength,
1353 edgeLength, thickness, newOrder, adjBeforeNodeArraySource,
1354 adjBeforeNodeArrayTarget, delta_u_nu, delta_d_nu, adjExternal);
1357 if (!nodeTreated[ae->twinNode()]) {
1358 node orig_ae_twin_theNode = S.
original(ae->twinNode());
1359 buffer[ae->theEdge()] = newOrder[orig_ae_twin_theNode];
1360 newOrder[orig_ae_twin_theNode].clear();
1363 buffer[ae->theEdge()].reverse();
1366 before = newOrder[v_original].pushFront(*it);
1368 before = newOrder[v_original].insertBefore(*it,
before);
1382 edge e_mu_to_nu = adj->theEdge();
1383 if (e_mu_to_nu->
source() != mu) {
1387 bottomUpThickness(spqrTree, nu, thickness, nodeLength, edgeLength);
1394 if (!referenceEdge) {
1402 if (eSG == referenceEdge) {
1408 dLength[eSG] = thickness[twinTN];
1410 dLength[eSG] = edgeLength[mu][eSG];
1415 switch (spqrTree.
typeOf(mu)) {
1420 if (eSG == referenceEdge) {
1423 if (min_dLength == -1 || dLength[eSG] < min_dLength) {
1424 min_dLength = dLength[eSG];
1427 thickness[mu] = min_dLength;
1431 T sumof_dLength = 0;
1433 if (eSG == referenceEdge) {
1436 sumof_dLength += dLength[eSG];
1438 thickness[mu] = sumof_dLength;
1452 T faceSize_f_ext = 0;
1453 adjEntry ae_f_ext_walker = ae_f_ext;
1456 + edgeLength[mu][ae_f_ext_walker->
theEdge()];
1458 }
while (ae_f_ext_walker != ae_f_ext);
1459 T faceSize_f_ref = 0;
1460 adjEntry ae_f_ref_walker = ae_f_ref;
1463 + edgeLength[mu][ae_f_ref_walker->
theEdge()];
1465 }
while (ae_f_ref_walker != ae_f_ref);
1466 if (faceSize_f_ext < faceSize_f_ref) {
1468 ae_f_ext = ae_f_ref;
1483 for (
adjEntry ae_nBG : nBG->adjEntries) {
1484 adjacencyList[nBG].pushBack(ae_nBG);
1490 for (
adjEntry adj : nBG->adjEntries) {
1491 if (adjEntryTreated[nBG].search(adj).valid()) {
1499 adjEntryTreated[adj2->
theNode()].pushBack(adj2);
1502 }
while (adj2 != adj);
1519 bool do_break =
false;
1521 if ((*it4) == (*it2)->twin()) {
1533 if (f1_id != f2_id && !adjFaces[fPG_to_nDG[f1_id]].search(fPG_to_nDG[f2_id]).valid()
1534 && !adjFaces[fPG_to_nDG[f2_id]].search(fPG_to_nDG[f1_id]).valid()) {
1535 adjFaces[fPG_to_nDG[f1_id]].pushBack(fPG_to_nDG[f2_id]);
1536 adjFaces[fPG_to_nDG[f2_id]].pushBack(fPG_to_nDG[f1_id]);
1537 edge e1 = DG.
newEdge(fPG_to_nDG[f1_id], fPG_to_nDG[f2_id]);
1538 edge e2 = DG.
newEdge(fPG_to_nDG[f2_id], fPG_to_nDG[f1_id]);
1543 edge e = (*it_f1)->theEdge();
1545 it_f2.
valid(); ++it_f2) {
1546 if ((*it_f2)->theEdge() == e
1547 && (e_length == -1 || edgeLength[mu][e] < e_length)) {
1548 e_length = edgeLength[mu][e];
1552 edgeLengthDG[e1] = e_length;
1553 edgeLengthDG[e2] = e_length;
1556 if (*it2 == ae_f_ext) {
1559 if (*it2 == ae_f_ref) {
1567 node nDG_f_ref = fPG_to_nDG[f_ref_id];
1568 List<node>& f_ref_adj_faces = adjFaces[nDG_f_ref];
1571 DG.
delNode(fPG_to_nDG[f_ref_id]);
1575 node nDG_f_ext = fPG_to_nDG[f_ext_id];
1576 sssp(DG, nDG_f_ext, edgeLengthDG, dist);
1580 node fDG = *it_adj_faces;
1581 if (fDG != nDG_f_ext) {
1583 if (minDist == -1 || d < minDist) {
1588 thickness[mu] = minDist + 1;
1602 for (
node v : G.nodes) {
1607 for (
int i = 1; i < G.numberOfNodes(); ++i) {
1608 for (
edge e : G.edges) {
1610 if (d[e->target()] > d[e->source()] + length[e]) {
1611 d[e->target()] = d[e->source()] + length[e];
1617 for (
edge e : G.edges) {
1618 if (d[e->target()] > d[e->source()] + length[e]) {
Declaration and implementation of ArrayBuffer class.
Declaration of CombinatorialEmbedding and face.
Declares ogdf::EmbedderMaxFaceBiconnectedGraphs.
Includes declaration of graph class.
Decralation of GraphElement and GraphList classes.
Declaration of doubly linked lists and iterators.
Declaration of class SPQRTree.
Declaration of class Skeleton.
Declaration of class StaticSPQRTree.
Basic declarations, included by all source files.
Class for adjacency list elements.
adjEntry twin() const
Returns the corresponding adjacency element associated with the same edge.
adjEntry succ() const
Returns the successor in the adjacency list.
edge theEdge() const
Returns the edge associated with this adjacency entry.
node twinNode() const
Returns the associated node of the corresponding adjacency entry (shorthand for twin()->theNode()).
node theNode() const
Returns the node whose adjacency list contains this element.
adjEntry faceCycleSucc() const
Returns the cyclic successor in face.
An array that keeps track of the number of inserted elements; also usable as an efficient stack.
void push(E e)
Puts a new element in the buffer.
Combinatorial embeddings of planar graphs with modification functionality.
internal::GraphObjectContainer< FaceElement > faces
The container containing all face objects.
Class for the representation of edges.
adjEntry adjSource() const
Returns the corresponding adjacancy entry at source node.
adjEntry adjTarget() const
Returns the corresponding adjacancy entry at target node.
node target() const
Returns the target node of the edge.
node source() const
Returns the source node of the edge.
Embedder that maximizing the external face.
static T computeSize(const Graph &G, const node &n, const NodeArray< T > &nodeLength, const EdgeArray< T > &edgeLength)
Returns the size of a maximum external face in G containing the node n.
static void compute(const Graph &G, const NodeArray< T > &nodeLength, const EdgeArray< T > &edgeLength, StaticSPQRTree *spqrTree, NodeArray< EdgeArray< T > > &edgeLengthSkel)
Computes the component lengths of all virtual edges in spqrTree.
static T largestFaceInSkeleton(const StaticSPQRTree &spqrTree, const node &mu, const NodeArray< T > &nodeLength, const NodeArray< EdgeArray< T > > &edgeLength)
Computes the size of a maximum face in the skeleton graph of mu.
static T largestFaceContainingNode(const StaticSPQRTree &spqrTree, const node &mu, const node &n, const NodeArray< T > &nodeLength, const NodeArray< EdgeArray< T > > &edgeLength)
Computes the size of a maximum face in the skeleton graph of mu containing n.
Embedder that maximizes the external face (plus layers approach).
static void expandEdge(const StaticSPQRTree &spqrTree, NodeArray< bool > &treeNodeTreated, const node &mu, const node &leftNode, const NodeArray< T > &nodeLength, const NodeArray< EdgeArray< T > > &edgeLength, const NodeArray< T > &thickness, NodeArray< List< adjEntry > > &newOrder, NodeArray< ListIterator< adjEntry > > &adjBeforeNodeArraySource, NodeArray< ListIterator< adjEntry > > &adjBeforeNodeArrayTarget, const T &delta_u, const T &delta_d, adjEntry &adjExternal, const node &n=nullptr)
static void expandEdgePNode(const StaticSPQRTree &spqrTree, NodeArray< bool > &treeNodeTreated, const node &mu, const node &leftNode, const NodeArray< T > &nodeLength, const NodeArray< EdgeArray< T > > &edgeLength, const NodeArray< T > &thickness, NodeArray< List< adjEntry > > &newOrder, NodeArray< ListIterator< adjEntry > > &adjBeforeNodeArraySource, NodeArray< ListIterator< adjEntry > > &adjBeforeNodeArrayTarget, const T &delta_u, const T &delta_d, adjEntry &adjExternal)
static bool sssp(const Graph &G, const node &s, const EdgeArray< T > &length, NodeArray< T > &d)
static void adjEntryForNode(adjEntry &ae, ListIterator< adjEntry > &before, const StaticSPQRTree &spqrTree, NodeArray< bool > &treeNodeTreated, const node &mu, const node &leftNode, const NodeArray< T > &nodeLength, const NodeArray< EdgeArray< T > > &edgeLength, const NodeArray< T > &thickness, NodeArray< List< adjEntry > > &newOrder, NodeArray< ListIterator< adjEntry > > &adjBeforeNodeArraySource, NodeArray< ListIterator< adjEntry > > &adjBeforeNodeArrayTarget, const T &delta_u, const T &delta_d, adjEntry &adjExternal)
static void expandEdgeSNode(const StaticSPQRTree &spqrTree, NodeArray< bool > &treeNodeTreated, const node &mu, const node &leftNode, const NodeArray< T > &nodeLength, const NodeArray< EdgeArray< T > > &edgeLength, const NodeArray< T > &thickness, NodeArray< List< adjEntry > > &newOrder, NodeArray< ListIterator< adjEntry > > &adjBeforeNodeArraySource, NodeArray< ListIterator< adjEntry > > &adjBeforeNodeArrayTarget, const T &delta_u, const T &delta_d, adjEntry &adjExternal)
static void bottomUpThickness(const StaticSPQRTree &spqrTree, const node &mu, NodeArray< T > &thickness, const NodeArray< T > &nodeLength, const NodeArray< EdgeArray< T > > &edgeLength)
static void expandEdgeRNode(const StaticSPQRTree &spqrTree, NodeArray< bool > &treeNodeTreated, const node &mu, const node &leftNode, const NodeArray< T > &nodeLength, const NodeArray< EdgeArray< T > > &edgeLength, const NodeArray< T > &thickness, NodeArray< List< adjEntry > > &newOrder, NodeArray< ListIterator< adjEntry > > &adjBeforeNodeArraySource, NodeArray< ListIterator< adjEntry > > &adjBeforeNodeArrayTarget, const T &delta_u, const T &delta_d, adjEntry &adjExternal, const node &n=nullptr)
static void embed(Graph &G, adjEntry &adjExternal, const NodeArray< T > &nodeLength, const EdgeArray< T > &edgeLength, const node &n=nullptr)
Embeds G by computing and extending a maximum face in G containing n.
Faces in a combinatorial embedding.
internal::FaceAdjContainer entries
Container maintaining the adjacency entries in the face.
Data type for general directed graphs (adjacency list representation).
void sort(node v, const ADJ_ENTRY_LIST &newOrder)
Sorts the adjacency list of node v according to newOrder.
virtual void delNode(node v)
Removes node v and all incident edges from the graph.
internal::GraphObjectContainer< NodeElement > nodes
The container containing all node objects.
void allNodes(CONTAINER &nodeContainer) const
Returns a container with all nodes of the graph.
node newNode(int index=-1)
Creates a new node and returns it.
edge newEdge(node v, node w, int index=-1)
Creates a new edge (v,w) and returns it.
internal::GraphObjectContainer< EdgeElement > edges
The container containing all edge objects.
Doubly linked lists (maintaining the length of the list).
int size() const
Returns the number of elements in the list.
iterator pushBack(const E &x)
Adds element x at the end of the list.
iterator insertBefore(const E &x, iterator it)
Inserts element x before it.
iterator pushFront(const E &x)
Adds element x at the beginning of the list.
iterator insertAfter(const E &x, iterator it)
Inserts element x after it.
Encapsulates a pointer to a list element.
bool valid() const
Returns true iff the iterator points to an element.
iterator begin()
Returns an iterator to the first element of the list.
const_iterator cyclicPred(const_iterator it) const
Returns a const iterator to the cyclic predecessor of it.
const_iterator get(int pos) const
Returns a const iterator pointing to the element at position pos.
ListConstIterator< E > search(const E &e) const
Scans the list for the specified element and returns an iterator to the first occurrence in the list,...
Class for the representation of nodes.
int degree() const
Returns the degree of the node (indegree + outdegree).
internal::GraphObjectContainer< AdjElement > adjEntries
The container containing all entries in the adjacency list of this node.
adjEntry firstAdj() const
Returns the first entry in the adjaceny list.
adjEntry lastAdj() const
Returns the last entry in the adjacency list.
void init(const Base *base=nullptr)
Reinitializes the array. Associates the array with the matching registry of base.
Skeleton graphs of nodes in an SPQR-tree.
virtual edge twinEdge(edge e) const =0
Returns the twin edge of skeleton edge e.
virtual node original(node v) const =0
Returns the vertex in the original graph G that corresponds to v.
virtual edge realEdge(edge e) const =0
Returns the real edge that corresponds to skeleton edge e.
virtual node twinTreeNode(edge e) const =0
Returns the tree node in T containing the twin edge of skeleton edge e.
const Graph & getGraph() const
Returns a reference to the skeleton graph M.
virtual bool isVirtual(edge e) const =0
Returns true iff e is a virtual edge.
edge referenceEdge() const
Returns the reference edge of S in M.
Linear-time implementation of static SPQR-trees.
node rootTreeAt(edge e) override
Roots T at edge e and returns the new root node of T.
const Graph & tree() const override
Returns a reference to the tree T.
Skeleton & skeleton(node v) const override
Returns the skeleton of node v.
const Graph & originalGraph() const override
Returns a reference to the original graph G.
const Skeleton & skeletonOfReal(edge e) const override
Returns the skeleton that contains the real edge e.
NodeType typeOf(node v) const override
Returns the type of node v.
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
RegisteredArray for nodes, edges and adjEntries of a graph.
Declaration of extended graph algorithms.
bool planarEmbed(Graph &G)
Returns true, if G is planar, false otherwise. If true is returned, G will be planarly embedded.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
TWeight infinity()
Helper function to get the maximum value for a given weight type.
The namespace for all OGDF objects.