445 bool operator==(const Edge i) const {return id==i.id;} |
445 bool operator==(const Edge i) const {return id==i.id;} |
446 bool operator!=(const Edge i) const {return id!=i.id;} |
446 bool operator!=(const Edge i) const {return id!=i.id;} |
447 bool operator<(const Edge i) const {return id<i.id;} |
447 bool operator<(const Edge i) const {return id<i.id;} |
448 }; |
448 }; |
449 |
449 |
450 void construct(int upperNodeNum, int lowerNodeNum) { |
450 void construct(int aNodeNum, int bNodeNum) { |
451 _upperNodeNum = upperNodeNum; |
451 _aNodeNum = aNodeNum; |
452 _lowerNodeNum = lowerNodeNum; |
452 _bNodeNum = bNodeNum; |
453 _edgeNum = upperNodeNum * lowerNodeNum; |
453 _edgeNum = aNodeNum * bNodeNum; |
454 } |
454 } |
455 |
455 |
456 void firstUpper(Node& node) const { |
456 void firstANode(Node& node) const { |
457 node.id = 2 * _upperNodeNum - 2; |
457 node.id = 2 * _aNodeNum - 2; |
458 if (node.id < 0) node.id = -1; |
458 if (node.id < 0) node.id = -1; |
459 } |
459 } |
460 void nextUpper(Node& node) const { |
460 void nextANode(Node& node) const { |
461 node.id -= 2; |
461 node.id -= 2; |
462 if (node.id < 0) node.id = -1; |
462 if (node.id < 0) node.id = -1; |
463 } |
463 } |
464 |
464 |
465 void firstLower(Node& node) const { |
465 void firstBNode(Node& node) const { |
466 node.id = 2 * _lowerNodeNum - 1; |
466 node.id = 2 * _bNodeNum - 1; |
467 } |
467 } |
468 void nextLower(Node& node) const { |
468 void nextBNode(Node& node) const { |
469 node.id -= 2; |
469 node.id -= 2; |
470 } |
470 } |
471 |
471 |
472 void first(Node& node) const { |
472 void first(Node& node) const { |
473 if (_upperNodeNum > 0) { |
473 if (_aNodeNum > 0) { |
474 node.id = 2 * _upperNodeNum - 2; |
474 node.id = 2 * _aNodeNum - 2; |
475 } else { |
475 } else { |
476 node.id = 2 * _lowerNodeNum - 1; |
476 node.id = 2 * _bNodeNum - 1; |
477 } |
477 } |
478 } |
478 } |
479 void next(Node& node) const { |
479 void next(Node& node) const { |
480 node.id -= 2; |
480 node.id -= 2; |
481 if (node.id == -2) { |
481 if (node.id == -2) { |
482 node.id = 2 * _lowerNodeNum - 1; |
482 node.id = 2 * _bNodeNum - 1; |
483 } |
483 } |
484 } |
484 } |
485 |
485 |
486 void first(Edge& edge) const { |
486 void first(Edge& edge) const { |
487 edge.id = _edgeNum - 1; |
487 edge.id = _edgeNum - 1; |
488 } |
488 } |
489 void next(Edge& edge) const { |
489 void next(Edge& edge) const { |
490 --edge.id; |
490 --edge.id; |
491 } |
491 } |
492 |
492 |
493 void firstDown(Edge& edge, const Node& node) const { |
493 void firstOut(Edge& edge, const Node& node) const { |
494 LEMON_ASSERT((node.id & 1) == 0, NodeSetError()); |
494 LEMON_ASSERT((node.id & 1) == 0, NodeSetError()); |
495 edge.id = (node.id >> 1) * _lowerNodeNum; |
495 edge.id = (node.id >> 1) * _bNodeNum; |
496 } |
496 } |
497 void nextDown(Edge& edge) const { |
497 void nextOut(Edge& edge) const { |
498 ++(edge.id); |
498 ++(edge.id); |
499 if (edge.id % _lowerNodeNum == 0) edge.id = -1; |
499 if (edge.id % _bNodeNum == 0) edge.id = -1; |
500 } |
500 } |
501 |
501 |
502 void firstUp(Edge& edge, const Node& node) const { |
502 void firstIn(Edge& edge, const Node& node) const { |
503 LEMON_ASSERT((node.id & 1) == 1, NodeSetError()); |
503 LEMON_ASSERT((node.id & 1) == 1, NodeSetError()); |
504 edge.id = (node.id >> 1); |
504 edge.id = (node.id >> 1); |
505 } |
505 } |
506 void nextUp(Edge& edge) const { |
506 void nextIn(Edge& edge) const { |
507 edge.id += _lowerNodeNum; |
507 edge.id += _bNodeNum; |
508 if (edge.id >= _edgeNum) edge.id = -1; |
508 if (edge.id >= _edgeNum) edge.id = -1; |
509 } |
509 } |
510 |
510 |
511 static int id(const Node& node) { |
511 static int id(const Node& node) { |
512 return node.id; |
512 return node.id; |
513 } |
513 } |
514 static Node nodeFromId(int id) { |
514 static Node nodeFromId(int id) { |
515 return Node(id); |
515 return Node(id); |
516 } |
516 } |
517 int maxNodeId() const { |
517 int maxNodeId() const { |
518 return _upperNodeNum > _lowerNodeNum ? |
518 return _aNodeNum > _bNodeNum ? |
519 _upperNodeNum * 2 - 2 : _lowerNodeNum * 2 - 1; |
519 _aNodeNum * 2 - 2 : _bNodeNum * 2 - 1; |
520 } |
520 } |
521 |
521 |
522 static int id(const Edge& edge) { |
522 static int id(const Edge& edge) { |
523 return edge.id; |
523 return edge.id; |
524 } |
524 } |
527 } |
527 } |
528 int maxEdgeId() const { |
528 int maxEdgeId() const { |
529 return _edgeNum - 1; |
529 return _edgeNum - 1; |
530 } |
530 } |
531 |
531 |
532 static int upperId(const Node& node) { |
532 static int aNodeId(const Node& node) { |
533 return node.id >> 1; |
533 return node.id >> 1; |
534 } |
534 } |
535 static Node fromUpperId(int id, Node) { |
535 static Node fromANodeId(int id, Node) { |
536 return Node(id << 1); |
536 return Node(id << 1); |
537 } |
537 } |
538 int maxUpperId() const { |
538 int maxANodeId() const { |
539 return _upperNodeNum; |
539 return _aNodeNum; |
540 } |
540 } |
541 |
541 |
542 static int lowerId(const Node& node) { |
542 static int bNodeId(const Node& node) { |
543 return node.id >> 1; |
543 return node.id >> 1; |
544 } |
544 } |
545 static Node fromLowerId(int id) { |
545 static Node fromBNodeId(int id) { |
546 return Node((id << 1) + 1); |
546 return Node((id << 1) + 1); |
547 } |
547 } |
548 int maxLowerId() const { |
548 int maxBNodeId() const { |
549 return _lowerNodeNum; |
549 return _bNodeNum; |
550 } |
550 } |
551 |
551 |
552 Node upperNode(const Edge& edge) const { |
552 Node aNode(const Edge& edge) const { |
553 return Node((edge.id / _lowerNodeNum) << 1); |
553 return Node((edge.id / _bNodeNum) << 1); |
554 } |
554 } |
555 Node lowerNode(const Edge& edge) const { |
555 Node bNode(const Edge& edge) const { |
556 return Node(((edge.id % _lowerNodeNum) << 1) + 1); |
556 return Node(((edge.id % _bNodeNum) << 1) + 1); |
557 } |
557 } |
558 |
558 |
559 static bool upper(const Node& node) { |
559 static bool aNode(const Node& node) { |
560 return (node.id & 1) == 0; |
560 return (node.id & 1) == 0; |
561 } |
561 } |
562 |
562 |
563 static bool lower(const Node& node) { |
563 static bool bNode(const Node& node) { |
564 return (node.id & 1) == 1; |
564 return (node.id & 1) == 1; |
565 } |
565 } |
566 |
566 |
567 static Node upperNode(int index) { |
567 static Node aNode(int index) { |
568 return Node(index << 1); |
568 return Node(index << 1); |
569 } |
569 } |
570 |
570 |
571 static Node lowerNode(int index) { |
571 static Node bNode(int index) { |
572 return Node((index << 1) + 1); |
572 return Node((index << 1) + 1); |
573 } |
573 } |
574 |
574 |
575 }; |
575 }; |
576 |
576 |
577 |
577 |
578 typedef StaticMappableUBipartiteGraphExtender< |
578 typedef StaticMappableBpUGraphExtender< |
579 IterableUBipartiteGraphExtender< |
579 IterableBpUGraphExtender< |
580 AlterableUBipartiteGraphExtender< |
580 AlterableBpUGraphExtender< |
581 UBipartiteGraphExtender < |
581 BpUGraphExtender < |
582 FullUBipartiteGraphBase> > > > |
582 FullBpUGraphBase> > > > |
583 ExtendedFullUBipartiteGraphBase; |
583 ExtendedFullBpUGraphBase; |
584 |
584 |
585 |
585 |
586 class FullUBipartiteGraph : |
586 /// \ingroup graphs |
587 public ExtendedFullUBipartiteGraphBase { |
587 /// |
588 public: |
588 /// \brief An undirected full bipartite graph class. |
589 typedef ExtendedFullUBipartiteGraphBase Parent; |
589 /// |
590 FullUBipartiteGraph(int upperNodeNum, int lowerNodeNum) { |
590 /// This is a simple and fast bipartite undirected full graph implementation. |
591 Parent::construct(upperNodeNum, lowerNodeNum); |
591 /// It is completely static, so you can neither add nor delete either |
|
592 /// edges or nodes. |
|
593 /// |
|
594 /// \sa FullGraph |
|
595 /// |
|
596 /// \author Balazs Dezso |
|
597 class FullBpUGraph : |
|
598 public ExtendedFullBpUGraphBase { |
|
599 public: |
|
600 typedef ExtendedFullBpUGraphBase Parent; |
|
601 FullBpUGraph(int aNodeNum, int bNodeNum) { |
|
602 Parent::construct(aNodeNum, bNodeNum); |
592 } |
603 } |
593 }; |
604 }; |
594 |
605 |
595 } //namespace lemon |
606 } //namespace lemon |
596 |
607 |