Пример #1
0
void MultiEdgeApproxInserter::Block::initSPQR(int m)
{
	if(m_spqr == 0) {
		m_spqr = new StaticPlanarSPQRTree(*this,true);
		m_pathSPQR.init(m);

		const Graph &tree = m_spqr->tree();
		m_tc.init(tree);
		m_info.init(tree);

		// compute allocation nodes
		m_allocNodes.init(*this);

		node n;
		forall_nodes(n,tree)
		{
			const Skeleton &S = m_spqr->skeleton(n);
			const Graph &M = S.getGraph();

			EdgeArray<int> &tcS = m_tc[n];
			tcS.init(M,-1);

			node x;
			forall_nodes(x,M)
				m_allocNodes[S.original(x)].pushBack(n);

			edge e;
			forall_edges(e,M) {
				edge eOrig = S.realEdge(e);
				if(eOrig != 0) tcS[e] = 1;
			}
		}
Пример #2
0
void FruchtermanReingold :: calculate_exact_repulsive_forces(const Graph &G, NodeArray
                            <NodeAttributes> &A, NodeArray<DPoint>& F_rep)
{
	//naive algorithm by Fruchterman & Reingold
	mathExtension M;
	numexcept N;
	node v,u;
	DPoint f_rep_u_on_v;
	DPoint vector_v_minus_u;
	DPoint pos_u,pos_v;
	DPoint nullpoint (0,0);
	double norm_v_minus_u;
	long node_number = G.numberOfNodes();
	Array<node> array_of_the_nodes (node_number+1);
	long counter = 1;
	long i,j; 
	double scalar;

	forall_nodes(v,G)
		F_rep[v]= nullpoint;

	forall_nodes(v,G)
	{
		array_of_the_nodes[counter]=v;
		counter++;   
	}    
//
// destructor: deletes skeleton graphs
//
StaticSPQRTree::~StaticSPQRTree()
{
	node vT;

	forall_nodes(vT,m_tree)
		delete m_sk[vT];

	delete m_cpV;
}
void ComponentSplitterLayout::call(GraphAttributes &GA)
{
	// Only do preparations and call if layout is valid
	if (m_secondaryLayout.valid())
	{
		//first we split the graph into its components
		const Graph& G = GA.constGraph();

		NodeArray<int> componentNumber(G);
		m_numberOfComponents = connectedComponents(G, componentNumber);
		if (m_numberOfComponents == 0) {
			return;
		}

		//std::vector< std::vector<node> > componentArray;
		//componentArray.resize(numComponents);
		//Array<GraphAttributes *> components(numComponents);
		//

		// intialize the array of lists of nodes contained in a CC
		nodesInCC.init(m_numberOfComponents);

		node v;
		forall_nodes(v,G)
			nodesInCC[componentNumber[v]].pushBack(v);

		 // Create copies of the connected components and corresponding
		 // GraphAttributes
		 GraphCopy GC;
		 GC.createEmpty(G);

		 EdgeArray<edge> auxCopy(G);

		 for (int i = 0; i < m_numberOfComponents; i++)
		 {
			 GC.initByNodes(nodesInCC[i],auxCopy);
			 GraphAttributes cGA(GC);
			 //copy information into copy GA
			 forall_nodes(v, GC)
			 {
				cGA.width(v) = GA.width(GC.original(v));
				cGA.height(v) = GA.height(GC.original(v));
				cGA.x(v) = GA.x(GC.original(v));
				cGA.y(v) = GA.y(GC.original(v));
			 }
			 m_secondaryLayout.get().call(cGA);

			 //copy layout information back into GA
			 forall_nodes(v, GC)
			 {
				 node w = GC.original(v);
				 if (w != 0)
					 GA.x(w) = cGA.x(v);
				 GA.y(w) = cGA.y(v);
			 }
		 }
void EnergyFunction::printStatus() const{
	cout << "\nEnergy function name: " << m_name;
	cout << "\nCurrent energy: " << m_energy;
	node v;
	cout << "\nPosition of nodes in current solution:";
	NodeArray<int> num(m_G);
	int count = 1;
	forall_nodes(v,m_G) num[v] = count ++;
	forall_nodes(v,m_G) {
		cout << "\nNode: " << num[v] << " Position: " << currentPos(v);
	}
Пример #6
0
bool Delaunay3D::Invoke() {
    typedef leda::d3_rat_point point3_t;

    _simplices.clear();

    if(!NB::FirstSelectedMesh()) {
        NB::LogPrintf("no geometry selected.\n");
        return false;
    }

    NB::SetOperatorName("Delaunay 3D");

    NB::Mesh cloud = NB::FirstSelectedMesh();
    COM_assert(cloud);

    leda::nb::RatPolyMesh& cloudGraph = NB::GetGraph(cloud);
    leda::list<point3_t> L;
    leda::node v;
    forall_nodes(v, cloudGraph) L.push_back(cloudGraph.position_of(v));

    leda::list<leda::fork::simplex_t> S;

    std::cout << "Delaunay3D: calling D3_DELAUNAY ... " << std::flush;
    // NOTE: include d3_delaunay.cpp when building LEDA
    leda::fork::D3_DELAUNAY(L, S);
    std::cout << "DONE" << std::endl;

    _mesh = NB::CreateMesh();
    NB::SetMeshRenderMode(_mesh, NB::RM_ALL);
    NB::SetMeshPosition(_mesh, NB::GetMeshPosition(cloud));
    leda::nb::RatPolyMesh& graph = NB::GetGraph(_mesh);

    std::cout << "Delaunay3D: creating simplex geometries ... " << std::flush;
    leda::list_item it;
    forall_items(it, S) {
        Simplex simplex;

        simplex.center = leda::rat_vector::zero(3);
        leda::rat_vector pos[4];
        for(int i = 0; i < 4; ++i) {
            pos[i] = S[it].verts[i].to_vector();
            simplex.center += pos[i];

            simplex.verts[i] = graph.new_node();
            graph.set_position(simplex.verts[i], pos[i]);
        }
        simplex.center /= 4;
        for(int i = 0; i < 4; ++i) simplex.localPos[i] = pos[i] - simplex.center;
        AddFace(graph, simplex.verts[0], simplex.verts[1], simplex.verts[2], simplex.verts[3]);

        _simplices.push_back(simplex);
    }
Пример #7
0
// extract and add external subgraph from stopnode to ancestors of the node with dfi root
// to edgelist, nodeMarker is used as a visited flag. returns the endnode with lowest dfi.
void FindKuratowskis::extractExternalSubgraphBundles(
			const node stop,
			int root,
			SListPure<edge>& externalSubgraph,
			int nodeMarker)
{
	node v,temp;
	adjEntry adj;

	#ifdef OGDF_DEBUG
	forall_nodes(v,m_g) OGDF_ASSERT(m_wasHere[v]!=nodeMarker);
	#endif

	StackPure<node> stack; // stack for dfs-traversal
	ListConstIterator<node> it;
	stack.push(stop);
	while (!stack.empty()) {
		v = stack.pop();
		if (m_wasHere[v]==nodeMarker) continue;
		// mark visited nodes
		m_wasHere[v]=nodeMarker;

		// search for unvisited nodes and add them to stack
		forall_adj(adj,v) {
			temp = adj->twinNode();
			if (m_edgeType[adj->theEdge()]==EDGE_BACK_DELETED) continue;

			// go along backedges to ancestor (ignore virtual nodes)
			if (m_dfi[temp] < root && m_dfi[temp] > 0) {
				OGDF_ASSERT(m_edgeType[adj->theEdge()]==EDGE_BACK);
				externalSubgraph.pushBack(adj->theEdge());
			} else if (v != stop && m_dfi[temp]>=m_dfi[v]) {
				// set flag and push unvisited nodes
				OGDF_ASSERT(m_edgeType[adj->theEdge()]==EDGE_BACK ||
							m_edgeType[adj->theEdge()]==EDGE_DFS ||
							m_edgeType[adj->theEdge()]==EDGE_BACK_DELETED);
				externalSubgraph.pushBack(adj->theEdge());
				if (m_wasHere[temp] != nodeMarker) stack.push(temp);
			}
		}

		// descent to external active child bicomps
		for (it = m_separatedDFSChildList[v].begin(); it.valid(); ++it) {
			temp = *it;
			if (m_lowPoint[temp] >= root) break;
			stack.push(m_nodeFromDFI[-m_dfi[temp]]);
		}
	}
Пример #8
0
//*************************************************************
// call for PlanarizationLayoutUML
void SimDrawCaller::callPlanarizationLayout()
{
	m_SD->addAttribute(GraphAttributes::nodeGraphics);
	m_SD->addAttribute(GraphAttributes::edgeGraphics);

	// nodes get default size
	node v;
	forall_nodes(v, *m_G)
		m_GA->height(v) = m_GA->width(v) = 5.0;


	// actual call on PlanarizationLayout
	PlanarizationLayout PL;
	PL.callSimDraw(*m_GA);

} // end callPlanarizationLayout
Пример #9
0
//*************************************************************
// call for SugiyamaLayout
void SimDrawCaller::callSugiyamaLayout()
{
	m_SD->addAttribute(GraphAttributes::nodeGraphics);
	m_SD->addAttribute(GraphAttributes::edgeGraphics);

	// nodes get default size
	node v;
	forall_nodes(v, *m_G)
		m_GA->height(v) = m_GA->width(v) = 5.0;

	// actual call of SugiyamaLayout
	updateESG();
	SugiyamaLayout SL;
	SL.setSubgraphs(m_esg); // needed to call SimDraw mode
	SL.call(*m_GA);

} // end callSugiyamaLayout
Пример #10
0
void GraphCopySimple::initGC(const GraphCopySimple &GC,
	NodeArray<node> &vCopy,
	EdgeArray<edge> &eCopy)
{
	m_pGraph = GC.m_pGraph;

	m_vOrig.init(*this,0); m_eOrig.init(*this,0);
	m_vCopy.init(*m_pGraph,0); m_eCopy.init(*m_pGraph,0);

	node v;
	forall_nodes(v,GC)
		m_vCopy[m_vOrig[vCopy[v]] = GC.m_vOrig[v]] = vCopy[v];

	edge e;
	forall_edges(e,GC) {
		edge eOrig = GC.m_eOrig[e];
		m_eOrig[eCopy[e]] = eOrig;
		if (eOrig)
			m_eCopy[eOrig] = eCopy[e];
	}
Пример #11
0
SpringEmbedderFRExact::ArrayGraph::ArrayGraph(GraphAttributes &ga) : m_ga(&ga), m_mapNode(ga.constGraph())
{
	const Graph &G = ga.constGraph();
	m_numNodes = m_numEdges = 0;

	m_orig = 0;
	m_src = m_tgt = 0;
	m_x = m_y = 0;
	m_nodeWeight = 0;
	m_useNodeWeight = false;

	// compute connected components of G
	NodeArray<int> component(G);
	m_numCC = connectedComponents(G,component);

	m_nodesInCC.init(m_numCC);

	node v;
	forall_nodes(v,G)
		m_nodesInCC[component[v]].pushBack(v);
}
Пример #12
0
void SpringEmbedderFR::call(GraphAttributes &AG)
{
	const Graph &G = AG.constGraph();
	if(G.empty())
		return;

	// all edges straight-line
	AG.clearAllBends();

	GraphCopy GC;
	GC.createEmpty(G);

	// compute connected component of G
	NodeArray<int> component(G);
	int numCC = connectedComponents(G,component);

	// intialize the array of lists of nodes contained in a CC
	Array<List<node> > nodesInCC(numCC);

	node v;
	forall_nodes(v,G)
		nodesInCC[component[v]].pushBack(v);

	EdgeArray<edge> auxCopy(G);
	Array<DPoint> boundingBox(numCC);

	int i;
	for(i = 0; i < numCC; ++i)
	{
		GC.initByNodes(nodesInCC[i],auxCopy);

		GraphCopyAttributes AGC(GC,AG);
		node vCopy;
		forall_nodes(vCopy, GC) {
			node vOrig = GC.original(vCopy);
			AGC.x(vCopy) = AG.x(vOrig);
			AGC.y(vCopy) = AG.y(vOrig);
		}

		// original
		if (initialize(GC, AGC) == true)
		{
			for(int i = 1; i <= m_iterations; i++)
				mainStep(GC, AGC);

		}
		cleanup();
		// end original

		node vFirst = GC.firstNode();
		double minX = AGC.x(vFirst), maxX = AGC.x(vFirst),
			minY = AGC.y(vFirst), maxY = AGC.y(vFirst);

		forall_nodes(vCopy,GC) {
			node v = GC.original(vCopy);
			AG.x(v) = AGC.x(vCopy);
			AG.y(v) = AGC.y(vCopy);

			if(AG.x(v)-AG.width (v)/2 < minX) minX = AG.x(v)-AG.width(v) /2;
			if(AG.x(v)+AG.width (v)/2 > maxX) maxX = AG.x(v)+AG.width(v) /2;
			if(AG.y(v)-AG.height(v)/2 < minY) minY = AG.y(v)-AG.height(v)/2;
			if(AG.y(v)+AG.height(v)/2 > maxY) maxY = AG.y(v)+AG.height(v)/2;
		}
Пример #13
0
void OptimalRanking::doCall(
	const Graph& G,
	NodeArray<int> &rank,
	EdgeArray<bool> &reversed,
	const EdgeArray<int> &length,
	const EdgeArray<int> &costOrig)
{
	MinCostFlowReinelt mcf;

	// construct min-cost flow problem
	GraphCopy GC;
	GC.createEmpty(G);

	// compute connected component of G
	NodeArray<int> component(G);
	int numCC = connectedComponents(G,component);

	// intialize the array of lists of nodes contained in a CC
	Array<List<node> > nodesInCC(numCC);

	node v;
	forall_nodes(v,G)
		nodesInCC[component[v]].pushBack(v);

	EdgeArray<edge> auxCopy(G);
	rank.init(G);

	for(int i = 0; i < numCC; ++i)
	{
		GC.initByNodes(nodesInCC[i], auxCopy);
        makeLoopFree(GC);

		edge e;
		forall_edges(e,GC)
			if(reversed[GC.original(e)])
				GC.reverseEdge(e);

		// special cases:
		if(GC.numberOfNodes() == 1) {
			rank[GC.original(GC.firstNode())] = 0;
			continue;
		} else if(GC.numberOfEdges() == 1) {
			e = GC.original(GC.firstEdge());
			rank[e->source()] = 0;
			rank[e->target()] = length[e];
			continue;
		}

		EdgeArray<int> lowerBound(GC,0);
		EdgeArray<int> upperBound(GC,mcf.infinity());
		EdgeArray<int> cost(GC);
		NodeArray<int> supply(GC);

		forall_edges(e,GC)
			cost[e] = -length[GC.original(e)];

		node v;
		forall_nodes(v,GC) {
			int s = 0;
			forall_adj_edges(e,v) {
				if(v == e->source())
					s += costOrig[GC.original(e)];
				else
					s -= costOrig[GC.original(e)];
			}
			supply[v] = s;
		}

		OGDF_ASSERT(isAcyclic(GC) == true);

		// find min-cost flow
		EdgeArray<int> flow(GC);
		NodeArray<int> dual(GC);
#ifdef OGDF_DEBUG
		bool feasible =
#endif
			mcf.call(GC, lowerBound, upperBound, cost, supply, flow, dual);
		OGDF_ASSERT(feasible);

		forall_nodes(v,GC)
			rank[GC.original(v)] = dual[v];
	}
Пример #14
0
void randomTriconnectedGraph(Graph &G, int n, double p1, double p2)
{
	if(n < 4) n = 4;

	// start with K_4
	completeGraph(G,4);

	// nodes[0],...,nodes[i-1] is array of all nodes
	Array<node> nodes(n);

	node v;
	int i = 0;
	forall_nodes(v,G)
		nodes[i++] = v;

	// Will be used below as array of neighbors of v
	Array<edge> neighbors(n);

	// used to mark neighbors
	//   0 = not marked
	//   1 = marked left
	//   2 = marked right
	//   3 = marked both
	Array<int>  mark(0,n-1,0);

	for(; i < n; ++i)
	{
		// pick a random node
		v = nodes[randomNumber(0,i-1)];

		// create a new node w such that v is split into v and w
		node w = nodes[i] = G.newNode();

		// build array of all neighbors
		int d = v->degree();

		int j = 0;
		adjEntry adj;
		forall_adj(adj,v)
			neighbors[j++] = adj->theEdge();

		// mark two distinct neighbors for left
		for(j = 2; j > 0; ) {
			int r = randomNumber(0,d-1);
			if((mark[r] & 1) == 0) {
				mark[r] |= 1; --j;
			}
		}

		// mark two distinct neighbors for right
		for(j = 2; j > 0; ) {
			int r = randomNumber(0,d-1);
			if((mark[r] & 2) == 0) {
				mark[r] |= 2; --j;
			}
		}

		for(j = 0; j < d; ++j) {
			int m = mark[j];
			mark[j] = 0;

			// decide to with which node each neighbor is connected
			// (possible: v, w, or both)
			double x = randomDouble(0.0,1.0);
			switch(m)
			{
			case 0:
				if(x < p1)
					m = 1;
				else if(x < p1+p2)
					m = 2;
				else
					m = 3;
				break;
			case 1:
			case 2:
				if(x >= p1+p2) m = 3;
				break;
			}

			// move edge or create new one if necessary
			edge e = neighbors[j];
			switch(m)
			{
			case 2:
				if(v == e->source())
					G.moveSource(e,w);
				else
					G.moveTarget(e,w);
				break;
			case 3:
				G.newEdge(w,e->opposite(v));
				break;
			}
		}

		G.newEdge(v,w);
	}
}
Пример #15
0
void planarTriconnectedGraph(Graph &G, int n, double p1, double p2)
{
	if (n < 4) n = 4;

	// start with K_4
	completeGraph(G,4);

	planarEmbedPlanarGraph(G);

	// nodes[0],...,nodes[i-1] is array of all nodes
	Array<node> nodes(n);

	node v;
	int i = 0;
	forall_nodes(v,G)
		nodes[i++] = v;

	for(; i < n; ++i)
	{
		// pick a random node
		v = nodes[randomNumber(0,i-1)];

		int m = v->degree();
		int a1 = randomNumber(0,m-1);
		int a2 = randomNumber(0,m-2);

		int j;
		adjEntry adj1, adj2;
		for(adj1 = v->firstAdj(), j = 0; j < a1; adj1 = adj1->succ(), ++j) ;
		for(adj2 = adj1->cyclicSucc(), j = 0; j < a2; adj2 = adj2->cyclicSucc(), ++j) ;

		adjEntry adj_b1 = adj2->cyclicPred();
		adjEntry adj_b2 = adj1->cyclicPred();

		nodes[i] = G.splitNode(adj1, adj2);

		if(adj1 == adj_b1)
			G.newEdge(adj_b1, adj2->twin());
		else if(adj2 == adj_b2)
			G.newEdge(adj2, adj_b1->twin(), ogdf::before);
		else {
			double r = randomDouble(0.0,1.0);
			if(r <= p1) {
				int s = randomNumber(0,1);
				if(s == 0)
					G.newEdge(adj_b1, adj2->twin());
				else
					G.newEdge(adj2, adj_b1->twin(), ogdf::before);
			}
		}

		double r = randomDouble(0.0,1.0);
		if(r <= p2) {
			int s = randomNumber(0,1);
			if(s == 0)
				G.newEdge(adj1, adj_b2->twin(), ogdf::before);
			else
				G.newEdge(adj_b2, adj1->twin());
		}
	}
}
Пример #16
0
void planarTriconnectedGraph(Graph &G, int n, int m)
{
	if (n < 4) n = 4;
	if(n % 2) ++n; // need an even number

	// start with K_4
	completeGraph(G,4);

	planarEmbedPlanarGraph(G);

	// nodes[0],...,nodes[i-1] is array of all nodes
	Array<node> nodes(n);

	node v;
	int i = 0;
	forall_nodes(v,G)
		nodes[i++] = v;

	// create planar triconnected 3-graph
	for(; i < n; )
	{
		// pick a random node
		v = nodes[randomNumber(0,i-1)];

		adjEntry adj2 = v->firstAdj();
		int r = randomNumber(0,2);
		switch(r) {
			case 2: adj2 = adj2->succ(); // fall through to next case
			case 1: adj2 = adj2->succ();
		}
		adjEntry adj1 = adj2->cyclicSucc();

		nodes[i++] = G.splitNode(adj1,adj2);

		r = randomNumber(0,1);
		if(r == 0) {
			adjEntry adj = adj1->twin();
			G.newEdge(adj2,adj);
			nodes[i++] = G.splitNode(adj,adj->cyclicSucc()->cyclicSucc());

		} else {
			adjEntry adj = adj1->cyclicSucc()->twin();
			G.newEdge(adj2,adj,ogdf::before);
			nodes[i++] = G.splitNode(adj->cyclicPred(),adj->cyclicSucc());
		}
	}

	nodes.init();
	Array<edge> edges(m);

	CombinatorialEmbedding E(G);
	Array<face> faces(2*n);

	i = 0;
	face f;
	forall_faces(f,E) {
		if(f->size() >= 4)
			faces[i++] = f;
	}

	while(G.numberOfEdges() < m && i > 0)
	{
		int r = randomNumber(0,i-1);
		f = faces[r];
		faces[r] = faces[--i];

		int p = randomNumber(0,f->size()-1);
		int j = 0;
		adjEntry adj, adj2;
		for(adj = f->firstAdj(); j < p; adj = adj->faceCycleSucc(), ++j) ;

		p = randomNumber(2, f->size()-2);
		for(j = 0, adj2 = adj; j < p; adj2 = adj2->faceCycleSucc(), ++j) ;

		edge e = E.splitFace(adj,adj2);

		f = E.rightFace(e->adjSource());
		if(f->size() >= 4) faces[i++] = f;

		f = E.rightFace(e->adjTarget());
		if(f->size() >= 4) faces[i++] = f;
	}
}
void GEMLayout::call(GraphAttributes &AG) 
{
	const Graph &G = AG.constGraph();
	if(G.empty())
		return;

	OGDF_ASSERT(m_numberOfRounds >= 0);
	OGDF_ASSERT(DIsGreaterEqual(m_minimalTemperature,0));
	OGDF_ASSERT(DIsGreaterEqual(m_initialTemperature,m_minimalTemperature));
	OGDF_ASSERT(DIsGreaterEqual(m_gravitationalConstant,0));
	OGDF_ASSERT(DIsGreaterEqual(m_desiredLength,0));
	OGDF_ASSERT(DIsGreaterEqual(m_maximalDisturbance,0));
	OGDF_ASSERT(DIsGreaterEqual(m_rotationAngle,0));
	OGDF_ASSERT(DIsLessEqual(m_rotationAngle,pi / 2));
	OGDF_ASSERT(DIsGreaterEqual(m_oscillationAngle,0));
	OGDF_ASSERT(DIsLessEqual(m_oscillationAngle,pi / 2));
	OGDF_ASSERT(DIsGreaterEqual(m_rotationSensitivity,0));
	OGDF_ASSERT(DIsLessEqual(m_rotationSensitivity,1));
	OGDF_ASSERT(DIsGreaterEqual(m_oscillationSensitivity,0));
	OGDF_ASSERT(DIsLessEqual(m_oscillationSensitivity,1));
	OGDF_ASSERT(m_attractionFormula == 1 || m_attractionFormula == 2);
	
	// all edges straight-line
	AG.clearAllBends();

	GraphCopy GC;
	GC.createEmpty(G);

	// compute connected component of G
	NodeArray<int> component(G);
	int numCC = connectedComponents(G,component);

	// intialize the array of lists of nodes contained in a CC
	Array<List<node> > nodesInCC(numCC);

	node v;
	forall_nodes(v,G)
		nodesInCC[component[v]].pushBack(v);

	EdgeArray<edge> auxCopy(G);
	Array<DPoint> boundingBox(numCC);

	int i;
	for(i = 0; i < numCC; ++i)
	{
		GC.initByNodes(nodesInCC[i],auxCopy);

		GraphCopyAttributes AGC(GC,AG);
		node vCopy;
		forall_nodes(vCopy, GC) {
			node vOrig = GC.original(vCopy);
			AGC.x(vCopy) = AG.x(vOrig);
			AGC.y(vCopy) = AG.y(vOrig);
		}

		SList<node> permutation;
		node v;

		// initialize node data
		m_impulseX.init(GC,0);
		m_impulseY.init(GC,0);
		m_skewGauge.init(GC,0);
		m_localTemperature.init(GC,m_initialTemperature);

		// initialize other data
		m_globalTemperature = m_initialTemperature;
		m_barycenterX = 0;
		m_barycenterY = 0;
		forall_nodes(v,GC) {
			m_barycenterX += weight(v) * AGC.x(v);
			m_barycenterY += weight(v) * AGC.y(v);
		}