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()]; } } } }