//insert a copy for original node v
void SimpleIncNodeInserter::insertCopyNode(node v, Graph::NodeType vTyp)
{
	OGDF_ASSERT(m_planRep->copy(v) == 0)

	//insert a new node copy
	node vCopy = m_planRep->newCopy(v, vTyp);
	if (v->degree() == 0) return;
	//insert all adjacent edges to already inserted nodes
	adjEntry adjOrig = v->firstAdj();
	do
	{
		node wOrig = adjOrig->twinNode();
		node wCopy = m_planRep->copy(wOrig);
		edge e = adjOrig->theEdge();
		if (wCopy && (m_planRep->chain(e).size() == 0))
		{
			//inserted edge copy
			//edge eCopy;
			//newCopy can cope with zero value for adjEntry
			if (v == e->source())
				/* eCopy = */ m_planRep->newCopy(vCopy, wCopy->firstAdj(), e);
			else
				/* eCopy = */ m_planRep->newCopy(wCopy, vCopy->firstAdj(), e);

			//TODO: update component number in planrepinc

		}//if edge to be inserted
		adjOrig = adjOrig->cyclicSucc();
	} while (adjOrig != v->firstAdj());
}//insertCopyNode
Exemple #2
0
void LCA::dfs(const Graph &G, node root)
{
	OGDF_ASSERT(isSimple(G));
	OGDF_ASSERT(isArborescence(G));
	List< std::pair<node,int> > todo;
	List< adjEntry > adjStack;
	int dfscounter = 0;
	todo.pushBack(std::pair<node,int>(root, 0));
	adjStack.pushBack(root->firstAdj());

	while (!todo.empty()) {
		const node u = todo.back().first;
		const int level = todo.back().second;
		adjEntry adj = adjStack.popBackRet();

		m_euler[dfscounter] = u;
		m_level[dfscounter] = level;
		m_representative[u] = dfscounter;

		while (adj && adj->theEdge()->source() != u) {
			adj = adj->succ();
		}
		if (adj) {
			node v = adj->twinNode();
			adjStack.pushBack(adj->succ());
			todo.pushBack(std::pair<node,int>(v, level + 1));
			adjStack.pushBack(v->firstAdj());
		} else {
			todo.popBack();
		}
		++dfscounter;
	}
}
	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;
			}
		}
	}
Exemple #4
0
    forall_nodes(v, primalGraph)
    {
		edge ePrimal = v->firstAdj()->theEdge();
		edge eDual = m_dualEdge[ePrimal];
		face fDual = rightFace(eDual->adjSource());
		if(ePrimal->source()==v)
			fDual = leftFace(eDual->adjSource());
		m_dualFace[v] = fDual;
		m_primalNode[fDual] = v;
    }
Exemple #5
0
//compute a drawing of the clique around node center and save its size
//the call to circular will later be replaced by an dedicated computation
DRect UMLGraph::circularBound(node center)
{

	//TODO: hier computecliqueposition(0,...) benutzen, rest weglassen
	DRect bb;
	CircularLayout cl;
	Graph G;
	GraphAttributes AG(G);
	NodeArray<node> umlOriginal(G);

	//TODO: we need to assure that the circular drawing
	//parameters fit the drawing parameters of the whole graph
	//umlgraph clique parameter members?

	OGDF_ASSERT(center->degree() > 0)
	node lastNode = nullptr;
	node firstNode = nullptr;

	adjEntry ae = center->firstAdj();
	do {
		node w = ae->twinNode();
		node v = G.newNode();
		umlOriginal[v] = w;

		if (!firstNode) firstNode = v;
		AG.width(v) = width(w);
		AG.height(v) = height(w);
		ae = ae->cyclicSucc();
		if (lastNode != nullptr) G.newEdge(lastNode, v);
		lastNode = v;
	} while (ae != center->firstAdj());
	G.newEdge(lastNode, firstNode);

	cl.call(AG);

	for(node v : G.nodes)
	{
		m_cliqueCirclePos[umlOriginal[v]] = DPoint(AG.x(v), AG.y(v));
	}
	bb = AG.boundingBox();

	return bb;
}//circularBound
Exemple #6
0
//*************************************************************
// checks whether node is a proper dummy node
// proper dummy means that node is marked as dummy and 
// incident edges have at least one common input graph
bool SimDraw::isProperDummy(node v) const
{
    if(!isDummy(v))
	return false;
    int sgb = m_GA.subGraphBits(v->firstAdj()->theEdge());
    edge e;
    forall_adj_edges(e, v)
	sgb &= m_GA.subGraphBits(e);
    
    return (sgb != 0);

} // end isProperDummy
Exemple #7
0
    forall_nodes(v,PG)
    {
        if (PG.typeOf(v) == PlanRepUML::dummy && v->degree() == 4) {
            adjEntry adj = v->firstAdj();

            edge e1 = adj->theEdge();
            edge e2 = adj->succ()->theEdge();

            if (PG.typeOf(e1) == Graph::generalization &&
                    PG.typeOf(e2) == Graph::generalization)
                return false;
        }
    }
	void EmbedderOptimalFlexDraw::computePrincipalSplitComponentCost(
		StaticPlanarSPQRTree &T,
		NodeArray<int> cost[],
		NodeArray<long long> embedding[],
		node parent,
		node mu)
	{
		for (adjEntry adj = mu->firstAdj(); adj != nullptr; adj = adj->succ())
			if (adj->twinNode() != parent)
				computePrincipalSplitComponentCost(T, cost, embedding, mu, adj->twinNode());

		for (int bends = 0; bends < 4; ++bends)
			optimizeOverEmbeddings(T, parent, mu, bends, cost, embedding);
	}
Exemple #9
0
void PlanRep::removeCrossing(node v)
{
	OGDF_ASSERT(v->degree() == 4)
	OGDF_ASSERT(isCrossingType(v))

	adjEntry a1 = v->firstAdj();
	adjEntry b1 = a1->cyclicSucc();
	adjEntry a2 = b1->cyclicSucc();
	adjEntry b2 = a2->cyclicSucc();

	removeUnnecessaryCrossing(a1, a2, b1, b2);


}//removeCrossing
void CombinatorialEmbedding::removeDeg1(node v)
{
	OGDF_ASSERT(v->degree() == 1);

	adjEntry adj = v->firstAdj();
	face     f   = m_rightFace[adj];

	if (f->entries.m_adjFirst == adj || f->entries.m_adjFirst == adj->twin())
		f->entries.m_adjFirst = adj->faceCycleSucc();
	f->m_size -= 2;

	m_pGraph->delNode(v);

	OGDF_ASSERT_IF(dlConsistencyChecks, consistencyCheck());
}
Exemple #11
0
void MinCut::contraction(node t, node s) {

	/*
	 * The contraction of the two nodes \as and \a t is performed as follows:
	 * in the first step, all edges between \a s and \a t are deleted, and all edges incident
	 * to \a s are redirected to \a t. Then, node \a s is deleted and the adjacency list of \a t
	 * is checked for parallel edges. If k parallel edges are found, k-1 of them are deleted
	 * and their weights are added to the edge that is left.
	 */

	// Step 1: redirecting edges and deleting node \a s
	adjEntry adj = s->firstAdj();
	while (adj != 0)
	{
		adjEntry succ = adj->succ();
		edge e = adj->theEdge();
		if (e->source() == t || e->target() == t) {
			m_GC.delEdge(e);
		}
		else if (e->source() == s) {
			m_GC.moveSource(e,t);
		}
		else {
			m_GC.moveTarget(e,t);
		}
		adj = succ;
	}
	m_GC.delNode(s);

	/*
	 * Because of technical problems that occur when deleting edges and thus adjacency entries in a loop,
	 * a NodeArray is filled with the edges incident to node \a t.
	 * This NodeArray is checked for entries with more than one edge, which corresponds
	 * to parallel edges.
	 */

	// NodeArray containing parallel edges
	NodeArray<List<edge> > adjNodes(m_GC);

	forall_adj(adj,t) {
		adjNodes[adj->twinNode()].pushBack(adj->theEdge());
	}
Exemple #12
0
// calculates the lowpoints
void BoyerMyrvoldInit::computeLowPoints()
{
	node w;
	adjEntry adj,lastAdj;

	for (int i = m_g.numberOfNodes(); i >= 1; --i) {
		const node v = m_nodeFromDFI[i];

		// initialize lowpoints with least Ancestors and highpoints with dfi of node
		m_lowPoint[v] = m_leastAncestor[v];
		if (m_embeddingGrade > BoyerMyrvoldPlanar::doNotFind) m_highestSubtreeDFI[v] = i;

		// set the lowPoint of v by minimizing over its children lowPoints
		// create virtual vertex for each child
		adj = v->firstAdj();
		while (adj) {
			lastAdj = adj;
			adj = adj->succ();

			// avoid self-loops, parallel- and backedges
			if (m_edgeType[lastAdj->theEdge()] != EDGE_DFS) continue;
			w = lastAdj->twinNode();

			// avoid parent dfs-node
			if (m_dfi[w] <= i) continue;

			// set lowPoints and highpoints
			if (m_lowPoint[w] < m_lowPoint[v]) m_lowPoint[v] = m_lowPoint[w];
			if (m_embeddingGrade > BoyerMyrvoldPlanar::doNotFind &&
									m_highestSubtreeDFI[w] > m_highestSubtreeDFI[v])
				m_highestSubtreeDFI[v] = m_highestSubtreeDFI[w];

			// create virtual vertex for each dfs-child
			createVirtualVertex(lastAdj);
		}
	}
}
	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()];
				}
			}
		}
	}