File: MultilevelGraph.h

package info (click to toggle)
tulip 4.8.0dfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 179,264 kB
  • ctags: 64,517
  • sloc: cpp: 600,444; ansic: 36,311; makefile: 22,136; python: 1,304; sh: 946; yacc: 522; xml: 337; pascal: 157; php: 66; lex: 55
file content (177 lines) | stat: -rw-r--r-- 6,185 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*
 * $Revision: 4180 $
 *
 * last checkin:
 *   $Author: klein $
 *   $Date: 2014-06-05 16:01:57 +0200 (Thu, 05 Jun 2014) $
 ***************************************************************/

/** \file
 * \brief MLG is the main data structure for ModularMultilevelMixer
 *
 * \author Gereon Bartel
 *
 * \par License:
 * This file is part of the Open Graph Drawing Framework (OGDF).
 *
 * \par
 * Copyright (C)<br>
 * See README.txt in the root directory of the OGDF installation for details.
 *
 * \par
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * Version 2 or 3 as published by the Free Software Foundation;
 * see the file LICENSE.txt included in the packaging of this file
 * for details.
 *
 * \par
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * \par
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 * \see  http://www.gnu.org/copyleft/gpl.html
 ***************************************************************/

#ifdef _MSC_VER
#pragma once
#endif

#ifndef OGDF_MULTILEVEL_GRAPH_H
#define OGDF_MULTILEVEL_GRAPH_H

#include <ogdf/basic/Graph.h>
#include <ogdf/basic/GraphAttributes.h>
#include <vector>
#include <map>

namespace ogdf {

//Stores info on merging for a refinement level
struct NodeMerge
{
	// Node/Edge IDs instead of pointers as the nodes themselves may be nonexistent.
	std::vector<int> m_deletedEdges;
	std::vector<int> m_changedEdges;
	std::map<int, double> m_doubleWeight; // for changed and deleted edges
	std::map<int, int> m_source;
	std::map<int, int> m_target;

	int m_mergedNode;
	std::vector< std::pair<int, double> > m_position; // optional information <target, distance>. mergedNode will be placed at average of relative distances to target.

	std::vector<int> m_changedNodes; // there may be placement strategies that use more than one reference-node.
	std::map<int, double> m_radius; // for changed nodes and the merged node

	int m_level;


	NodeMerge(int level) : m_level(level) { }
	~NodeMerge() { }
};


class OGDF_EXPORT MultilevelGraph
{
private:
	bool m_createdGraph; //used in destructor, TODO: check if it is needed
	Graph * m_G;
	GraphAttributes * m_GA; //<! Keeps layout info in replacement of information below (todo: remove them)
	std::vector<NodeMerge *> m_changes;
	NodeArray<double> m_radius;
	double m_avgRadius; //stores average node radius for scaling and random layout purposes

	EdgeArray<double> m_weight;

	// Associations to index only as the node/edge may be nonexistent
	NodeArray<int> m_nodeAssociations;
	EdgeArray<int> m_edgeAssociations;

	std::vector<node> m_reverseNodeIndex;
	std::vector<int> m_reverseNodeMergeWeight;//<! Keeps number of vertices represented by vertex with given index
	std::vector<edge> m_reverseEdgeIndex;

	MultilevelGraph * removeOneCC(std::vector<node> &componentSubArray);
	void copyFromGraph(const Graph &G, NodeArray<int> &nodeAssociations, EdgeArray<int> &edgeAssociations);
	void prepareGraphAttributes(GraphAttributes &GA) const;

	void initReverseIndizes();
	void initInternal();

public:
	~MultilevelGraph();
	MultilevelGraph();
	MultilevelGraph(Graph &G);
	MultilevelGraph(GraphAttributes &GA);
	// if the Graph is available without const, no copy needs to be created.
	MultilevelGraph(GraphAttributes &GA, Graph &G);

	// creates MultilevelGraph directly from GML file.
	MultilevelGraph(istream &is);
	MultilevelGraph(const char *filename);

	NodeArray<double> &getRArray() { return m_radius; }
	EdgeArray<double> &getWArray() { return m_weight; }

	edge getEdge(unsigned int index);
	node getNode(unsigned int index);

	double radius(node v) { return m_radius[v]; }
	void radius(node v, double r) { m_radius[v] = r; }
	double averageRadius() const { return m_avgRadius;}

	double x(node v) { return m_GA->x(v); }
	double y(node v) { return m_GA->y(v); }
	void x(node v, double x) { m_GA->x(v) = x;}
	void y(node v, double y) { m_GA->y(v) = y;}

	void weight(edge e, double weight) { m_weight[e] = weight; }
	double weight(edge e) { return m_weight[e]; }

	//returns the merge weight, i.e. the number of nodes represented by v on the current level
	int mergeWeight(node v) {return m_reverseNodeMergeWeight[v->index()];}

	void moveToZero();

	int getLevel();
	Graph & getGraph() { return *m_G; }
	//! Returns attributes of current level graph as GraphAttributes
	GraphAttributes & getGraphAttributes() const { return *m_GA; }
	void exportAttributes(GraphAttributes &GA) const;
	void exportAttributesSimple(GraphAttributes &GA) const;
	void importAttributes(const GraphAttributes &GA);
	void importAttributesSimple(const GraphAttributes &GA);
	void reInsertGraph(MultilevelGraph &MLG);
	void reInsertAll(std::vector<MultilevelGraph *> &components);
	void copyNodeTo(node v, MultilevelGraph &MLG, std::map<node, node> &tempNodeAssociations, bool associate, int index = -1);
	void copyEdgeTo(edge e, MultilevelGraph &MLG, std::map<node, node> &tempNodeAssociations, bool associate, int index = -1);
	void writeGML(ostream &os);
	void writeGML(const char *fileName);

	// the original graph will be cleared to save Memory
	std::vector<MultilevelGraph *> splitIntoComponents();

	bool postMerge(NodeMerge * NM, node merged);
	//\a merged is the node now represented by \a theNode
	bool changeNode(NodeMerge * NM, node theNode, double newRadius, node merged);
	bool changeEdge(NodeMerge * NM, edge theEdge, double newWeight, node newSource, node newTarget);
	bool deleteEdge(NodeMerge * NM, edge theEdge);
	std::vector<edge> moveEdgesToParent(NodeMerge * NM, node theNode, node parent, bool deleteDoubleEndges, int adjustEdgeLengths);
	NodeMerge * getLastMerge();
	node undoLastMerge();

	void updateReverseIndizes();
	//sets the merge weights back to initial values
	void updateMergeWeights();
};

} // namespace ogdf

#endif