Showing
3 changed files
with
239 additions
and
33 deletions
... | @@ -30,6 +30,11 @@ public: | ... | @@ -30,6 +30,11 @@ public: |
30 | void setWidth(int w) { width = w; } | 30 | void setWidth(int w) { width = w; } |
31 | void setColor(QColor color) { this->color = color; } | 31 | void setColor(QColor color) { this->color = color; } |
32 | 32 | ||
33 | + //method | ||
34 | + bool match(QString qs1, QString qs2) { return (qs1==from&&qs2==to)||(qs2==from&&qs1==to); } | ||
35 | + bool match(string s1, string s2) { return this->match(QString(s1.c_str()),QString(s2.c_str())); } | ||
36 | + | ||
37 | + //overrides | ||
33 | QRectF boundingRect() const override; | 38 | QRectF boundingRect() const override; |
34 | QPainterPath shape() const override; | 39 | QPainterPath shape() const override; |
35 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; | 40 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; | ... | ... |
... | @@ -243,16 +243,41 @@ void GraphItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, | ... | @@ -243,16 +243,41 @@ void GraphItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, |
243 | void GraphItem::might_know() | 243 | void GraphItem::might_know() |
244 | { | 244 | { |
245 | // 알 수도 있는 연구원 찾기 | 245 | // 알 수도 있는 연구원 찾기 |
246 | - vertex_iterator vi, vi_end, vtarget; | 246 | + vertex_iterator vi, vi_end/*, vtarget*/; |
247 | - Graph::adjacency_iterator ai, ai_end; | 247 | + vertex_descriptor vtarget; |
248 | - vector<string> might_know_vec; | 248 | + /*Graph::adjacency_iterator ai, ai_end, |
249 | + ai2, ai2_end;*/ | ||
250 | + adjacencyIterator ai, ai_end, | ||
251 | + ai2, ai2_end; | ||
252 | + vector<string> coauthor_name_vec, might_know_name_vec, | ||
253 | + visited; | ||
254 | + vector<string> paper_name_vec, coauthor_paper_name_vec; | ||
255 | + vector<vertex_descriptor> paper_vec, coauthor_paper_vec, | ||
256 | + might_know_paper_vec; | ||
249 | 257 | ||
258 | + auto node_idx_map = boost::get(vertex_index, *graph); | ||
250 | auto node_label_map = get(vertex_name, *graph); | 259 | auto node_label_map = get(vertex_name, *graph); |
251 | auto node_type_map = get(vertex_type, *graph); | 260 | auto node_type_map = get(vertex_type, *graph); |
261 | + | ||
262 | + //vertex_descriptor vvv = boost::vertex(node_idx_map[*vi], *graph); | ||
263 | + //vertex_descriptor vvv = boost::vertex(node_idx_map[*ai], *graph); | ||
264 | + | ||
265 | + //사람 지정 | ||
266 | + bool isok = false; | ||
267 | + string target_name; | ||
268 | + QInputDialog *inputDialog = new QInputDialog(); | ||
269 | + target_name = inputDialog->getText(nullptr, "Enter target's name", "Target node's name:", | ||
270 | + QLineEdit::Normal, "Akira Idoue", &isok).toStdString(); | ||
271 | + if (!isok) { | ||
272 | + qDebug("input cancelled"); | ||
273 | + return; | ||
274 | + } | ||
275 | + qDebug() << target_name.c_str(); | ||
276 | + | ||
252 | 277 | ||
253 | // 회색 색칠 | 278 | // 회색 색칠 |
254 | for (auto& n : nodeList) { | 279 | for (auto& n : nodeList) { |
255 | - if (n->getLabel().toStdString() != TARGET_AUTHOR_NAME) { | 280 | + if (n->getLabel().toStdString() != target_name) { |
256 | n->setColor(QColor(Qt::lightGray)); | 281 | n->setColor(QColor(Qt::lightGray)); |
257 | } else { | 282 | } else { |
258 | n->setColor(QColor(Qt::blue)); | 283 | n->setColor(QColor(Qt::blue)); |
... | @@ -261,44 +286,161 @@ void GraphItem::might_know() | ... | @@ -261,44 +286,161 @@ void GraphItem::might_know() |
261 | 286 | ||
262 | // find target node | 287 | // find target node |
263 | for (boost::tie(vi, vi_end) = boost::vertices(*graph); vi!=vi_end; ++vi) { | 288 | for (boost::tie(vi, vi_end) = boost::vertices(*graph); vi!=vi_end; ++vi) { |
264 | - if (node_label_map[*vi] == std::string(TARGET_AUTHOR_NAME)) { | 289 | + if (node_label_map[*vi] == target_name) { |
265 | - vtarget = vi; | 290 | + vtarget = vertex(node_idx_map[*vi], *graph); |
266 | break; | 291 | break; |
267 | } | 292 | } |
268 | } | 293 | } |
269 | 294 | ||
270 | - // bfs | 295 | + visited.push_back(target_name); |
271 | - //std::queue<vertex_iterator> q; | 296 | + |
272 | - //q.push(vtarget); | 297 | + //push target's papers |
273 | - //while (!q.empty()) { | 298 | + for (boost::tie(ai, ai_end) = boost::adjacent_vertices(vtarget, *graph); |
274 | - // /*auto next_vi = q.front(); | 299 | + ai != ai_end; |
275 | - // q.pop(); | 300 | + ++ai) { |
301 | + //ai: 타겟 노드의 이웃 노드(paper) | ||
302 | + const string& node_label = node_label_map[*ai]; | ||
303 | + //qDebug() << "ai: " << node_label.c_str(); | ||
304 | + | ||
305 | + paper_vec.push_back(vertex(node_idx_map[*ai], *graph)); | ||
306 | + paper_name_vec.push_back(node_label); | ||
307 | + | ||
308 | + visited.push_back(node_label); | ||
309 | + } | ||
276 | 310 | ||
277 | - // if (nodeType[*next_vi] == NODE_TYPE::NODE_PAPER) | 311 | + // find coauthor |
278 | - // continue; | 312 | + for (auto paper: paper_vec) { |
313 | + //paper: 타겟 저자의 논문 | ||
314 | + for (boost::tie(ai, ai_end)=boost::adjacent_vertices(paper, *graph); | ||
315 | + ai!=ai_end; | ||
316 | + ++ai) { | ||
317 | + //ai: paper의 이웃. = 저자들 | ||
318 | + // == coauthors | ||
319 | + const string& node_label = node_label_map[*ai]; | ||
320 | + //if (node_label == target_name) { | ||
321 | + // // 중복체크 | ||
322 | + // continue; | ||
323 | + //} | ||
324 | + if (find(visited.begin(), visited.end(), node_label) != visited.end()) { | ||
325 | + continue; | ||
326 | + } | ||
327 | + //qDebug() << "_ai: "<< node_label.c_str(); | ||
279 | 328 | ||
280 | - // for (boost::tie(ai, ai_end) = boost::adjacent_vertices(*next_vi, *graph); | 329 | + coauthor_name_vec.push_back(node_label_map[*ai]); |
281 | - // ai != ai_end; ++ai) { | 330 | + coauthor_paper_vec.push_back(vertex(node_idx_map[*ai], *graph)); |
282 | - // if (nodeType[*ai] == NODE_TYPE::NODE_PAPER) | 331 | + visited.push_back(node_label); |
283 | - // continue; | 332 | + } |
284 | - // else | 333 | + } |
285 | - // q.push(ai); | ||
286 | - // }*/ | ||
287 | - //} | ||
288 | 334 | ||
289 | - for (boost::tie(ai, ai_end) = boost::adjacent_vertices(*vtarget, *graph); | 335 | + //push coauthors' papers |
290 | - ai != ai_end; | 336 | + for (auto coauthor_paper: coauthor_paper_vec) { |
291 | - ++ai) { | 337 | + //coauthor_paper: coauthor의 논문 |
292 | - might_know_vec.push_back(node_label_map[*ai]); | 338 | + for (boost::tie(ai, ai_end) = boost::adjacent_vertices(coauthor_paper, *graph); |
339 | + ai != ai_end; | ||
340 | + ++ai) { | ||
341 | + //ai: coauthor_paper의 저자들 = might know | ||
342 | + //if () { | ||
343 | + // continue; | ||
344 | + //} | ||
345 | + | ||
346 | + const string& node_label = node_label_map[*ai]; | ||
347 | + if (find(visited.begin(), visited.end(), node_label) != visited.end()) { | ||
348 | + continue; | ||
349 | + } | ||
350 | + //qDebug() << "_ai2: " << node_label.c_str(); | ||
351 | + | ||
352 | + might_know_paper_vec.push_back(vertex(node_idx_map[*ai], *graph)); | ||
353 | + coauthor_paper_name_vec.push_back(node_label); | ||
354 | + visited.push_back(node_label); | ||
355 | + } | ||
356 | + } | ||
357 | + | ||
358 | + // find "might know" author | ||
359 | + for (auto paper: might_know_paper_vec) { | ||
360 | + for (boost::tie(ai, ai_end)=boost::adjacent_vertices(paper, *graph); | ||
361 | + ai!=ai_end; | ||
362 | + ++ai) { | ||
363 | + const string& node_label = node_label_map[*ai]; | ||
364 | + if (find(visited.begin(), visited.end(), node_label) != visited.end()) { | ||
365 | + continue; | ||
366 | + } | ||
367 | + //qDebug() << "_ai3: " << node_label.c_str(); | ||
368 | + | ||
369 | + might_know_name_vec.push_back(node_label); | ||
370 | + visited.push_back(node_label); | ||
371 | + } | ||
293 | } | 372 | } |
294 | 373 | ||
374 | + | ||
295 | // highlight | 375 | // highlight |
376 | + //1. might know | ||
377 | + //2. coauthor | ||
296 | for (auto& n: nodeList) { | 378 | for (auto& n: nodeList) { |
297 | - if (std::find(might_know_vec.begin(), might_know_vec.end(), n->getLabel().toStdString()) | 379 | + if (n->getLabel().toStdString() == target_name) { |
298 | - != might_know_vec.end()) { | ||
299 | - //found | ||
300 | n->setColor(Qt::red); | 380 | n->setColor(Qt::red); |
301 | } | 381 | } |
382 | + else if (std::find(paper_name_vec.begin(), paper_name_vec.end(), n->getLabel().toStdString()) | ||
383 | + != paper_name_vec.end()) { | ||
384 | + n->setColor("#ff8c00"); | ||
385 | + } | ||
386 | + else if (std::find(coauthor_name_vec.begin(), coauthor_name_vec.end(), n->getLabel().toStdString()) | ||
387 | + != coauthor_name_vec.end()) { | ||
388 | + //coauthor | ||
389 | + n->setColor(Qt::yellow); | ||
390 | + } | ||
391 | + else if (std::find(coauthor_paper_name_vec.begin(), coauthor_paper_name_vec.end(), n->getLabel().toStdString()) | ||
392 | + != coauthor_paper_name_vec.end()) { | ||
393 | + n->setColor(Qt::green); | ||
394 | + } | ||
395 | + else if (std::find(might_know_name_vec.begin(), might_know_name_vec.end(), n->getLabel().toStdString()) | ||
396 | + != might_know_name_vec.end()) { | ||
397 | + //might know | ||
398 | + n->setColor(Qt::blue); | ||
399 | + } | ||
400 | + } | ||
401 | + //highlight nodes | ||
402 | + //1. target - paper | ||
403 | + //2. paper - coauthor | ||
404 | + //3. coauthor - coauthor's paper | ||
405 | + //4. coauthor's paper - might know | ||
406 | + for (auto& to: paper_name_vec) { | ||
407 | + //1. | ||
408 | + for (auto& e: edgeList) { | ||
409 | + if (e->match(to, target_name)) { | ||
410 | + e->setColor(Qt::red); | ||
411 | + e->setWidth(3); | ||
412 | + } | ||
413 | + } | ||
414 | + } | ||
415 | + for (auto& from: paper_name_vec) { | ||
416 | + for (auto& to: coauthor_name_vec) { | ||
417 | + for (auto& e : edgeList) { | ||
418 | + if (e->match(from, to)) { | ||
419 | + e->setColor("#ff8c00"); | ||
420 | + e->setWidth(3); | ||
421 | + } | ||
422 | + } | ||
423 | + } | ||
424 | + } | ||
425 | + for (auto& from : coauthor_name_vec) { | ||
426 | + for (auto& to : coauthor_paper_name_vec) { | ||
427 | + for (auto& e : edgeList) { | ||
428 | + if (e->match(from, to)) { | ||
429 | + e->setColor(Qt::yellow); | ||
430 | + e->setWidth(3); | ||
431 | + } | ||
432 | + } | ||
433 | + } | ||
434 | + } | ||
435 | + for (auto& from : coauthor_paper_name_vec) { | ||
436 | + for (auto& to : might_know_name_vec) { | ||
437 | + for (auto& e : edgeList) { | ||
438 | + if (e->match(from, to)) { | ||
439 | + e->setColor(Qt::green); | ||
440 | + e->setWidth(3); | ||
441 | + } | ||
442 | + } | ||
443 | + } | ||
302 | } | 444 | } |
303 | } | 445 | } |
304 | 446 | ||
... | @@ -311,6 +453,10 @@ void GraphItem::reset_color() | ... | @@ -311,6 +453,10 @@ void GraphItem::reset_color() |
311 | n->setColor(QColor(Qt::green)); | 453 | n->setColor(QColor(Qt::green)); |
312 | } | 454 | } |
313 | } | 455 | } |
456 | + for (auto& e: edgeList) { | ||
457 | + e->setColor(Qt::black); | ||
458 | + e->setWidth(0); | ||
459 | + } | ||
314 | } | 460 | } |
315 | 461 | ||
316 | void GraphItem::topK_highlight_with_total() | 462 | void GraphItem::topK_highlight_with_total() |
... | @@ -334,6 +480,7 @@ void GraphItem::topK_highlight_with_total() | ... | @@ -334,6 +480,7 @@ void GraphItem::topK_highlight_with_total() |
334 | //} | 480 | //} |
335 | 481 | ||
336 | // <record, label> | 482 | // <record, label> |
483 | + //저자별 논문 수 계산 | ||
337 | TopKHeap<pair<int, string>> heap(TOP_K); | 484 | TopKHeap<pair<int, string>> heap(TOP_K); |
338 | for (boost::tie(vi, vi_end) = boost::vertices(*graph); vi != vi_end; ++vi) { | 485 | for (boost::tie(vi, vi_end) = boost::vertices(*graph); vi != vi_end; ++vi) { |
339 | if (node_type_map[*vi] != NODE_TYPE::NODE_AUTHOR) { | 486 | if (node_type_map[*vi] != NODE_TYPE::NODE_AUTHOR) { |
... | @@ -489,8 +636,7 @@ void GraphItem::find_shortest_path() | ... | @@ -489,8 +636,7 @@ void GraphItem::find_shortest_path() |
489 | size_t paths_sz = paths.size(); | 636 | size_t paths_sz = paths.size(); |
490 | for (int i = 0; i < paths_sz - 1; ++i) { | 637 | for (int i = 0; i < paths_sz - 1; ++i) { |
491 | for (auto& e : edgeList) { | 638 | for (auto& e : edgeList) { |
492 | - if ((e->getFrom().toStdString() == paths[i] && e->getTo().toStdString() == paths[i + 1]) | 639 | + if (e->match(paths[i], paths[i+1])) { |
493 | - || (e->getFrom().toStdString() == paths[i + 1] && e->getTo().toStdString() == paths[i])) { | ||
494 | e->setColor(QColor(Qt::blue)); | 640 | e->setColor(QColor(Qt::blue)); |
495 | e->setWidth(3); | 641 | e->setWidth(3); |
496 | } | 642 | } |
... | @@ -503,8 +649,63 @@ void GraphItem::test() | ... | @@ -503,8 +649,63 @@ void GraphItem::test() |
503 | { | 649 | { |
504 | qDebug("* test action start"); | 650 | qDebug("* test action start"); |
505 | 651 | ||
652 | + //지정한 사람 주변 topk coloring | ||
653 | + | ||
654 | + | ||
506 | 655 | ||
507 | 656 | ||
657 | + //vertex_iterator vi, vi_end; | ||
658 | + //Graph::adjacency_iterator ai, ai_end; | ||
659 | + | ||
660 | + | ||
661 | + | ||
662 | + // | ||
663 | + // <record, label> | ||
664 | + //TopKHeap<pair<int, string>> heap(TOP_K); | ||
665 | + //for (boost::tie(vi, vi_end) = boost::vertices(*graph); vi != vi_end; ++vi) { | ||
666 | + // if (node_type_map[*vi] != NODE_TYPE::NODE_AUTHOR) { | ||
667 | + // continue; | ||
668 | + // } | ||
669 | + | ||
670 | + // int record_cnt = 0; | ||
671 | + // for (boost::tie(ai, ai_end) = boost::adjacent_vertices(*vi, *graph); | ||
672 | + // ai != ai_end; ++ai) { | ||
673 | + // if (node_type_map[*ai] == NODE_TYPE::NODE_PAPER) { | ||
674 | + // ++record_cnt; | ||
675 | + // } | ||
676 | + // } | ||
677 | + | ||
678 | + // boost::put(vertex_record, *graph, *vi, record_cnt); | ||
679 | + // heap.push(make_pair(record_cnt, node_label_map[*vi])); | ||
680 | + | ||
681 | + // //qDebug() << record_cnt; | ||
682 | + //} | ||
683 | + | ||
684 | + ////get top K records | ||
685 | + //pair<int, string> topk_arr[TOP_K]; | ||
686 | + //for (int i = 0; i < TOP_K; ++i) { | ||
687 | + // topk_arr[i] = heap.pop(); | ||
688 | + // qDebug() << "topk[" << i << "] = " << topk_arr[i].first << ", " << QString::fromStdString(topk_arr[i].second); | ||
689 | + //} | ||
690 | + | ||
691 | + | ||
692 | + //for (auto& n : nodeList) { | ||
693 | + // auto label = n->getLabel(); | ||
694 | + // n->setColor(QColor(Qt::lightGray)); | ||
695 | + // for (auto& p : topk_arr) { | ||
696 | + // if (label.toStdString() == p.second) { | ||
697 | + // n->setColor(QColor(Qt::red)); | ||
698 | + // break; | ||
699 | + // } | ||
700 | + // } | ||
701 | + //} | ||
702 | + | ||
703 | + | ||
704 | + //전체노드 색 변경 | ||
705 | + for (auto& n: nodeList) { | ||
706 | + n->setColor(Qt::lightGray); | ||
707 | + } | ||
708 | + | ||
508 | qDebug("* test action end"); | 709 | qDebug("* test action end"); |
509 | } | 710 | } |
510 | 711 | ... | ... |
... | @@ -88,7 +88,7 @@ typedef boost::adjacency_list< | ... | @@ -88,7 +88,7 @@ typedef boost::adjacency_list< |
88 | > Graph; | 88 | > Graph; |
89 | typedef typename graph_traits<Graph>::edge_iterator edge_iterator; | 89 | typedef typename graph_traits<Graph>::edge_iterator edge_iterator; |
90 | typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator; | 90 | typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator; |
91 | -//typedef boost::graph_traits<Graph>::adjacency_iterator adjacency_iterator; | 91 | +typedef boost::graph_traits<Graph>::adjacency_iterator adjacencyIterator; |
92 | typedef boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor; | 92 | typedef boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor; |
93 | typedef square_topology<> Topology; | 93 | typedef square_topology<> Topology; |
94 | typedef typename Topology::point_type Point; | 94 | typedef typename Topology::point_type Point; |
... | @@ -110,7 +110,7 @@ namespace { | ... | @@ -110,7 +110,7 @@ namespace { |
110 | const int TOP_K = 5; //상위 몇 개 아이템에 대해 highlight 할 지 | 110 | const int TOP_K = 5; //상위 몇 개 아이템에 대해 highlight 할 지 |
111 | 111 | ||
112 | /* a research you might know */ | 112 | /* a research you might know */ |
113 | - const char* TARGET_AUTHOR_NAME = "Shuichi Itoh"; | 113 | + //const char* TARGET_AUTHOR_NAME = "Shuichi Itoh"; |
114 | } | 114 | } |
115 | 115 | ||
116 | /* boost */ | 116 | /* boost */ | ... | ... |
-
Please register or login to post a comment