조성현

중간저장

#include "stdafx.h"
#include "ChartDialog.h"
ChartDialog::ChartDialog()
{
}
ChartDialog::~ChartDialog()
{
}
#pragma once
#include "stdafx.h"
class ChartDialog : public QDialog
{
private:
public:
ChartDialog();
virtual ~ChartDialog();
};
......@@ -36,6 +36,11 @@ void GraphItem::read_more()
auto node_label_map = boost::get(vertex_name, *graph);
auto node_type_map = boost::get(vertex_type, *graph);
auto node_citation_map = boost::get(vertex_citation, *graph);
auto node_pagerank_map = boost::get(vertex_pagerank, *graph);
auto node_category_map = boost::get(vertex_category, *graph);
auto node_title_map = boost::get(vertex_title, *graph);
auto node_year_map = boost::get(vertex_year, *graph);
auto node_category_accuracy_map = boost::get(vertex_category_accuracy, *graph);
int line_cnt = 0;
qDebug() << "* graph reading start";
......@@ -116,8 +121,7 @@ void GraphItem::read_more()
//Paper일 경우
//vertex type 설정
boost::put(vertex_type, *graph, *vi, NODE_TYPE::NODE_PAPER);
//citation counting
#ifdef CITATION_COUNT
//bibtex 다운로드
std::string dblp_url = std::string("http://dblp.uni-trier.de/rec/bib1/") + node_label;
_curl_processor.set_url(dblp_url.c_str());
......@@ -137,6 +141,7 @@ void GraphItem::read_more()
_curl_processor.set_url(json_address.c_str());
_curl_processor.perform();
//citation 카운트
_json_processor.read_json(_curl_processor.get_buffer());
if (!_json_processor.is_ok()) {
node_citation_map[*vi] = 0;
......@@ -145,6 +150,20 @@ void GraphItem::read_more()
node_citation_map[*vi] = _json_processor.get_citation_count();
}
}
//논문제목(title), year 등 기타정보 받아오기
std::string title, year_str;
int year;
_bibtex_processor.get_value("title", title);
_bibtex_processor.get_value("year", year_str);
year = stoi(year_str);
node_title_map[*vi] = title;
node_year_map[*vi] = year;
#endif // CITATION_COUNT
//카테고리 계산 및 accuracy 계산
//--> case insensitive
} else {
//Author
boost::put(vertex_type, *graph, *vi, NODE_TYPE::NODE_AUTHOR);
......@@ -699,75 +718,75 @@ void GraphItem::topK_highlight_with_target()
delete[] topk_arr;
}
void GraphItem::topK_using_custom_score()
{
// 전체 그래프 기준 topK highlight
// 저자 노드별 실적 계산
vertex_iterator vi, vi_end;
Graph::adjacency_iterator ai, ai_end;
auto node_label_map = boost::get(vertex_name, *graph);
auto node_type_map = boost::get(vertex_type, *graph);
auto node_records_map = boost::get(vertex_record, *graph);
//k 입력
bool isok = false;
QInputDialog *inputDialog = new QInputDialog();
//int inputK = inputDialog->getText(nullptr, "Enter target's name", "Start node's name:",
// QLineEdit::Normal, "Akira Idoue", &isok).toStdString();
int inputK = inputDialog->getInt(nullptr, "Enter K", "K:", 3,
1, whole_node_cnt, 1, &isok);
if (!isok) {
qDebug("input cancelled");
return;
}
//저자별 논문 수 계산 + TopK Heap 사용
//pair -> <num_of_record, label>
TopKHeap<pair<int, string>> heap(inputK);
for (boost::tie(vi, vi_end) = boost::vertices(*graph); vi != vi_end; ++vi) {
if (node_type_map[*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 (node_type_map[*ai] == NODE_TYPE::NODE_PAPER) {
++record_cnt;
}
}
boost::put(vertex_record, *graph, *vi, record_cnt);
heap.push(make_pair(record_cnt, node_label_map[*vi]));
//qDebug() << record_cnt;
}
//get top K records
//pair<int, string> topk_arr[inputK];
pair<int, string> *topk_arr = new pair<int, string>[inputK];
for (int i = 0; i < inputK; ++i) {
topk_arr[i] = heap.pop();
qDebug() << "topk[" << i << "] = " << topk_arr[i].first << ", " << QString::fromStdString(topk_arr[i].second);
}
for (auto& n : nodeList) {
auto label = n->getLabel();
n->setColor(QColor(Qt::lightGray));
for (int i = 0; i < inputK; ++i) {
auto& p = topk_arr[i];
if (label.toStdString() == p.second) {
n->setColor(QColor(Qt::red));
break;
}
}
}
delete[] topk_arr;
}
//void GraphItem::topK_using_custom_score()
//{
// // 전체 그래프 기준 topK highlight
//
// // 저자 노드별 실적 계산
// vertex_iterator vi, vi_end;
// Graph::adjacency_iterator ai, ai_end;
//
// auto node_label_map = boost::get(vertex_name, *graph);
// auto node_type_map = boost::get(vertex_type, *graph);
// auto node_records_map = boost::get(vertex_record, *graph);
//
// //k 입력
// bool isok = false;
//
// QInputDialog *inputDialog = new QInputDialog();
// //int inputK = inputDialog->getText(nullptr, "Enter target's name", "Start node's name:",
// // QLineEdit::Normal, "Akira Idoue", &isok).toStdString();
// int inputK = inputDialog->getInt(nullptr, "Enter K", "K:", 3,
// 1, whole_node_cnt, 1, &isok);
// if (!isok) {
// qDebug("input cancelled");
// return;
// }
//
// //저자별 논문 수 계산 + TopK Heap 사용
// //pair -> <num_of_record, label>
// TopKHeap<pair<int, string>> heap(inputK);
// for (boost::tie(vi, vi_end) = boost::vertices(*graph); vi != vi_end; ++vi) {
// if (node_type_map[*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 (node_type_map[*ai] == NODE_TYPE::NODE_PAPER) {
// ++record_cnt;
// }
// }
//
// boost::put(vertex_record, *graph, *vi, record_cnt);
// heap.push(make_pair(record_cnt, node_label_map[*vi]));
//
// //qDebug() << record_cnt;
// }
//
// //get top K records
// //pair<int, string> topk_arr[inputK];
// pair<int, string> *topk_arr = new pair<int, string>[inputK];
// for (int i = 0; i < inputK; ++i) {
// topk_arr[i] = heap.pop();
// qDebug() << "topk[" << i << "] = " << topk_arr[i].first << ", " << QString::fromStdString(topk_arr[i].second);
// }
//
//
// for (auto& n : nodeList) {
// auto label = n->getLabel();
// n->setColor(QColor(Qt::lightGray));
// for (int i = 0; i < inputK; ++i) {
// auto& p = topk_arr[i];
// if (label.toStdString() == p.second) {
// n->setColor(QColor(Qt::red));
// break;
// }
// }
// }
// delete[] topk_arr;
//}
void GraphItem::find_shortest_path()
{
......@@ -892,6 +911,60 @@ void GraphItem::find_shortest_path()
qDebug("* path highlighting end");
}
void GraphItem::topk_with_pagerank() {
//k 입력
bool isok = false;
QInputDialog *inputDialog = new QInputDialog();
int inputK = inputDialog->getInt(nullptr, "Enter K", "K:", 3,
1, whole_node_cnt, 1, &isok);
if (!isok) {
qDebug("input cancelled");
return;
}
//전체노드 색 변경
for (auto& n : nodeList) {
n->setColor(Qt::lightGray);
}
auto node_label_map = boost::get(vertex_name, *graph);
auto node_pagerank_map = boost::get(vertex_pagerank, *graph);
vertex_iterator vi, vi_end;
//페이지랭크 계산
qDebug("* pagerank start");
boost::graph::page_rank(*graph, node_pagerank_map);
for (boost::tie(vi, vi_end) = vertices(*graph); vi != vi_end; ++vi) {
printf("%s\t\t%f\n", node_label_map[*vi].c_str(),
node_pagerank_map[*vi]);
}
qDebug("* pagerank end");
//페이지랭크 topK 계산
TopKHeap<pair<double, string>> heap(inputK);
for (boost::tie(vi, vi_end) = vertices(*graph); vi != vi_end; ++vi) {
heap.push(make_pair(node_pagerank_map[*vi], node_label_map[*vi]));
}
pair<double, string> *topk_arr = new pair<double, string>[inputK];
for (int i = 0; i < inputK; ++i) {
topk_arr[i] = heap.pop();
qDebug() << "topk[" << i << "] = " << topk_arr[i].first << ", " << QString::fromStdString(topk_arr[i].second);
}
for (auto& n : nodeList) {
auto label = n->getLabel();
n->setColor(QColor(Qt::lightGray));
for (int i = 0; i < inputK; ++i) {
auto& p = topk_arr[i];
if (label.toStdString() == p.second) {
n->setColor(QColor(Qt::red));
break;
}
}
}
delete[] topk_arr;
}
void GraphItem::reset_color()
{
for (auto& n: nodeList) {
......
......@@ -8,6 +8,7 @@
using namespace std;
using namespace boost;
//#define CITATION_COUNT
class GraphItem
: public QGraphicsItem
......@@ -29,8 +30,9 @@ public:
void might_know();
void topK_highlight_with_total();
void topK_highlight_with_target();
void topK_using_custom_score();
//void topK_using_custom_score();
void find_shortest_path();
void topk_with_pagerank();
void reset_color();
//test
......
......@@ -52,6 +52,9 @@ void MainWindow::createActions()
findShortestPathAct = new QAction(tr("Find Shortest Path"), this);
findShortestPathAct->setStatusTip("Find shortest path between two node");
connect(findShortestPathAct, &QAction::triggered, this, &MainWindow::find_shortest_path);
topkWithPagerankAct = new QAction(tr("topK with pagerank"), this);
topkWithPagerankAct->setStatusTip(tr("highlight which is in top k pagerank in whole graph"));
connect(topkWithPagerankAct, &QAction::triggered, this, &MainWindow::topk_with_pagerank);
resetColorAct = new QAction(tr("Reset colors"), this);
resetColorAct->setStatusTip(tr("Reset all node's color"));
......@@ -73,6 +76,7 @@ void MainWindow::createMenus()
actionMenu->addAction(topkWithTotalAct);
actionMenu->addAction(topKWithTargetAct);
actionMenu->addAction(findShortestPathAct);
actionMenu->addAction(topkWithPagerankAct);
actionMenu->addAction(resetColorAct);
......@@ -109,6 +113,10 @@ void MainWindow::find_shortest_path()
graphWidget->find_shortest_path();
}
void MainWindow::topk_with_pagerank() {
graphWidget->topk_with_pagerank();
}
void MainWindow::reset_color()
{
graphWidget->reset_color();
......
......@@ -25,6 +25,7 @@ private:
QAction *topkWithTotalAct;
QAction *topKWithTargetAct;
QAction *resetColorAct;
QAction *topkWithPagerankAct;
QAction *findShortestPathAct;
//test
......@@ -41,6 +42,7 @@ private slots:
void topK_with_total();
void topK_with_target();
void find_shortest_path();
void topk_with_pagerank();
void reset_color();
//test
void test();
......
......@@ -92,6 +92,9 @@
<ClCompile Include="json_processor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ChartDialog.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="PaperGraphWidget.h">
......@@ -129,5 +132,8 @@
<ClInclude Include="json_processor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ChartDialog.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
......
......@@ -75,6 +75,11 @@ void PaperGraphWidget::find_shortest_path()
scene->update();
}
void PaperGraphWidget::topk_with_pagerank() {
graphItem->topk_with_pagerank();
scene->update();
}
void PaperGraphWidget::reset_color()
{
graphItem->reset_color();
......
......@@ -19,6 +19,7 @@ public:
void topk_with_total();
void topk_with_target();
void find_shortest_path();
void topk_with_pagerank();
void reset_color();
//test
......
......@@ -3,47 +3,6 @@
#include "MainWindow.h"
int main(int argc, char *argv[]) {
//if (1) {
// _curl_processor.set_url("http://dblp.uni-trier.de/rec/bib1/conf/sbrn/WedemannCD06");
// _curl_processor.perform();
// printf("%s", _curl_processor.get_buffer().c_str());
//
// _bibtex_processor.read(_curl_processor.get_buffer());
// std::string doi;
// _bibtex_processor.get_value("doi", doi);
// std::string address = std::string("http://api.crossref.org/works/")+doi;
// _curl_processor.set_url(address.c_str());
// _curl_processor.perform();
// printf("json: %s\n", _curl_processor.get_buffer().c_str());
// //rapidjson test
// rapidjson::Document d;
// d.Parse(_curl_processor.get_buffer().c_str());
// rapidjson::Value& value_status = d["status"];
// std::string status_str = value_status.GetString();
// printf("status: %s\n", status_str.c_str());
// if (status_str != "ok") {
// printf("status: %s\n", status_str.c_str());
// printf("not ok\n");
// return 1;
// }
// rapidjson::Value& value_message = d["message"];
// rapidjson::Value& citation_count = value_message["is-referenced-by-count"];
// int cit_cnt = citation_count.GetInt();
// printf("citation: %d\n", cit_cnt);
// //
// rapidjson::Value& citation_count2 = d["message"]["is-referenced-by-count"];
// printf("%d\n", citation_count2.GetInt());
// return 0;
//}
QApplication app(argc, argv);
MainWindow m;
......
......@@ -16,9 +16,12 @@
#include <qmath.h>
#include <QMessageBox>
#include <QtGui>
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtWidgets>
#include <QtCharts/QChartView>
#include <QtCharts/QBarSeries>
#include <QtCharts/QBarSet>
#include <QtCharts/QLegend>
#include <QtCharts/QBarCategoryAxis>
#include <boost/algorithm/string.hpp> //boost::split
#include <boost/bimap.hpp>
......@@ -62,6 +65,8 @@ using bibtex::BibTeXEntry;
using namespace boost;
using namespace std;
/* Qt namespaces */
/* function declaration */
size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp);
......@@ -69,15 +74,65 @@ size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp);
enum vertex_position_t { vertex_position };
enum vertex_type_t { vertex_type };
enum vertex_record_t { vertex_record };
enum vertex_citation_t { vertex_citation };
enum vertex_citation_t { vertex_citation }; //for paper
enum vertex_pagerank_t { vertex_pagerank };
enum vertex_category_t { vertex_category }; //for paper
enum vertex_title_t { vertex_title }; //for paper
enum vertex_year_t { vertex_year }; //for paper
enum vertex_category_accuracy_t { vertex_category_accuracy }; //for paper
namespace boost {
BOOST_INSTALL_PROPERTY(vertex, position);
BOOST_INSTALL_PROPERTY(vertex, type);
BOOST_INSTALL_PROPERTY(vertex, record);
BOOST_INSTALL_PROPERTY(vertex, citation);
BOOST_INSTALL_PROPERTY(vertex, pagerank);
BOOST_INSTALL_PROPERTY(vertex, category);
BOOST_INSTALL_PROPERTY(vertex, title);
BOOST_INSTALL_PROPERTY(vertex, year);
BOOST_INSTALL_PROPERTY(vertex, category_accuracy);
}
enum PAPER_CATEGORY {
CS_AI,
CS_CL,
CS_CC,
CS_CE,
CS_CG,
CS_GT,
CS_CV,
CS_CY,
CS_CR,
CS_DS,
CS_DB,
CS_DL,
CS_DM,
CS_DC,
CS_ET,
CS_FL,
CS_GL,
CS_GR,
CS_AR,
CS_HC,
CS_IR,
CS_IT,
CS_LG,
CS_LO,
CS_MS,
CS_MA,
CS_MM,
CS_NI,
CS_NE,
CS_NA,
CS_OS,
CS_OH,
CS_PF,
CS_PL,
CS_RO,
CS_SI,
CS_SE,
CS_SD,
CS_SC,
CS_SY
};
enum NODE_TYPE {
NODE_PAPER,
NODE_AUTHOR
......@@ -98,8 +153,12 @@ typedef boost::property<vertex_index_t, int,
boost::property<vertex_type_t, int, //타입. enum NODE_TYPE에 정의됨
boost::property<vertex_record_t, int, //이웃 노드 개수
boost::property<vertex_citation_t, int, //피인용수
boost::property<vertex_pagerank_t, double> //페이지랭크 값
>>>>>
boost::property<vertex_pagerank_t, double, //페이지랭크값 계산해서 저장할 property
boost::property<vertex_category_t, int, //논문 주제
boost::property<vertex_title_t, std::string, //논문 제목
boost::property<vertex_year_t, int,
boost::property<vertex_category_accuracy_t, double>
>>>>>>>>>
> VertexProperties;
typedef boost::adjacency_list<
listS, //outEdgeList
......@@ -126,8 +185,8 @@ namespace {
const int NODE_SIZE = 4;
const int LAYOUT_MODE = GRAPH_LAYOUT::RANDOM_LAYOUT;
//const int SCREEN_SIZE = 3000;
const int SCREEN_SIZE = 3000;
const int READ_LINE_UNIT = 10; //한 번에 몇 라인을 읽을지
const int SCREEN_SIZE = 500;
const int READ_LINE_UNIT = 100; //한 번에 몇 라인을 읽을지
/* curl processor */
curl_processor _curl_processor;
......