Toggle navigation
Toggle navigation
This project
Loading...
Sign in
조성현
/
graph-visualization
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
조성현
2017-04-17 22:40:21 +0900
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
4ef6d249747e04a2282d9c5db862d07c9711687d
4ef6d249
1 parent
af4e861f
variable arrange, add topk, get stream input
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
318 additions
and
68 deletions
PaperGraph/GraphItem.cpp
PaperGraph/GraphItem.h
PaperGraph/MainWindow.cpp
PaperGraph/MainWindow.h
PaperGraph/PaperGraphWidget.cpp
PaperGraph/PaperGraphWidget.h
PaperGraph/main.cpp
PaperGraph/stdafx.h
PaperGraph/GraphItem.cpp
View file @
4ef6d24
#include "stdafx.h"
#include "GraphItem.h"
GraphItem
::
GraphItem
(
ifstream
&
fin
,
int
numOfLines
)
GraphItem
::
GraphItem
(
const
char
*
filename
)
{
//numOfLines == ifstream에서 읽을 라인의 수
fin
.
open
(
filename
);
if
(
!
fin
)
throw
std
::
exception
(
"graph file input is invalid"
);
else
if
(
numOfLines
<
1
)
throw
std
::
exception
(
"invalid numOfLines"
);
throw
std
::
exception
(
"graph file is not available"
);
graph
=
new
Graph
();
read_more
();
}
GraphItem
::~
GraphItem
()
{
fin
.
close
();
}
void
GraphItem
::
read_more
()
{
/**
* Parse Paper dataset
* - paper_key, [author_list], publish_year
* Column Delimiter: ||
* Author list Delimiter: &&
*/
* Parse Paper dataset
* - paper_key, [author_list], publish_year
* Column Delimiter: ||
* Author list Delimiter: &&
*/
std
::
string
line
;
vector
<
std
::
string
>
tokens
;
vector
<
std
::
string
>
authors
;
vector
<
pair
<
string
,
string
>>
edges
;
//String <--> int 양방향 변환을 위해 bidirectional map 상숑
//map<string, int> -> <vertex label, vertex index>
/*typedef boost::bimap<string, int> bm_type;*/
/*bm_type node_ids;
vector<simple_edge> edges_indexes*/
;
//int로 변환된 edge
int
node_cnt
=
0
;
/*vector<pair<string, string>> edges;*/
//vector<simple_edge> edges_indexes;
int
line_cnt
=
0
;
qDebug
()
<<
"* graph reading start"
;
//한 줄씩 읽어서 Parse
int
node_cnt
=
0
;
while
(
std
::
getline
(
fin
,
line
)
&&
!
line
.
empty
())
{
//boost::split 이용해 문자열 분리
//tokens[0]: Paper-key. ex) conf/iastedCSN/KeimS06
...
...
@@ -39,53 +43,72 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines)
//tokens[2]: Published year.
boost
::
split
(
tokens
,
line
,
boost
::
is_any_of
(
"||"
),
boost
::
token_compress_on
);
boost
::
split
(
authors
,
tokens
[
1
],
boost
::
is_any_of
(
"&&"
),
boost
::
token_compress_on
);
const
string
&
paper_key
=
tokens
[
0
];
if
(
node_ids
.
left
.
find
(
paper_key
)
==
node_ids
.
left
.
end
())
{
node_ids
.
insert
(
bm_type
::
value_type
(
paper_key
,
node_cnt
++
));
node_ids
.
insert
(
bm_type
::
value_type
(
paper_key
,
node_cnt
+
whole_node_cnt
));
++
node_cnt
;
}
for
(
auto
author
:
authors
)
{
edges
.
push_back
(
pair
<
string
,
string
>
(
paper_key
,
author
));
if
(
node_ids
.
left
.
find
(
author
)
==
node_ids
.
left
.
end
())
{
node_ids
.
insert
(
bm_type
::
value_type
(
author
,
node_cnt
++
));
node_ids
.
insert
(
bm_type
::
value_type
(
author
,
node_cnt
+
whole_node_cnt
));
++
node_cnt
;
}
}
//debug
++
line_cnt
;
if
(
line_cnt
>=
numOfLines
)
break
;
if
(
line_cnt
>=
READ_LINE_UNIT
)
break
;
}
qDebug
()
<<
"* graph reading complete"
;
qDebug
()
<<
"* # of read line: "
<<
line_cnt
;
qDebug
()
<<
"* # of nodes: "
<<
node_cnt
;
qDebug
()
<<
"* # of edges: "
<<
edges
.
size
();
//qDebug() << "* # of edges: " << edges.size();
//edge conversion
//<string, string> to <int, int>
//using boost::bimap (bidirectional map)
edges_indexes
.
clear
();
for
(
auto
edge
:
edges
)
{
edges_indexes
.
push_back
({
node_ids
.
left
.
find
(
edge
.
first
)
->
get_right
(),
node_ids
.
left
.
find
(
edge
.
second
)
->
get_right
()
});
}
//Graph --> defined in "PaperGraphWidget.h"
//Graph graph(edges_indexes.begin(), edges_indexes.end(), node_ids.size());
//graph = new Graph(edges_indexes.begin(), edges_indexes.end(), node_ids.size());
//for (auto& e: edges_indexes) {
// boost::add_edge(e.first, e.second, graph);
//}
if
(
graph
)
{
delete
graph
;
graph
=
nullptr
;
}
graph
=
new
Graph
(
edges_indexes
.
begin
(),
edges_indexes
.
end
(),
node_ids
.
size
());
//set index property
qDebug
()
<<
"* set vertex property start"
;
vertex_iterator
vi
,
vi_end
;
int
i
=
0
;
for
(
boost
::
tie
(
vi
,
vi_end
)
=
vertices
(
*
graph
);
vi
!=
vi_end
;
++
vi
)
{
for
(
boost
::
tie
(
vi
,
vi_end
)
=
vertices
(
*
graph
);
vi
!=
vi_end
;
++
vi
)
{
//Vertex Property 설정
//index:
0
~ ...
//index:
n
~ ...
//name : map의 value(i) 기준으로 찾은 Key
// map --> map<string, int> (boost bidirectional map)
//
map --> map<string, int> (boost bidirectional map)
std
::
string
node_label
=
node_ids
.
right
.
find
(
i
)
->
get_left
();
boost
::
put
(
vertex_index
,
*
graph
,
*
vi
,
i
);
boost
::
put
(
vertex_name
,
*
graph
,
*
vi
,
node_label
);
boost
::
put
(
vertex_record
,
*
graph
,
*
vi
,
0
);
qDebug
()
<<
"** index: "
<<
i
<<
", name: "
<<
node_label
.
c_str
();
//node type 설정
if
(
boost
::
regex_match
(
node_label
,
paper_reg
))
{
...
...
@@ -99,7 +122,7 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines)
++
i
;
}
qDebug
()
<<
"* set vertex property end"
;
whole_node_cnt
+=
node_cnt
;
//qDebug("* set edges weight start");
////모든 edge의 weight를 1로 설정
...
...
@@ -133,7 +156,7 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines)
//while (current != boost::vertex(start_idx, *graph)) {
//}
//qDebug("* path highlighting end");
//graph layout calculation
//using boost::random_graph_layout and boost::kamada_kawai_spring_layout
...
...
@@ -148,18 +171,18 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines)
Topology
::
point_difference_type
extent
;
extent
[
0
]
=
extent
[
1
]
=
(
double
)
SCREEN_SIZE
;
rectangle_topology
<>
rect_top
(
gen
,
-
SCREEN_SIZE
/
2
,
-
SCREEN_SIZE
/
2
,
SCREEN_SIZE
/
2
,
SCREEN_SIZE
/
2
);
-
SCREEN_SIZE
/
2
,
-
SCREEN_SIZE
/
2
,
SCREEN_SIZE
/
2
,
SCREEN_SIZE
/
2
);
switch
(
LAYOUT_MODE
)
{
case
GRAPH_LAYOUT
:
:
RANDOM_LAYOUT
:
random_graph_layout
(
*
graph
,
get
(
vertex_position
,
*
graph
),
rect_top
);
break
;
case
GRAPH_LAYOUT
:
:
CIRCLE_LAYOUT
:
circle_graph_layout
(
*
graph
,
get
(
vertex_position
,
*
graph
),
SCREEN_SIZE
/
2
);
circle_graph_layout
(
*
graph
,
get
(
vertex_position
,
*
graph
),
SCREEN_SIZE
/
2
);
break
;
case
GRAPH_LAYOUT
:
:
FRUCHTERMAN_REINGOLD_LAYOUT
:
fruchterman_reingold_force_directed_layout
(
*
graph
,
get
(
vertex_position
,
*
graph
),
...
...
@@ -172,14 +195,18 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines)
qDebug
()
<<
"* make graph layout end"
;
//clear lists
nodeList
.
clear
();
edgeList
.
clear
();
//add edges
auto
position
=
get
(
vertex_position
,
*
graph
);
auto
label
=
get
(
vertex_name
,
*
graph
);
auto
nodeType
=
get
(
vertex_type
,
*
graph
);
auto
position
=
boost
::
get
(
vertex_position
,
*
graph
);
auto
label
=
boost
::
get
(
vertex_name
,
*
graph
);
auto
nodeType
=
boost
::
get
(
vertex_type
,
*
graph
);
edge_iterator
ei
,
ei_end
;
vertex_descriptor
u
,
v
;
for
(
boost
::
tie
(
ei
,
ei_end
)
=
boost
::
edges
(
*
graph
);
ei
!=
ei_end
;
++
ei
)
{
for
(
boost
::
tie
(
ei
,
ei_end
)
=
boost
::
edges
(
*
graph
);
ei
!=
ei_end
;
++
ei
)
{
u
=
source
(
*
ei
,
*
graph
);
v
=
target
(
*
ei
,
*
graph
);
Point
p1
=
position
[
u
];
...
...
@@ -187,14 +214,14 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines)
//make edge item and push it to list
EdgeItem
*
edge
;
edge
=
new
EdgeItem
(
p1
[
0
],
p1
[
1
],
p2
[
0
],
p2
[
1
],
QColor
(
Qt
::
black
),
0
);
edge
->
setPos
(
p1
[
0
],
p1
[
1
]);
edgeList
<<
edge
;
}
//add nodes
for
(
boost
::
tie
(
vi
,
vi_end
)
=
vertices
(
*
graph
);
vi
!=
vi_end
;
++
vi
)
{
for
(
boost
::
tie
(
vi
,
vi_end
)
=
vertices
(
*
graph
);
vi
!=
vi_end
;
++
vi
)
{
Point
p
=
position
[
*
vi
];
auto
nt
=
nodeType
[
*
vi
];
std
::
string
name
=
label
[
*
vi
];
...
...
@@ -203,7 +230,8 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines)
NodeItem
*
node
;
if
(
nt
==
NODE_TYPE
::
NODE_PAPER
)
{
node
=
new
NodeItem
(
p
[
0
],
p
[
1
],
QColor
(
Qt
::
darkGreen
),
QString
(
name
.
c_str
()),
nt
);
}
else
{
}
else
{
node
=
new
NodeItem
(
p
[
0
],
p
[
1
],
QColor
(
Qt
::
green
),
QString
(
name
.
c_str
()),
nt
);
}
node
->
setPos
(
QPointF
(
p
[
0
],
p
[
1
]));
...
...
@@ -262,6 +290,63 @@ void GraphItem::reset_color()
}
}
void
GraphItem
::
topK_highlight
()
{
// 저자 노드별 실적 계산
vertex_iterator
vi
,
vi_end
;
Graph
::
adjacency_iterator
ai
,
ai_end
;
auto
nodeLabel
=
boost
::
get
(
vertex_name
,
*
graph
);
auto
nodeType
=
boost
::
get
(
vertex_type
,
*
graph
);
auto
numOfRecords
=
boost
::
get
(
vertex_record
,
*
graph
);
//실적 count 초기화
//for (boost::tie(vi, vi_end) = boost::vertices(*graph); vi != vi_end; ++vi) {
// if (nodeType[*vi] != NODE_TYPE::NODE_AUTHOR) {
// continue;
// }
// boost::put(vertex_record, *graph, *vi, 0);
//}
// <record, label>
TopKHeap
<
pair
<
int
,
string
>>
heap
(
TOP_K
);
for
(
boost
::
tie
(
vi
,
vi_end
)
=
boost
::
vertices
(
*
graph
);
vi
!=
vi_end
;
++
vi
)
{
if
(
nodeType
[
*
vi
]
!=
NODE_TYPE
::
NODE_AUTHOR
)
{
continue
;
}
int
record_cnt
=
0
;
for
(
boost
::
tie
(
ai
,
ai_end
)
=
boost
::
adjacent_vertices
(
*
vi
,
*
graph
);
ai
!=
ai_end
;
++
ai
)
{
if
(
nodeType
[
*
vi
]
==
NODE_TYPE
::
NODE_PAPER
)
{
++
record_cnt
;
}
}
boost
::
put
(
vertex_record
,
*
graph
,
*
vi
,
record_cnt
);
heap
.
push
(
make_pair
(
record_cnt
,
nodeLabel
[
*
vi
]));
}
//get top K records
pair
<
int
,
string
>
topk_arr
[
TOP_K
];
for
(
int
i
=
0
;
i
<
TOP_K
;
++
i
)
{
topk_arr
[
i
]
=
heap
.
pop
();
}
for
(
auto
&
n
:
nodeList
)
{
auto
label
=
n
->
getLabel
();
n
->
setColor
(
QColor
(
Qt
::
lightGray
));
for
(
auto
&
p
:
topk_arr
)
{
if
(
label
.
toStdString
()
==
p
.
second
)
{
n
->
setColor
(
QColor
(
Qt
::
red
));
break
;
}
}
}
//delete[] topk_arr;
}
//event handler
void
GraphItem
::
mousePressEvent
(
QGraphicsSceneMouseEvent
*
event
)
{
...
...
PaperGraph/GraphItem.h
View file @
4ef6d24
...
...
@@ -13,7 +13,12 @@ class GraphItem
:
public
QGraphicsItem
{
public
:
GraphItem
(
ifstream
&
fin
,
int
numOfLines
);
//GraphItem(ifstream* pFin);
GraphItem
(
const
char
*
filename
);
virtual
~
GraphItem
();
//io
void
read_more
();
//overrides
QRectF
boundingRect
()
const
override
;
...
...
@@ -23,6 +28,7 @@ public:
//methods
void
path_highlighting
(
std
::
string
start
,
std
::
string
end
);
void
reset_color
();
void
topK_highlight
();
protected
:
void
mousePressEvent
(
QGraphicsSceneMouseEvent
*
event
)
override
;
...
...
@@ -30,8 +36,12 @@ protected:
void
mouseReleaseEvent
(
QGraphicsSceneMouseEvent
*
event
)
override
;
private
:
ifstream
fin
;
bm_type
node_ids
;
vector
<
pair
<
string
,
string
>>
edges
;
vector
<
simple_edge
>
edges_indexes
;
int
whole_node_cnt
=
0
;
Graph
*
graph
=
nullptr
;
QList
<
NodeItem
*>
nodeList
;
QList
<
EdgeItem
*>
edgeList
;
...
...
PaperGraph/MainWindow.cpp
View file @
4ef6d24
...
...
@@ -25,35 +25,56 @@ MainWindow::~MainWindow()
}
void
MainWindow
::
print_graph
(
std
::
ifstream
&
fin
)
void
MainWindow
::
print_graph
(
const
char
*
filename
)
{
graphWidget
->
print_graph
(
fi
n
);
graphWidget
->
print_graph
(
fi
lename
);
}
//void MainWindow::print_graph(std::ifstream *pFin)
//{
// graphWidget->print_graph(pFin);
//}
//////////////////////////////////////////////////////////////////
// private methods
//////////////////////////////////////////////////////////////////
void
MainWindow
::
createActions
()
{
testHighlightAct
=
new
QAction
(
tr
(
"&Highlight"
),
this
);
readMoreAct
=
new
QAction
(
tr
(
"Read more"
),
this
);
readMoreAct
->
setStatusTip
(
tr
(
"read more lines from file"
));
connect
(
readMoreAct
,
&
QAction
::
triggered
,
this
,
&
MainWindow
::
read_more
);
testHighlightAct
=
new
QAction
(
tr
(
"Highlight"
),
this
);
testHighlightAct
->
setStatusTip
(
tr
(
"Highlighting node"
));
connect
(
testHighlightAct
,
&
QAction
::
triggered
,
this
,
&
MainWindow
::
test_highlighting
);
resetColorAct
=
new
QAction
(
tr
(
"&Reset colors"
),
this
);
topkAct
=
new
QAction
(
tr
(
"topK"
),
this
);
topkAct
->
setStatusTip
(
tr
(
"highlight who was top k papers"
));
connect
(
topkAct
,
&
QAction
::
triggered
,
this
,
&
MainWindow
::
topk
);
resetColorAct
=
new
QAction
(
tr
(
"Reset colors"
),
this
);
resetColorAct
->
setStatusTip
(
tr
(
"Reset all node's color"
));
connect
(
resetColorAct
,
&
QAction
::
triggered
,
this
,
&
MainWindow
::
reset_color
);
}
void
MainWindow
::
createMenus
()
{
fileMenu
=
menuBar
()
->
addMenu
(
tr
(
"&File"
));
fileMenu
->
addAction
(
readMoreAct
);
actionMenu
=
menuBar
()
->
addMenu
(
tr
(
"&Actions"
));
actionMenu
->
addAction
(
testHighlightAct
);
actionMenu
->
addAction
(
topkAct
);
actionMenu
->
addAction
(
resetColorAct
);
}
//////////////////////////////////////////////////////////////////
// slots
//////////////////////////////////////////////////////////////////
void
MainWindow
::
read_more
()
{
qDebug
(
"* MainWindow::read_more"
);
graphWidget
->
read_more
();
}
void
MainWindow
::
test_highlighting
()
{
/*QMessageBox::information(this, "test",
...
...
@@ -62,7 +83,12 @@ void MainWindow::test_highlighting()
//graphWidget->update();
}
void
MainWindow
::
topk
()
{
graphWidget
->
topk
();
}
void
MainWindow
::
reset_color
()
{
graphWidget
->
reset_color
();
}
\ No newline at end of file
}
...
...
PaperGraph/MainWindow.h
View file @
4ef6d24
...
...
@@ -12,14 +12,18 @@ public:
MainWindow
(
QWidget
*
parent
=
0
);
~
MainWindow
();
void
print_graph
(
std
::
ifstream
&
fin
);
/*void test_highlighting();*/
//void print_graph(std::ifstream *pFin);
void
print_graph
(
const
char
*
filename
);
private
:
PaperGraphWidget
*
graphWidget
;
QMenu
*
fileMenu
;
QAction
*
readMoreAct
;
QMenu
*
actionMenu
;
QAction
*
testHighlightAct
;
QAction
*
topkAct
;
QAction
*
resetColorAct
;
private
:
...
...
@@ -27,7 +31,9 @@ private:
void
createMenus
();
private
slots
:
void
read_more
();
void
test_highlighting
();
void
topk
();
void
reset_color
();
};
...
...
PaperGraph/PaperGraphWidget.cpp
View file @
4ef6d24
...
...
@@ -25,23 +25,47 @@ PaperGraphWidget::PaperGraphWidget(QWidget *parent)
setWindowTitle
(
tr
(
"dblp paper graph visualization"
));
}
void
PaperGraphWidget
::
print_graph
(
ifstream
&
fin
)
//void PaperGraphWidget::print_graph(ifstream* pFin)
//{
// qDebug("* PaperGraphWidget::print_graph");
// //QGraphicsItem *graph_item = new GraphItem(fin);
// if (graphItem)
// throw std::exception("already have graph item");
//
// graphItem = new GraphItem(pFin);
// graphItem->setPos(0, 0);
// scene->addItem(graphItem);
//}
void
PaperGraphWidget
::
print_graph
(
const
char
*
filename
)
{
//QGraphicsItem *graph_item = new GraphItem(fin);
if
(
graphItem
)
throw
std
::
exception
(
"already have graph item"
);
graphItem
=
new
GraphItem
(
fi
n
,
READ_LINE_UNIT
);
graphItem
=
new
GraphItem
(
fi
lename
);
graphItem
->
setPos
(
0
,
0
);
scene
->
addItem
(
graphItem
);
}
void
PaperGraphWidget
::
read_more
()
{
qDebug
(
"* PaperGraphWidget::read_more"
);
graphItem
->
read_more
();
scene
->
update
();
}
void
PaperGraphWidget
::
path_highlight
()
{
graphItem
->
path_highlighting
(
std
::
string
(
""
),
std
::
string
(
""
));
scene
->
update
();
}
void
PaperGraphWidget
::
topk
()
{
graphItem
->
topK_highlight
();
scene
->
update
();
}
void
PaperGraphWidget
::
reset_color
()
{
graphItem
->
reset_color
();
...
...
PaperGraph/PaperGraphWidget.h
View file @
4ef6d24
...
...
@@ -11,9 +11,13 @@ class PaperGraphWidget : public QWidget
public
:
PaperGraphWidget
(
QWidget
*
parent
=
0
);
void
print_graph
(
ifstream
&
fin
);
//void print_graph(ifstream* pFin);
void
print_graph
(
const
char
*
filename
);
//main window slots
void
read_more
();
void
path_highlight
();
void
topk
();
void
reset_color
();
private
slots
:
...
...
PaperGraph/main.cpp
View file @
4ef6d24
...
...
@@ -9,9 +9,9 @@ int main(int argc, char *argv[])
MainWindow
m
;
try
{
ifstream
fin
(
PAPER_FILENAME
);
m
.
print_graph
(
fin
);
fin
.
close
();
//
ifstream fin(PAPER_FILENAME);
m
.
print_graph
(
PAPER_FILENAME
);
//
fin.close();
}
catch
(
const
std
::
exception
&
e
)
{
qDebug
()
<<
"Error: "
<<
e
.
what
();
return
EXIT_FAILURE
;
...
...
PaperGraph/stdafx.h
View file @
4ef6d24
...
...
@@ -28,13 +28,20 @@
#include <boost/graph/topology.hpp>
#include <boost/regex.hpp>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <exception>
#include <fstream>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <queue>
#include <string>
#include <utility>
#include <vector>
using
namespace
boost
;
...
...
@@ -43,9 +50,11 @@ using namespace std;
/* enums */
enum
vertex_position_t
{
vertex_position
};
enum
vertex_type_t
{
vertex_type
};
enum
vertex_record_t
{
vertex_record
};
namespace
boost
{
BOOST_INSTALL_PROPERTY
(
vertex
,
position
);
BOOST_INSTALL_PROPERTY
(
vertex
,
type
);
BOOST_INSTALL_PROPERTY
(
vertex
,
record
);
}
enum
NODE_TYPE
{
NODE_PAPER
,
...
...
@@ -64,7 +73,8 @@ typedef square_topology<>::point_type point;
typedef
boost
::
property
<
vertex_index_t
,
int
,
boost
::
property
<
vertex_name_t
,
std
::
string
,
boost
::
property
<
vertex_position_t
,
point
,
boost
::
property
<
vertex_type_t
,
int
>>>
boost
::
property
<
vertex_type_t
,
int
,
boost
::
property
<
vertex_record_t
,
int
>>>>
>
VertexProperties
;
typedef
boost
::
adjacency_list
<
listS
,
//outEdgeList
...
...
@@ -77,6 +87,7 @@ typedef boost::adjacency_list<
>
Graph
;
typedef
typename
graph_traits
<
Graph
>::
edge_iterator
edge_iterator
;
typedef
typename
graph_traits
<
Graph
>::
vertex_iterator
vertex_iterator
;
//typedef boost::graph_traits<Graph>::adjacency_iterator adjacency_iterator;
typedef
boost
::
graph_traits
<
Graph
>::
vertex_descriptor
vertex_descriptor
;
typedef
square_topology
<>
Topology
;
typedef
typename
Topology
::
point_type
Point
;
...
...
@@ -95,14 +106,98 @@ namespace {
const
int
NODE_SIZE
=
4
;
const
int
LAYOUT_MODE
=
GRAPH_LAYOUT
::
RANDOM_LAYOUT
;
const
int
SCREEN_SIZE
=
1000
;
const
int
READ_LINE_UNIT
=
100
;
//한 번에 몇 라인을 읽을지
const
int
READ_LINE_UNIT
=
5
;
//한 번에 몇 라인을 읽을지
/* topK */
const
int
TOP_K
=
10
;
//상위 몇 개 아이템에 대해 할 지
const
int
TOP_K
=
10
;
//상위 몇 개 아이템에 대해
highlight
할 지
}
/* boost */
namespace
boost
{
const
boost
::
regex
paper_reg
(
"(conf|journals).*"
);
}
\ No newline at end of file
}
/* topK heap */
template
<
typename
T
>
class
TopKHeap
{
private
:
int
k
;
//max size
int
size
;
//current size
T
*
heap
;
private
:
void
reHeapDown
(
int
root
)
{
//after pop
int
minIdx
,
left
,
right
;
left
=
root
*
2
+
1
;
right
=
root
*
2
+
2
;
if
(
left
<=
(
size
-
1
))
{
if
(
left
==
(
size
-
1
))
minIdx
=
left
;
else
{
minIdx
=
((
heap
[
left
]
<=
heap
[
right
])
?
left
:
right
);
}
if
(
heap
[
root
]
>
heap
[
minIdx
])
{
swap
(
heap
[
root
],
heap
[
minIdx
]);
reHeapDown
(
minIdx
);
}
}
}
void
reHeapUp
(
int
root
,
int
bottom
)
{
//bottom: 위로 올릴 노드 idx
//after push
if
(
root
>
bottom
)
{
int
parent
=
(
bottom
-
1
)
/
2
;
if
(
heap
[
parent
]
<
heap
[
bottom
])
{
swap
(
heap
[
parent
],
heap
[
bottom
]);
reHeapUp
(
root
,
parent
);
}
}
}
public
:
TopKHeap
(
int
_k
)
:
k
(
_k
),
size
(
0
)
{
if
(
_k
<=
0
)
abort
();
heap
=
new
T
[
_k
];
memset
(
heap
,
0
,
sizeof
(
heap
));
}
~
TopKHeap
()
{
if
(
heap
)
delete
[]
heap
;
}
public
:
void
push
(
T
elem
)
{
if
(
size
<
k
)
{
heap
[
size
++
]
=
elem
;
}
else
{
if
(
elem
<
heap
[
0
])
{
//less than minimum
}
else
{
pop
();
heap
[
size
++
]
=
elem
;
}
}
reHeapUp
(
0
,
size
-
1
);
}
T
pop
()
{
if
(
size
<=
0
)
abort
();
else
if
(
size
==
1
)
{
T
ret
=
heap
[
--
size
];
return
ret
;
}
else
{
T
ret
=
heap
[
0
];
heap
[
0
]
=
heap
[
--
size
];
reHeapDown
(
0
);
return
ret
;
}
}
};
\ No newline at end of file
...
...
Please
register
or
login
to post a comment