示例#1
0
//read all cluster tree information
bool GmlParser::clusterRead(GmlObject* rootCluster, 
							ClusterGraph& CG)
{

	//the root cluster is only allowed to hold child clusters and
	//nodes in a list

	if (rootCluster->m_valueType != gmlListBegin) return false;

	// read all clusters and nodes
	GmlObject *rootClusterSon = rootCluster->m_pFirstSon;

	for(; rootClusterSon; rootClusterSon = rootClusterSon->m_pBrother) 
	{
		switch(id(rootClusterSon)) 
		{
			case clusterPredefKey:
				{
					//we could delete this, but we aviod the call
					if (rootClusterSon->m_valueType != gmlListBegin) return false;
					// set attributes to default values
					//we currently do not set any values
					cluster c = CG.newCluster(CG.rootCluster());

					//recursively read cluster
					recursiveClusterRead(rootClusterSon, CG, c);

				} //case cluster
				break;
			case vertexPredefKey: //direct root vertices 
				{
					if (rootClusterSon->m_valueType != gmlStringValue) return false;
					String vIDString = rootClusterSon->m_stringValue;

					//we only allow a vertex id as string identification
					if ((vIDString[0] != 'v') &&
						(!isdigit(vIDString[0])))return false; //do not allow labels
					//if old style entry "v"i
					if (!isdigit(vIDString[0])) //should check prefix?
						vIDString[0] = '0'; //leading zero to allow conversion
					int vID = atoi(vIDString.cstr());

					OGDF_ASSERT(m_mapToNode[vID] != 0)

					//we assume that no node is already assigned ! Changed:
					//all new nodes are assigned to root
					//CG.reassignNode(mapToNode[vID], CG.rootCluster());
					//it seems that this may be unnessecary, TODO check
					CG.reassignNode(m_mapToNode[vID], CG.rootCluster());
					//char* vIDChar = new char[vIDString.length()+1];
					//for (int ind = 1; ind < vIDString.length(); ind++)
					//	vIDChar

				}//case vertex
		}//switch
	}//for all rootcluster sons

	return true;
				
}//clusterread
示例#2
0
ClusterGraphCopy::ClusterGraphCopy(const ExtendedNestingGraph &H, const ClusterGraph &CG)
: ClusterGraph(H), m_pCG(&CG), m_pH(&H), m_copy(CG,0)
{
	m_original.init(*this,0);
	m_copy    [CG.rootCluster()] = rootCluster();
	m_original[rootCluster()]    = CG.rootCluster();

	createClusterTree(CG.rootCluster());
}
示例#3
0
// write cluster graph structure with clusters
static void write_ogml_graph(const ClusterGraph &C, ostream &os)
{
	GraphIO::indent(os,2) << "<structure>\n";

	write_ogml_graph(C.rootCluster(), 0, os);
	write_ogml_graph_edges(C.constGraph(), os);

	GraphIO::indent(os,2) << "</structure>\n";
}
示例#4
0
//recursively read cluster subtree information
bool GmlParser::recursiveClusterRead(GmlObject* clusterObject,
								ClusterGraph& CG,
								cluster c)
{

	//for direct root cluster sons, this is checked twice...
	if (clusterObject->m_valueType != gmlListBegin) return false;

	GmlObject *clusterSon = clusterObject->m_pFirstSon;

	for(; clusterSon; clusterSon = clusterSon->m_pBrother)
	{
		//we dont read the attributes, therefore look only for
		//id and sons
		switch(id(clusterSon))
		{
			case clusterPredefKey:
				{
					if (clusterSon->m_valueType != gmlListBegin) return false;

					cluster cson = CG.newCluster(c);
					//recursively read child cluster
					recursiveClusterRead(clusterSon, CG, cson);
				}
				break;
			case vertexPredefKey: //direct cluster vertex entries
				{
					if (clusterSon->m_valueType != gmlStringValue) return false;
					string vIDString = clusterSon->m_stringValue;

					//if old style entry "v"i
					if ((vIDString[0] != 'v') &&
						(!isdigit((int)vIDString[0])))return false; //do not allow labels
					//if old style entry "v"i
					if (!isdigit((int)vIDString[0])) //should check prefix?
						vIDString[0] = '0'; //leading zero to allow conversion
					int vID = stoi(vIDString);

					OGDF_ASSERT(m_mapToNode[vID] != 0)

					//we assume that no node is already assigned
					//CG.reassignNode(mapToNode[vID], c);
					//changed: all nodes are already assigned to root
					CG.reassignNode(m_mapToNode[vID], c);
					//char* vIDChar = new char[vIDString.length()+1];
					//for (int ind = 1; ind < vIDString.length(); ind++)
					//	vIDChar

				}//case vertex
		}//switch
	}//for clustersons

	return true;

}//recursiveclusterread
示例#5
0
void ClusterGraphCopy::init(const ExtendedNestingGraph &H, const ClusterGraph &CG)
{
	ClusterGraph::init(H);
	m_pCG = &CG;
	m_pH  = &H;
	m_copy    .init(CG,0);
	m_original.init(*this,0);

	m_copy    [CG.rootCluster()] = rootCluster();
	m_original[rootCluster()]    = CG.rootCluster();

	createClusterTree(CG.rootCluster());
}
示例#6
0
//to be called AFTER calling read(G, AG)
bool GmlParser::readAttributedCluster(
	Graph &G,
	ClusterGraph& CG,
	ClusterGraphAttributes& ACG)
{
	OGDF_ASSERT(&CG.constGraph() == &G)


	//now we need the cluster object
	GmlObject *rootObject = m_objectTree;
	for(; rootObject; rootObject = rootObject->m_pBrother)
		if (id(rootObject) == rootClusterPredefKey) break;

	if(rootObject == nullptr)
		return true;

	if (id(rootObject) != rootClusterPredefKey)
	{
		setError("missing rootcluster key");
		return false;
	}

	if (rootObject->m_valueType != gmlListBegin) return false;

	attributedClusterRead(rootObject, CG, ACG);

	return true;
}//readAttributedCluster
示例#7
0
文件: GraphIO_dot.cpp 项目: ogdf/ogdf
bool GraphIO::writeDOT(const ClusterGraph &C, std::ostream &out)
{
	const Graph &G = C.constGraph();
	int id = 1;

	// Assign a list of edges for each cluster. Perhaps usage of std::vector
	// here needs reconsideration - vector is fast but usage of STL iterators
	// is ugly without C++11 for-each loop.
	ClusterArray< std::vector<edge> > edgeMap(C);
	for(edge e : G.edges) {
		const node s = e->source(), t = e->target();
		edgeMap[C.commonCluster(s, t)].push_back(e);
	}

	return dot::writeCluster(out, 0, edgeMap, C, nullptr, C.rootCluster(), id);
}
// Copy Function
void ClusterGraph::shallowCopy(const ClusterGraph &C)
{
	const Graph &G = C;
	m_pGraph = &G;

	m_nClusters = 0;

	//m_clusterDepth.init(*this, 0);

	initGraph(G);
	
	m_updateDepth = C.m_updateDepth;
	m_depthUpToDate = C.m_depthUpToDate;

	// Construct cluster tree
	ClusterArray<cluster> originalClusterTable(C);
	cluster c = 0;
	forall_clusters(c,C)
	{
		if (c == C.m_rootCluster)
		{
			originalClusterTable[c] = m_rootCluster;
			//does not really need to be assigned HERE in for
			m_rootCluster->depth() = 1;
			OGDF_ASSERT(C.rootCluster()->depth() == 1)
			continue;
		}
		originalClusterTable[c] = newCluster();
		originalClusterTable[c]->depth() = c->depth();
	}
示例#9
0
bool CconnectClusterPlanar::preProcess(ClusterGraph &C,Graph &G)
{
	if (!isCConnected(C))
	{
		m_errorCode = nonCConnected;
		return false;
	}

	if (!isPlanar(C))
	{
		m_errorCode = nonPlanar;
		return false;
	}

	cluster c;

	SListPure<node> selfLoops;
	makeLoopFree(G,selfLoops);

	c = C.rootCluster();

	bool cPlanar = planarityTest(C,c,G);

	return cPlanar;
}
示例#10
0
bool CconnectClusterPlanar::preProcess(ClusterGraph &C,Graph &G)
{
	if (!isCConnected(C))
	{
		ogdf::sprintf(errorCode,124,"Graph is not C-connected \n"); 
		m_errorCode = nonCConnected;
		return false;
	}

	PlanarModule Pm;
	if (!Pm.planarityTest(C))
	{
		ogdf::sprintf(errorCode,124,"Graph is not planar\n"); 
		m_errorCode = nonPlanar;
		return false;
	}

	cluster c;

	SListPure<node> selfLoops;
	makeLoopFree(G,selfLoops);

	c = C.rootCluster();

	bool cPlanar = planarityTest(C,c,G);

	return cPlanar;
}
示例#11
0
bool GraphIO::writeGEXF(const ClusterGraph &C, std::ostream &out)
{
	gexf::writeHeader(out);
	gexf::writeCluster(out, 1, C, nullptr, C.rootCluster());
	gexf::writeFooter(out);

	return true;
}
ClusterGraph::ClusterGraph(const ClusterGraph &C)
	: GraphObserver(&(C.getGraph())), m_clusterIdCount(0),m_postOrderStart(0),
	  m_rootCluster(0), m_nClusters(0),
	  m_lcaNumber(0), m_lcaSearch(0), m_vAncestor(0), m_wAncestor(0),
	  m_allowEmptyClusters(1), m_updateDepth(false), m_depthUpToDate(false)
{
	shallowCopy(C);
	m_clusterArrayTableSize = C.m_clusterArrayTableSize;
}
示例#13
0
static void writeCluster(
	std::ostream &out, int depth,
	const ClusterArray < std::vector<edge> > &edgeMap,
	const ClusterGraph &C, const ClusterGraphAttributes *CA, const cluster &c,
	int &clusterId)
{
	if(C.rootCluster() == c) {
		writeHeader(out, depth++, CA);
	} else {
		GraphIO::indent(out, depth++) << "subgraph cluster" << clusterId
		                              << " {\n";
	}
	clusterId++;

	bool whitespace; // True if a whitespace should printed (readability).

	whitespace = false;
	if(CA) {
		writeAttributes(out, depth, *CA, c);
		whitespace = true;
	}

	if(whitespace) {
		out << "\n";
	}

	// Recursively export all subclusters.
	whitespace = false;
	for(ListConstIterator<cluster> cit = c->cBegin(); cit.valid(); ++cit) {
		writeCluster(out, depth, edgeMap, C, CA, *cit, clusterId);
		whitespace = true;
	}

	if(whitespace) {
		out << "\n";
	}

	// Then, print all nodes whithout an adjacent edge.
	whitespace = false;
	for(ListConstIterator<node> nit = c->nBegin(); nit.valid(); ++nit) {
		whitespace |= writeNode(out, depth, CA, *nit);
	}

	if(whitespace) {
		out << "\n";
	}

	// Finally, we print all edges for this cluster (ugly version for now).
	const std::vector<edge> &edges = edgeMap[c];
	whitespace = false;
	for(size_t i = 0; i < edges.size(); i++) {
		whitespace |= writeEdge(out, depth, CA, edges[i]);
	}

	GraphIO::indent(out, --depth) << "}\n";
}
示例#14
0
bool Parser::readCluster(
	Graph &G, ClusterGraph &C, ClusterGraphAttributes *CA, cluster rootCluster,
	const XmlTagObject &rootTag)
{
	List<XmlTagObject *> nodeTags;
	rootTag.findSonXmlTagObjectByName("node", nodeTags);

	for(XmlTagObject *obj : nodeTags) {
		const XmlTagObject &nodeTag = *obj;

		XmlAttributeObject *idAttr;
		nodeTag.findXmlAttributeObjectByName("id", idAttr);
		if(!idAttr) {
			OGDF_ERROR("node is missing an attribute "
			          << "(line " << nodeTag.getLine() << ").");
		}

		// Node is a cluster iff it contains other nodes.
		XmlTagObject *nodesTag;
		nodeTag.findSonXmlTagObjectByName("nodes", nodesTag);
		if(nodesTag) {
			// Node tag found, therefore it is a cluster.
			const cluster c = C.newCluster(rootCluster);
			m_clusterId[idAttr->getValue()] = c;

			if(!readCluster(G, C, CA, c, *nodesTag)) {
				return false;
			}
		} else {
			// Node tag not found, therefore it is "normal" node.
			const node v = G.newNode();
			C.reassignNode(v, rootCluster);
			m_nodeId[idAttr->getValue()] = v;

			if(CA) {
				readAttributes(*CA, v, nodeTag);
			}
		}
	}

	return true;
}
示例#15
0
bool GraphMLParser::readClusters(
	Graph &G,
	ClusterGraph &C,
	ClusterGraphAttributes *CA,
	const cluster &rootCluster,
	const pugi::xml_node rootTag)
{
	for(pugi::xml_node nodeTag : rootTag.children("node")) {
		pugi::xml_attribute idAttr = nodeTag.attribute("id");
		pugi::xml_node clusterTag = nodeTag.child("graph");

		if (clusterTag == nullptr) {
			// Got normal node then, add it to the graph - id is required.
			if (!idAttr) {
				GraphIO::logger.lout() << "Node is missing id attribute." << endl;
				return false;
			}

			const node v = G.newNode();
			m_nodeId[idAttr.value()] = v;
			C.reassignNode(v, rootCluster);

			// Read attributes when CA given and return false if error.
			if(CA && !readAttributes(*CA, v, nodeTag)) {
				return false;
			}
		} else {
			// Got a cluster node - read it recursively.
			const cluster c = C.newCluster(rootCluster);
			if (!readClusters(G, C, CA, c, clusterTag)) {
				return false;
			}

			// Read attributes when CA given and return false if error.
			if(CA && !readAttributes(*CA, c, nodeTag)) {
				return false;
			}
		}
	}

	return readEdges(G, CA, rootTag);
}
示例#16
0
bool GraphMLParser::read(Graph &G, ClusterGraph &C, ClusterGraphAttributes &CA)
{
	if(m_error) {
		return false;
	}

	G.clear();
	m_nodeId.clear();

	return readClusters(G, C, &CA, C.rootCluster(), m_graphTag);
}
示例#17
0
bool GraphMLParser::read(Graph &G, ClusterGraph &C)
{
	if(m_error) {
		return false;
	}

	G.clear();
	m_nodeId.clear();

	return readClusters(G, C, nullptr, C.rootCluster(), m_graphTag);
}
//in ClusterGraph??
//is not yet recursive!!!
node collapseCluster(ClusterGraph& CG, cluster c, Graph& G)
{
	OGDF_ASSERT(c->cCount() == 0)

	ListIterator<node> its;
	SListPure<node> collaps;

	//we should check here if not empty
	node robinson = (*(c->nBegin()));

	for (its = c->nBegin(); its.valid(); its++)
		collaps.pushBack(*its);

	CG.collaps(collaps, G);

	if (c != CG.rootCluster())
		CG.delCluster(c);

	return robinson;
}
示例#19
0
void CPlanarSubClusteredST::call(const ClusterGraph &CG, EdgeArray<bool>& inST)
{
	initialize(CG);
	inST.fill(false);

	//representationsgraphs for every cluster, on clustergraph
	ClusterArray<Graph*> l_clusterRepGraph(CG, nullptr);
	computeRepresentationGraphs(CG, l_clusterRepGraph);

	//now we compute the spanning trees on the representation graphs
	//we should save the selection info on the original edge
	//are statically on the repgraphedges (we only have edge -> repedge
	//information) but
	ClusterArray< EdgeArray<bool> > l_inTree(CG);

	for(cluster c : CG.clusters) {
		l_inTree[c].init(*l_clusterRepGraph[c], false);
		//compute STs
		NodeArray<bool> visited(*l_clusterRepGraph[c], false);
		dfsBuildSpanningTree(l_clusterRepGraph[c]->firstNode(), l_inTree[c], visited);
	}

	OGDF_ASSERT(isConnected(CG.constGraph()));

	//compute the subclustered graph by constructing a spanning tree
	//using only the representation edges used in STs on the repgraphs
	NodeArray<bool> visited(CG, false);

	dfsBuildOriginalST(CG.constGraph().firstNode(),
	                   l_inTree,
	                   inST,
	                   visited);

	//unregister the edgearrays to avoid destructor failure after
	//representation graph deletion
	for(cluster c : CG.clusters) {
		l_inTree[c].init();
	}

	deleteRepresentationGraphs(CG, l_clusterRepGraph);
}
示例#20
0
static void writeCluster(
	std::ostream &out, int depth,
	const ClusterGraph &C, const ClusterGraphAttributes *CA, cluster c)
{
	if(C.rootCluster() != c) {
		GraphIO::indent(out, depth) << "<node "
		                            << "id=\"cluster" << c->index() << "\""
		                            << ">\n";
	} else {
		const std::string dir =
			(CA && !CA->directed()) ? "undirected" : "directed";
		GraphIO::indent(out, depth) << "<graph "
		                            << "mode=\"static\""
		                            << "defaultedgetype=\"" << dir << "\""
		                            << ">\n";

		if(CA) {
			defineAttributes(out, depth + 1, *CA);
		}
	}

	GraphIO::indent(out, depth + 1) << "<nodes>\n";

	for(ListConstIterator<cluster> cit = c->cBegin(); cit.valid(); ++cit) {
		writeCluster(out, depth + 2, C, CA, *cit);
	}

	for(ListConstIterator<node> nit = c->nBegin(); nit.valid(); ++nit) {
		writeNode(out, depth + 2, CA, *nit);
	}

	GraphIO::indent(out, depth + 1) << "</nodes>\n";

	if(C.rootCluster() != c) {
		GraphIO::indent(out, depth) << "</node>\n";
	} else {
		writeEdges(out, C.constGraph(), CA);
		GraphIO::indent(out, depth) << "</graph>\n";
	}
}
示例#21
0
void CPlanarSubClusteredST::initialize(const ClusterGraph& CG)
{
	//initialize "call-global" info arrays
	m_allocCluster.init(CG, nullptr);
	//edge status
#if 0
	m_edgeStatus.init(CG.getGraph(), 0);
#endif
	//edge to rep edge
	m_repEdge.init(CG, nullptr);
	//nodes and clusters to rep nodes
	m_cRepNode.init(CG, nullptr);
	m_vRepNode.init(CG, nullptr);
}
// true <=> C is C-connected
bool isCConnected(const ClusterGraph &C)
{
	if(C.getGraph().empty())
		return true;

	Graph G;
	ClusterGraph Cp(C,G);


	cluster root = Cp.rootCluster();
	SListPure<node>   compNodes;
	NodeArray<bool> mark(G,false);
	return cConnectTest(Cp,root,mark,G);
}
示例#23
0
ClusterGraph::ClusterGraph(const ClusterGraph &C) :
	GraphObserver(&(C.constGraph())),
	m_lcaSearch(0),
	m_vAncestor(0),
	m_wAncestor(0)
{
	m_clusterIdCount = 0;
	m_postOrderStart = 0;
	m_rootCluster    = 0;

	m_allowEmptyClusters = true;
	m_updateDepth   = false;
	m_depthUpToDate = false;

	m_nClusters = 0;
	m_lcaNumber = 0;

	m_clusterArrayTableSize = C.m_clusterArrayTableSize;
	shallowCopy(C);
}
示例#24
0
// Copy Function
void ClusterGraph::shallowCopy(const ClusterGraph &C)
{
	const Graph &G = C;
	m_pGraph = &G;

	initGraph(G);

	m_updateDepth = C.m_updateDepth;
	m_depthUpToDate = C.m_depthUpToDate;

	// Construct cluster tree
	ClusterArray<cluster> originalClusterTable(C);
	for(cluster c : C.clusters)
	{
		if (c == C.m_rootCluster) {
			originalClusterTable[c] = m_rootCluster;
			//does not really need to be assigned HERE in for
			m_rootCluster->m_depth = 1;
			continue;
		}
		originalClusterTable[c] = newCluster();
		originalClusterTable[c]->m_depth = c->depth();
	}

	for(cluster c : C.clusters)
	{
		if (c == C.m_rootCluster)
			continue;
		originalClusterTable[c]->m_parent = originalClusterTable[c->m_parent];
		originalClusterTable[c->m_parent]->children.pushBack(originalClusterTable[c]);
		originalClusterTable[c]->m_it = originalClusterTable[c->m_parent]->getChildren().rbegin();
	}

	for(node v : G.nodes)
		reassignNode(v,originalClusterTable[C.clusterOf(v)]);

	copyLCA(C);
}
示例#25
0
//the clustergraph has to be initialized on G!!,
//no clusters other then root cluster may exist, which holds all nodes
bool GmlParser::readCluster(Graph &G, ClusterGraph& CG)
{
	OGDF_ASSERT(&CG.constGraph() == &G)

	//now we need the cluster object
	GmlObject *rootObject = m_objectTree;
	for(; rootObject; rootObject = rootObject->m_pBrother)
		if (id(rootObject) == rootClusterPredefKey) break;

	//we have to check if the file does really contain clusters
	//otherwise, rootcluster will suffice
	if (rootObject == nullptr) return true;
	if (id(rootObject) != rootClusterPredefKey)
	{
		setError("missing rootcluster key");
		return false;
	}

	if (rootObject->m_valueType != gmlListBegin) return false;

	clusterRead(rootObject, CG);

	return true;
}//read clustergraph
示例#26
0
void CPlanarSubClusteredST::call(const ClusterGraph& CG,
		EdgeArray<bool>& inST,
		EdgeArray<double>& weight)
{
	initialize(CG);

	//representationsgraphs for every cluster, on clustergraph
	ClusterArray<Graph*> l_clusterRepGraph(CG, nullptr);
	computeRepresentationGraphs(CG, l_clusterRepGraph);

	//Now we compute the spanning trees on the representation graphs
	//are statically on the repgraphedges (we only have edge -> repedge
	//information)
	ClusterArray< EdgeArray<bool> > l_inTree(CG);
	//Weight of the representation edges
	ClusterArray< EdgeArray<double> > l_repWeight(CG);

	//Copy the weight
	for(cluster c : CG.clusters) {
		l_repWeight[c].init(*l_clusterRepGraph[c], 0.0);
	}
	for(edge e : CG.constGraph().edges) {
		l_repWeight[m_allocCluster[e]][m_repEdge[e]] = weight[e];
	}

	for(cluster c : CG.clusters)
	{
		l_inTree[c].init(*l_clusterRepGraph[c], false);
		//compute STs
		computeMinST(*l_clusterRepGraph[c], l_repWeight[c],
			l_inTree[c]);
	}

	OGDF_ASSERT(isConnected(CG.constGraph()));

	//Compute the subclustered graph
	for(edge e : CG.constGraph().edges)
	{
		if (l_inTree[m_allocCluster[e]][m_repEdge[e]])
			inST[e] = true;
		else inST[e] = false;
	}
#ifdef OGDF_DEBUG
	GraphCopy cg(CG.constGraph());
	for(edge e : CG.constGraph().edges)
	{
		if (!inST[e])
			cg.delEdge(cg.copy(e));
	}
	OGDF_ASSERT(isConnected(cg));
	OGDF_ASSERT(cg.numberOfEdges() == cg.numberOfNodes()-1);

#endif
	//unregister the edgearrays to avoid destructor failure after
	//representation graph deletion
	for(cluster c : CG.clusters)
	{
		l_inTree[c].init();
		l_repWeight[c].init();
	}

	deleteRepresentationGraphs(CG, l_clusterRepGraph);
}
示例#27
0
MaxCPlanarMaster::MaxCPlanarMaster(
	const ClusterGraph &C,
	int heuristicLevel,
	int heuristicRuns,
	double heuristicOEdgeBound,
	int heuristicNPermLists,
	int kuratowskiIterations,
	int subdivisions,
	int kSupportGraphs,
	double kHigh,
	double kLow,
	bool perturbation,
	double branchingGap,
	const char *time,
	bool dopricing,
	bool checkCPlanar,
	int numAddVariables,
	double strongConstraintViolation,
	double strongVariableViolation) : 	Master("MaxCPlanar", true, dopricing, OptSense::Max),
	m_numAddVariables(numAddVariables),
	m_strongConstraintViolation(strongConstraintViolation),
	m_strongVariableViolation(strongVariableViolation),
	m_fastHeuristicRuns(25),
	m_cutConnPool(nullptr),
	m_cutKuraPool(nullptr),
	m_useDefaultCutPool(true),
	m_checkCPlanar(checkCPlanar),
	m_porta(false)
{

	// Reference to the given ClusterGraph and the underlying Graph.
	m_C = &C;
	m_G = &(C.constGraph());
	// Create a copy of the graph as we need to modify it
	m_solutionGraph = new GraphCopy(*m_G);
	// Define the maximum number of variables needed.
	// The actual number needed may be much smaller, so there
	// is room for improvement...
	//ToDo: Just count how many vars are added

	//Max number of edges
	//KK: Check this change, added div 2
	int nComplete = (m_G->numberOfNodes()*(m_G->numberOfNodes()-1)) / 2;
	m_nMaxVars = nComplete;
	//to use less variables in case we have only the root cluster,
	//we temporarily set m_nMaxVars to the number of edges
	if ( (m_C->numberOfClusters() == 1) && (isConnected(*m_G)) )
		m_nMaxVars = m_G->numberOfEdges();

	// Computing the main objective function coefficient for the connection edges.
	//int nConnectionEdges = nComplete - m_G->numberOfEdges();
	m_epsilon = (double)(0.2/(2*(m_G->numberOfNodes())));

	// Setting parameters
	m_nKuratowskiIterations = kuratowskiIterations;
	m_nSubdivisions = subdivisions;
	m_nKuratowskiSupportGraphs = kSupportGraphs;
	m_heuristicLevel = heuristicLevel;
	m_nHeuristicRuns = heuristicRuns;
	m_usePerturbation = perturbation;
	m_kuratowskiBoundHigh = kHigh;
	m_kuratowskiBoundLow = kLow;
	m_branchingGap = branchingGap;
	m_maxCpuTime = new string(time);
	m_heuristicFractionalBound = heuristicOEdgeBound;
	m_nHeuristicPermutationLists = heuristicNPermLists;
	m_mpHeuristic = true;

	// Further settings
	m_nCConsAdded = 0;
	m_nKConsAdded = 0;
	m_solvesLP = 0;
	m_varsInit = 0;
	m_varsAdded = 0;
	m_varsPotential = 0;
	m_varsMax = 0;
	m_varsCut = 0;
	m_varsKura = 0;
	m_varsPrice = 0;
	m_varsBranch = 0;
	m_activeRepairs = 0;
	m_repairStat.init(100);
}
示例#28
0
void CconnectClusterPlanar::constructWheelGraph(ClusterGraph &C,
												Graph &G,
												cluster &parent,
												PlanarPQTree* T,
												EdgeArray<node> &outgoingTable)
{

	const PQNode<edge,IndInfo*,bool>* root = T->root();
	const PQNode<edge,IndInfo*,bool>*  checkNode = nullptr;

	Queue<const PQNode<edge,IndInfo*,bool>*> treeNodes;
	treeNodes.append(root);

	node correspond = G.newNode(); // Corresponds to the root node.
								   // root node is either a leaf or a P-node
	C.reassignNode(correspond,parent);

	Queue<node> graphNodes;
	graphNodes.append(correspond);

	node hub;
	node next = nullptr;
	node pre;
	node newNode; // corresponds to anchor of a hub or a cut node



	while (!treeNodes.empty())
	{
		checkNode = treeNodes.pop();
		correspond = graphNodes.pop();

		PQNode<edge,IndInfo*,bool>*  firstSon  = nullptr;
		PQNode<edge,IndInfo*,bool>*  nextSon   = nullptr;
		PQNode<edge,IndInfo*,bool>*  oldSib    = nullptr;
		PQNode<edge,IndInfo*,bool>*  holdSib   = nullptr;


		if (checkNode->type() == PQNodeRoot::PNode)
		{
			// correspond is a cut node

			OGDF_ASSERT(checkNode->referenceChild())
			firstSon = checkNode->referenceChild();

			if (firstSon->type() != PQNodeRoot::leaf)
			{
				treeNodes.append(firstSon);
				newNode = G.newNode();
				C.reassignNode(newNode,parent);
				graphNodes.append(newNode);
				G.newEdge(correspond,newNode);
			}
			else
			{
				// insert Edge to the outside
				PQLeaf<edge,IndInfo*,bool>* leaf =
					(PQLeaf<edge,IndInfo*,bool>*) firstSon;
				edge f = leaf->getKey()->m_userStructKey;
				//node x = outgoingTable[f];
				G.newEdge(correspond,outgoingTable[f]);
				delete leaf->getKey();
			}

			nextSon = firstSon->getNextSib(oldSib);
			oldSib = firstSon;
			pre = next;
			while (nextSon && nextSon != firstSon)
			{
				if (nextSon->type() != PQNodeRoot::leaf)
				{
					treeNodes.append(nextSon);
					newNode = G.newNode();  // new node corresponding to anchor
											// or cutnode
					C.reassignNode(newNode,parent);
					graphNodes.append(newNode);
					G.newEdge(correspond,newNode);
				}
				else
				{
					// insert Edge to the outside
					PQLeaf<edge,IndInfo*,bool>* leaf =
						(PQLeaf<edge,IndInfo*,bool>*) nextSon;
					edge f = leaf->getKey()->m_userStructKey;
					//node x = outgoingTable[f];
					G.newEdge(correspond,outgoingTable[f]);
					delete leaf->getKey();
				}
				holdSib = nextSon->getNextSib(oldSib);
				oldSib = nextSon;
				nextSon = holdSib;
			}

		}
		else if (checkNode->type() == PQNodeRoot::QNode)
		{
			// correspond is the anchor of a hub
			OGDF_ASSERT(checkNode->getEndmost(PQNodeRoot::LEFT))
			firstSon = checkNode->getEndmost(PQNodeRoot::LEFT);

			hub = G.newNode();
			C.reassignNode(hub,parent);
			G.newEdge(hub,correspond); // link anchor and hub
			next = G.newNode();   // for first son
			C.reassignNode(next,parent);
			G.newEdge(hub,next);
			G.newEdge(correspond,next);

			if (firstSon->type() != PQNodeRoot::leaf)
			{
				treeNodes.append(firstSon);
				newNode = G.newNode();
				C.reassignNode(newNode,parent);
				graphNodes.append(newNode);
				G.newEdge(next,newNode);
			}
			else
			{
				// insert Edge to the outside
				PQLeaf<edge,IndInfo*,bool>* leaf =
					(PQLeaf<edge,IndInfo*,bool>*) firstSon;
				edge f = leaf->getKey()->m_userStructKey;
				//node x = outgoingTable[f];
				G.newEdge(next,outgoingTable[f]);
				delete leaf->getKey();
			}

			nextSon = firstSon->getNextSib(oldSib);
			oldSib = firstSon;
			pre = next;
			while (nextSon)
			{
				next = G.newNode();
				C.reassignNode(next,parent);
				G.newEdge(hub,next);
				G.newEdge(pre,next);
				if (nextSon->type() != PQNodeRoot::leaf)
				{
					treeNodes.append(nextSon);
					newNode = G.newNode();  // new node corresponding to anchor
											// or cutnode
					C.reassignNode(newNode,parent);
					graphNodes.append(newNode);

					G.newEdge(next,newNode);
				}
				else
				{
					// insert Edge to the outside
					PQLeaf<edge,IndInfo*,bool>* leaf =
						(PQLeaf<edge,IndInfo*,bool>*) nextSon;
					edge f = leaf->getKey()->m_userStructKey;
					G.newEdge(next,outgoingTable[f]);
					delete leaf->getKey();
				}
				holdSib = nextSon->getNextSib(oldSib);
				oldSib = nextSon;
				nextSon = holdSib;
				pre = next;

			}
			G.newEdge(next,correspond);
		}
	}

	OGDF_ASSERT(C.consistencyCheck());
}
示例#29
0
void CPlanarSubClusteredGraph::call(const ClusterGraph &CGO,
									EdgeArray<bool>& inSub, //original edges in subgraph?
									List<edge>& leftOver,   //original edges not in subgraph
									EdgeArray<double>& edgeWeight) //prefer lightweight edges
{
	leftOver.clear();

	//we compute a c-planar subclustered graph by calling
	//CPlanarSubClusteredST and then perform reinsertion on
	//a copy of the computed subclustered graph
	//initialize "call-global" info arrays
	//edge status
	const Graph& origG = CGO.constGraph();
	m_edgeStatus.init(origG, 0);

	CPlanarSubClusteredST CPST;
	if (edgeWeight.valid())
		CPST.call(CGO, inSub, edgeWeight);
	else
		CPST.call(CGO, inSub);

	//now construct the copy
	//we should create a clusterGraph copy function that
	//builds a clustergraph upon a subgraph of the
	//original graph, preliminarily use fullcopy and delete edges

	ClusterArray<cluster> clusterCopy(CGO);
	NodeArray<node> nodeCopy(origG);
	EdgeArray<edge> edgeCopy(origG);
	Graph testG;
	ClusterGraph CG(CGO, testG, clusterCopy, nodeCopy, edgeCopy);

	CconnectClusterPlanar CCCP;

	//-------------------------------------
	//perform reinsertion of leftover edges
	//fill list of uninserted edges

	EdgeArray<bool> visited(origG,false);

	//delete the non-ST edges
	edge e;
	forall_edges(e, origG)
	{
		if (!inSub[e])
		{
			leftOver.pushBack(e); //original edges
			testG.delEdge(edgeCopy[e]);
		}//if
	}//foralledges

	//todo: cope with preferred edges
	//simple reinsertion strategy: just iterate over list and test
	ListIterator<edge> itE = leftOver.begin();
	while (itE.valid())
	{
		//testG=CG.getGraph()
		edge newCopy = testG.newEdge(nodeCopy[(*itE)->source()],
											 nodeCopy[(*itE)->target()]);
		edgeCopy[*itE] = newCopy;

		bool cplanar = CCCP.call(CG);


		if (!cplanar)
		{
			testG.delEdge(newCopy);
			itE++;
		}//if
		else
		{
			ListIterator<edge> itDel = itE;
			itE++;
			leftOver.del(itDel);
		}
	}//while

	/*
	ListConstIterator<edge> it;
	for(it = preferedEdges.begin(); it.valid(); ++it)
	{
		edge eG = *it;
		visited[eG] = true;

		edge eH = testG.newEdge(toTestG[eG->source()],toTestG[eG->target()]);

		if (preferedImplyPlanar == false && isPlanar(H) == false) {
			testG.delEdge(eH);
			delEdges.pushBack(eG);
		}
	}
	*/


}//call
示例#30
0
文件: GraphIO_dot.cpp 项目: ogdf/ogdf
static bool writeCluster(
	std::ostream &out, int depth,
	const ClusterArray < std::vector<edge> > &edgeMap,
	const ClusterGraph &C, const ClusterGraphAttributes *CA, const cluster &c,
	int &clusterId)
{
	std::ios_base::fmtflags currentFlags = out.flags();
	out.flags(currentFlags | std::ios::fixed);
	bool result = out.good();

	if(result) {
		if (C.rootCluster() == c) {
			writeHeader(out, depth++, CA);
		} else {
			GraphIO::indent(out, depth++) << "subgraph cluster" << clusterId << " {\n";
		}
		clusterId++;

		bool whitespace; // True if a whitespace should printed (readability).

		whitespace = false;
		if (CA) {
			writeAttributes(out, depth, *CA, c);
			whitespace = true;
		}

		if (whitespace) {
			out << "\n";
		}

		// Recursively export all subclusters.
		whitespace = false;
		for (cluster child : c->children) {
			writeCluster(out, depth, edgeMap, C, CA, child, clusterId);
			whitespace = true;
		}

		if (whitespace) {
			out << "\n";
		}

		// Then, print all nodes whithout an adjacent edge.
		whitespace = false;
		for (node v : c->nodes) {
			whitespace |= writeNode(out, depth, CA, v);
		}

		if (whitespace) {
			out << "\n";
		}

		// Finally, we print all edges for this cluster (ugly version for now).
		const std::vector<edge> &edges = edgeMap[c];
		whitespace = false;
		for (auto &e : edges) {
			whitespace |= writeEdge(out, depth, CA, e);
		}

		GraphIO::indent(out, --depth) << "}\n";
	}

	out.flags(currentFlags);

	return result;
}