Ejemplo n.º 1
0
void SubgraphUpwardPlanarizer::merge(
	const GraphCopy &GC,
	UpwardPlanRep &UPR_res,
	const GraphCopy &block,
	UpwardPlanRep &UPR)
{
	node startUPR = UPR.getSuperSource()->firstAdj()->theEdge()->target();
	node startRes;

	node startG = GC.original(block.original(UPR.original(startUPR)));

	bool empty = UPR_res.empty();

	if (empty) {

		OGDF_ASSERT(startG == 0);

		// contruct a node in UPR_res assocciated with startUPR
		startRes = UPR_res.newNode();
		UPR_res.m_isSinkArc.init(UPR_res, false);
		UPR_res.m_isSourceArc.init(UPR_res, false);
		UPR_res.s_hat = startRes;
	}
	else {
		startRes = UPR_res.copy(startG);
	}

	OGDF_ASSERT(startRes != 0);

	// compute the adjEntry position (in UPR_res) of the cutvertex startRes
	adjEntry pos = nullptr;
	if (!empty) {
		adjEntry adj_ext = nullptr, adj_int = nullptr;
		for(adjEntry run : startRes->adjEntries) {
			if (UPR_res.getEmbedding().rightFace(run) == UPR_res.getEmbedding().externalFace()) {
				adj_ext = run;
				break;
			}
			if (run->theEdge()->source() == startRes)
				adj_int = run;
		}
		// cutvertex is a sink in UPR_res
		if (adj_ext == nullptr && adj_int == nullptr) {
			pos = UPR_res.sinkSwitchOf(startRes);
		}
		else {
			if (adj_ext == nullptr)
				pos = adj_int;
			else
				pos = adj_ext;
		}
		OGDF_ASSERT(pos != 0);
	}

	// construct for each node (except the two super sink and the super source) of UPR a associated of UPR to UPR_res
	NodeArray<node> nodeUPR2UPR_res(UPR, nullptr);
	nodeUPR2UPR_res[startUPR] = startRes;
	for(node v : UPR.nodes) {

		// allready constructed or is super sink or super source
		if (v == startUPR || v == UPR.getSuperSink() || v == UPR.getSuperSink()->firstAdj()->theEdge()->source() || v == UPR.getSuperSource())
			continue;

		node vNew;
		if (UPR.original(v) != nullptr ) {
			node vG = GC.original(block.original((UPR.original(v))));
			if (vG != nullptr)
				vNew = UPR_res.newNode(vG);
			else
				vNew = UPR_res.newNode(); //vG is the super source
		}
		else // crossing dummy, no original node
			vNew = UPR_res.newNode();
		nodeUPR2UPR_res[v] = vNew;
	}

	//add edges of UPR to UPR_res
	EdgeArray<edge> edgeUPR2UPR_res(UPR, nullptr);
	for(edge e : block.edges) {

		if (e->source()->indeg()==0) // the artificial edge with the super source
			continue;

		List<edge> chains = UPR.chain(e);
		edge eG = nullptr, eGC = block.original(e);
		eG = GC.original(eGC);

		OGDF_ASSERT(!chains.empty());

		//construct new edges in UPR_res
		for(edge eChain : chains) {
			node tgt = nodeUPR2UPR_res[eChain->target()];
			node src = nodeUPR2UPR_res[eChain->source()];
			edge eNew = UPR_res.newEdge(src, tgt);
			edgeUPR2UPR_res[eChain] = eNew;

			if (UPR.isSinkArc(UPR.copy(e)))
				UPR_res.m_isSinkArc[eNew] = true;
			if (UPR.isSourceArc(UPR.copy(e)))
				UPR_res.m_isSourceArc[eNew] = true;

			if (eG == nullptr) { // edge is associated with a sink arc
				UPR_res.m_eOrig[eNew] = nullptr;
				continue;
			}

			UPR_res.m_eOrig[eNew] = eG;
			if (chains.size() == 1) { // e is not split
				UPR_res.m_eCopy[eG].pushBack(eNew);
				UPR_res.m_eIterator[eNew] = UPR_res.m_eCopy[eG].begin();
				break;
			}
			UPR_res.m_eCopy[eG].pushBack(eNew);
			UPR_res.m_eIterator[eNew] = UPR_res.m_eCopy[eG].rbegin();
		}
	}


	///*
	//* embed the new component in UPR_res with respect to the embedding of UPR
	//*/

	// for the cut vertex
	if (!empty) {
		adjEntry run = UPR.getAdjEntry(UPR.getEmbedding(), startUPR, UPR.getEmbedding().externalFace());
		run = run->cyclicSucc();
		adjEntry adjStart = run;
		do {
			if (edgeUPR2UPR_res[run->theEdge()] != nullptr) {
				adjEntry adj_UPR_res = edgeUPR2UPR_res[run->theEdge()]->adjSource();
				UPR_res.moveAdjAfter(adj_UPR_res, pos);
				pos = adj_UPR_res;
			}
			run = run->cyclicSucc();
		} while(run != adjStart);
	}

	for(node v : UPR.nodes) {
		if (v == startUPR && !empty)
			continue;

		node v_UPR_res = nodeUPR2UPR_res[v];
		List<adjEntry> adj_UPR, adj_UPR_res;
		v->allAdjEntries(adj_UPR);

		// convert adj_UPR of v to adj_UPR_res of v_UPR_res
		for(adjEntry adj : adj_UPR) {
			edge e_res = edgeUPR2UPR_res[adj->theEdge()];
			if (e_res == nullptr) // associated edges in UPR_res
				continue;
			adjEntry adj_res = e_res->adjSource();
			if (adj_res->theNode() != v_UPR_res)
				adj_res = adj_res->twin();
			adj_UPR_res.pushBack(adj_res);
		}

		UPR_res.sort(v_UPR_res, adj_UPR_res);
	}

	/*
	//---------------------------------------------------debug
	if (!UPR_res.empty()) {
		GraphAttributes GA_UPR_res(UPR_res, GraphAttributes::nodeGraphics|
				GraphAttributes::edgeGraphics|
				GraphAttributes::nodeColor|
				GraphAttributes::edgeColor|
				GraphAttributes::nodeLabel|
				GraphAttributes::edgeLabel
				);
		GA_UPR_res.setAllHeight(30.0);
		GA_UPR_res.setAllWidth(30.0);
		// label the nodes with their index
		for(node z : GA_UPR_res.constGraph().nodes) {
			GA_UPR_res.label(z) = to_string(z->index());
		}
		GA_UPR_res.writeGML("c:/temp/UPR_res_tmp.gml");
		cout << "UPR_res_tmp faces:";
		UPR_res.outputFaces(UPR_res.getEmbedding());
	}

	GraphAttributes GA_UPR(UPR, GraphAttributes::nodeGraphics|
				GraphAttributes::edgeGraphics|
				GraphAttributes::nodeColor|
				GraphAttributes::edgeColor|
				GraphAttributes::nodeLabel|
				GraphAttributes::edgeLabel
				);
	GA_UPR.setAllHeight(30.0);
	GA_UPR.setAllWidth(30.0);
	// label the nodes with their index
	for(node z : GA_UPR.constGraph().nodes) {
		GA_UPR.label(z) = to_string(z->index());
	}
	GA_UPR.writeGML("c:/temp/UPR_tmp.gml");
	cout << "UPR_tmp faces:";
	UPR.outputFaces(UPR.getEmbedding());
	//end -----------------------------------------------debug
	*/

	// update UPR_res
	UPR_res.initMe();
}
Ejemplo n.º 2
0
void VisibilityLayout::constructDualGraph(UpwardPlanRep &UPR)
{
	CombinatorialEmbedding &gamma = UPR.getEmbedding();

	faceToNode.init(gamma, nullptr);
	leftFace_node.init(UPR, nullptr);
	rightFace_node.init(UPR, nullptr);
	leftFace_edge.init(UPR, nullptr);
	rightFace_edge.init(UPR, nullptr);

	//construct a node for each face f
	for(face f : gamma.faces) {
		faceToNode[f] = D.newNode();

		if (f == gamma.externalFace())
			s_D = faceToNode[f] ;

		//compute face switches
		node s = nullptr, t = nullptr;
		for(adjEntry adj : f->entries) {
			adjEntry adjNext = adj->faceCycleSucc();
			if (adjNext->theEdge()->source() == adj->theEdge()->source())
				s = adjNext->theEdge()->source();
			if (adjNext->theEdge()->target() == adj->theEdge()->target())
				t = adjNext->theEdge()->target();
		}
		OGDF_ASSERT(s);
		OGDF_ASSERT(t);

		//compute left and right face
		bool passSource = false;
		adjEntry adj;
		if (f == gamma.externalFace()) {
			adj = UPR.getSuperSink()->firstAdj();
			if (gamma.rightFace(adj) != gamma.externalFace())
				adj = adj->cyclicSucc();
		}
		else
			adj = UPR.getAdjEntry(gamma, t, f);

		adjEntry adjBegin = adj;
		do {
			node v = adj->theEdge()->source();
			if (!passSource) {
				if (v != s)
					leftFace_node[v] = f;
				leftFace_edge[adj->theEdge()] = f;
			}
			else {
				if (v != s)
					rightFace_node[v] = f;
				rightFace_edge[adj->theEdge()] = f;
			}
			if (adj->theEdge()->source() == s)
				passSource = true;
			adj = adj->faceCycleSucc();
		} while(adj != adjBegin);
	}
	t_D = D.newNode(); // the second (right) node associated with the external face

	//construct dual edges
	for(edge e : UPR.edges) {
		face f_r = rightFace_edge[e];
		face f_l = leftFace_edge[e];
		node u = faceToNode[f_l];
		node v = faceToNode[f_r];
		if (f_r == gamma.externalFace() || f_r == f_l)
			D.newEdge(u, t_D);
		else
			D.newEdge(u,v);
	}

	OGDF_ASSERT(isConnected(D));
}