void MixedModelLayout::doCall(
	PlanRep &PG,
	adjEntry adjExternal,
	GridLayout &gridLayout,
	IPoint &boundingBox,
	bool fixEmbedding)
{
	// handle graphs with less than 3 nodes
	node v1, v2;
	switch (PG.numberOfNodes()) {
	case 0:
		boundingBox = IPoint(0,0);
		return;

	case 1:
		v1 = PG.firstNode();
		gridLayout.x(v1) = gridLayout.y(v1) = 0;
		boundingBox = IPoint(0,0);
		return;

	case 2:
		v1 = PG.firstNode();
		v2 = v1->succ();
		gridLayout.x(v1) = gridLayout.y(v1) = gridLayout.y(v2) = 0;
		gridLayout.x(v2) = 1;
		boundingBox = IPoint(1,0);
		return;
	}

	MixedModelBase mm(PG,gridLayout);

	if(fixEmbedding) {
		OGDF_ASSERT(PG.representsCombEmbedding());
		PlanarAugmentationFix fixAugmenter;
		mm.computeOrder(fixAugmenter, 0, adjExternal, m_compOrder.get());
	} else
		mm.computeOrder(m_augmenter.get(),&m_embedder.get(),0,m_compOrder.get());

	mm.assignIopCoords();
	mm.placeNodes();
	mm.postprocessing1();
	mm.setBends();
	mm.postprocessing2();

	m_crossingsBeautifier.get().call(PG,gridLayout);

	int xmin, ymin;
	gridLayout.computeBoundingBox(xmin,boundingBox.m_x,ymin,boundingBox.m_y);
}
Esempio n. 2
0
Module::ReturnType SubgraphPlanarizer::doCall(PlanRep &PG,
	int cc,
	const EdgeArray<int>  &cost,
	const EdgeArray<bool> &forbid,
	const EdgeArray<unsigned int>  &subgraphs,
	int& crossingNumber)
{
	OGDF_ASSERT(m_permutations >= 1);
  
	OGDF_ASSERT(!(useSubgraphs()) || useCost()); // ersetze durch exception handling

	double startTime;
	usedTime(startTime);

	if(m_setTimeout)
		m_subgraph.get().timeLimit(m_timeLimit);

	List<edge> deletedEdges;
	PG.initCC(cc);
	EdgeArray<int> costPG(PG);
	edge e;
	forall_edges(e,PG)
		costPG[e] = cost[PG.original(e)];
	ReturnType retValue = m_subgraph.get().call(PG, costPG, deletedEdges);
	if(isSolution(retValue) == false)
		return retValue;

	for(ListIterator<edge> it = deletedEdges.begin(); it.valid(); ++it)
		*it = PG.original(*it);

	bool foundSolution = false;
	CrossingStructure cs;
	for(int i = 1; i <= m_permutations; ++i)
	{
		const int nG = PG.numberOfNodes();
		
		for(ListConstIterator<edge> it = deletedEdges.begin(); it.valid(); ++it)
			PG.delCopy(PG.copy(*it));

		deletedEdges.permute();
	
		if(m_setTimeout)
			m_inserter.get().timeLimit(
				(m_timeLimit >= 0) ? max(0.0,m_timeLimit - usedTime(startTime)) : -1);
		
		ReturnType ret;
		if(useForbid()) {
			if(useCost()) {
				if(useSubgraphs())
					ret = m_inserter.get().call(PG, cost, forbid, deletedEdges, subgraphs);
				else
					ret = m_inserter.get().call(PG, cost, forbid, deletedEdges);
			} else
				ret = m_inserter.get().call(PG, forbid, deletedEdges);
		} else {
			if(useCost()) {	
				if(useSubgraphs())
					ret = m_inserter.get().call(PG, cost, deletedEdges, subgraphs);
				else
					ret = m_inserter.get().call(PG, cost, deletedEdges);
			} else
				ret = m_inserter.get().call(PG, deletedEdges);
		}

		if(isSolution(ret) == false)
			continue; // no solution found, that's bad...
	
		if(!useCost())
			crossingNumber = PG.numberOfNodes() - nG;
		else {
			crossingNumber = 0;
			node n;
			forall_nodes(n, PG) {
				if(PG.original(n) == 0) { // dummy found -> calc cost
					edge e1 = PG.original(n->firstAdj()->theEdge());
					edge e2 = PG.original(n->lastAdj()->theEdge());
					if(useSubgraphs()) {
						int subgraphCounter = 0;
						for(int i=0; i<32; i++) {
							if(((subgraphs[e1] & (1<<i))!=0) && ((subgraphs[e2] & (1<<i)) != 0))
								subgraphCounter++;
						}
						crossingNumber += (subgraphCounter*cost[e1] * cost[e2]);
					} else
						crossingNumber += cost[e1] * cost[e2];
				}
			}
		}
		
		if(i == 1 || crossingNumber < cs.weightedCrossingNumber()) {
			foundSolution = true;
			cs.init(PG, crossingNumber);
		}
		
		if(localLogMode() == LM_STATISTIC) {
			if(m_permutations <= 200 ||
				i <= 10 || (i <= 30 && (i % 2) == 0) || (i > 30 && i <= 100 && (i % 5) == 0) || ((i % 10) == 0))
				sout() << "\t" << cs.weightedCrossingNumber();
		}
		
		PG.initCC(cc);

		if(m_timeLimit >= 0 && usedTime(startTime) >= m_timeLimit) {
			if(foundSolution == false)
				return retTimeoutInfeasible; // not able to find a solution...
			break;
		}
	}
	
	cs.restore(PG,cc); // restore best solution in PG
	crossingNumber = cs.weightedCrossingNumber();
	
	PlanarModule pm;
	OGDF_ASSERT(pm.planarityTest(PG) == true);
	
	return retFeasible;
}