ratio_cut_partition.h

00001 //==========================================================================
00002 //
00003 //      ratio_cut_partition.h
00004 //
00005 //==========================================================================
00006 // $Id: ratio_cut_partition.h,v 1.8 2003/01/31 08:15:04 chris Exp $
00007 
00008 #ifndef GTL_RATIO_CUT_PARTITION_H
00009 #define GTL_RATIO_CUT_PARTITION_H
00010 
00011 #include <GTL/GTL.h>
00012 #include <GTL/graph.h>
00013 #include <GTL/node_map.h>
00014 #include <GTL/edge_map.h>
00015 #include <GTL/algorithm.h>
00016 
00017 __GTL_BEGIN_NAMESPACE
00018 
00019 
00031 class GTL_EXTERN ratio_cut_partition : public algorithm
00032 {
00033 public:
00040     typedef int side_type;
00041 
00047     const static side_type A;
00048 
00054     const static side_type B;
00055 
00064     typedef short int fix_type;
00065 
00071     const static fix_type FIXA;
00072 
00078     const static fix_type FIXB;
00079 
00085     const static fix_type UNFIXED;
00086 
00092     ratio_cut_partition();
00093 
00099     virtual ~ratio_cut_partition();
00100 
00112     void set_vars(const graph& G, const node_map<int>& node_weight,
00113         const edge_map<int>& edge_weight);
00114 
00128     void set_vars(const graph& G, const node_map<int>& node_weight,
00129         const edge_map<int>& edge_weight, const node source_node,
00130         const node target_node);
00131 
00150     void set_vars(const graph& G, const node_map<int>& node_weight,
00151         const edge_map<int>& edge_weight, const node source_node,
00152         const node target_node, const node_map<side_type>& init_side);
00153                         
00172     void set_vars(const graph& G, const node_map<int>& node_weight,
00173         const edge_map<int>& edge_weight, const node source_node,
00174         const node target_node, const node_map<fix_type>& fixed);
00175 
00199     void set_vars(const graph& G, const node_map<int>& node_weight,
00200         const edge_map<int>& edge_weight, const node source_node,
00201         const node target_node, const node_map<side_type>& init_side,
00202         const node_map<fix_type>& fixed);
00203 
00213     void store_cut_edges(const bool set);
00214 
00226     void store_nodesAB(const bool set);
00227 
00252     virtual int check(graph& G);
00253 
00264     int run(graph& G);
00265 
00271     int get_cutsize();
00272                 
00279     double get_cutratio();
00280                 
00289     side_type get_side_of_node(const node& n) const;
00290 
00300     side_type operator [](const node& n) const;
00301                                 
00309     int get_weight_on_sideA(const graph& G) const;
00310 
00318     int get_weight_on_sideB(const graph& G) const;
00319 
00323     typedef list<edge>::const_iterator cut_edges_iterator;
00324 
00333     cut_edges_iterator cut_edges_begin() const;
00334 
00343     cut_edges_iterator cut_edges_end() const;
00344                 
00348     typedef list<node>::const_iterator nodes_of_one_side_iterator;
00349 
00357     nodes_of_one_side_iterator nodes_of_sideA_begin() const;
00358 
00367     nodes_of_one_side_iterator nodes_of_sideA_end() const;
00368 
00376     nodes_of_one_side_iterator nodes_of_sideB_begin() const;
00377 
00386     nodes_of_one_side_iterator nodes_of_sideB_end() const;
00387 
00394     virtual void reset();
00395 protected:
00399     enum direction_type {LEFT_SHIFT = 2, RIGHT_SHIFT = 3};
00400 
00406     bool enable_cut_edges_storing;
00407                 
00412     list<edge> cut_edges;
00413 
00419     bool enable_nodesAB_storing;
00420                 
00425     list<node> nodesA;
00426 
00431     list<node> nodesB;
00432 
00437     node source_node;
00438 
00443     node target_node;
00444 
00451     bool set_vars_executed;
00452 
00458     bool provided_st;
00459 
00466     bool provided_initial_part;
00467 
00473     bool provided_fix;
00474                 
00479     node_map<fix_type> fixed;
00480 
00486     direction_type direction;
00487 
00493     node_map<int> node_weight;
00494 
00500     edge_map<int> edge_weight;
00501 
00507     int max_edge_weight;
00508 
00514     int node_weight_on_sideA;
00515 
00521     int node_weight_on_sideB;
00522                 
00527     int nodes_on_sideA;
00528                 
00533     int nodes_on_sideB;
00534                 
00539     node_map<side_type> side;
00540                 
00545     node_map<list<node>::iterator> position_in_bucket;
00546                 
00551     int max_vertex_degree;
00552 
00557     edge_map<int> aside;
00558 
00563     edge_map<int> bside;
00564 
00570     edge_map<list<node> > unlockedA;
00571 
00577     edge_map<list<node> > unlockedB;
00578 
00583     node_map<int> gain_value;
00584 
00589     bool bucketA_empty;
00590 
00595     bool bucketB_empty;
00596 
00602     int max_gainA;
00603 
00609     int max_gainB;
00610                 
00617     vector<list<node> > bucketA;
00618 
00625     vector<list<node> > bucketB;
00626 
00632     int cur_cutsize;
00633 
00638     double cur_cutratio;
00639 
00645     void divide_up(const graph& G);
00646 
00653     void make_connected(graph& G, list<edge>& artificial_edges);
00654                 
00660     void restore(graph& G, list<edge>& artificial_edges);
00661                 
00666     void initialization(const graph& G);
00667 
00672     void init_data_structure(const graph& G);
00673 
00679     void init_filling_buckets(const graph& G);
00680 
00686     int inital_gain_of_node_on_sideA(const node cur_node);
00687 
00693     int inital_gain_of_node_on_sideB(const node cur_node);
00694 
00699     void init_variables(const graph& G);
00700                 
00705     void compute_max_vertex_degree(const graph& G);
00706 
00711     void determine_source_node(const graph& G);
00712 
00717     void compute_target_node(const graph& G);
00718 
00724     void right_shift_op(const graph& G);
00725 
00731     void left_shift_op(const graph& G);
00732 
00740     bool move_vertex_A2B(const graph& G, node& moved_node);
00741 
00748     bool move_vertex_B2A(const graph& G, node& moved_node);
00749 
00754     node compute_highest_ratio_node(list<node> node_list);
00755 
00763     double cutratio();
00764                                 
00771     double ratio_of_node_A2B(const node cur_node);
00772 
00779     double ratio_of_node_B2A(const node cur_node);
00780                 
00786     inline int range_up(const int gain_value) const;
00787 
00793     inline int range_down(const int index) const;
00794 
00800     void update_data_structure_A2B(const node cur_node,
00801         const bool init_mode);
00802                 
00808     void update_data_structure_B2A(const node cur_node,
00809         const bool init_mode);
00810                 
00816     void update_bucketA(const node cur_node, const int old_gain,
00817         const int new_gain, const bool init_mode);
00818 
00824     void update_bucketB(const node cur_node, const int old_gain,
00825         const int new_gain, const bool init_mode);
00826                 
00832     void update_max_gain(const side_type side);
00833 
00838     void clean_step(const graph& G);
00839 
00844     void copy_side_node_map(const graph& G, node_map<side_type>& dest,
00845         const node_map<side_type> source) const;
00846                         
00851     void iterative_shifting(const graph& G);
00852 
00857     void group_swapping(const graph& G);
00858 
00865     bool move_manager(const graph& G);
00866 
00873     bool move_vertex(const graph& G, node& moved_node);
00874 
00879     void compute_cut_edges(const graph& G);
00880 
00885     void compute_nodesAB(const graph& G);
00886 private:
00887 #ifdef _DEBUG
00888 
00892     void print_bucketA();
00893 
00898     void print_bucketB();
00899 #endif  // _DEBUG
00900 };
00901 
00902 __GTL_END_NAMESPACE
00903 
00904 #endif // GTL_RATIO_CUT_PARTITION_H
00905 
00906 //--------------------------------------------------------------------------
00907 //   end of file
00908 //--------------------------------------------------------------------------