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