text: /******************************************************************************
   * stop_rules.h 
   *
   * Source of KaHIP -- Karlsruhe High Quality Partitioning.
   *
   *****************************************************************************/
  
  #ifndef STOP_RULES_SZ45JQS6
  #define STOP_RULES_SZ45JQS6
  
  #include <math.h>
  
  #include "partition_config.h"
  
  class stop_rule {
          public:
                  stop_rule() {};
                  virtual ~stop_rule() {};
                  virtual bool stop( NodeID number_of_finer_vertices, NodeID number_of_coarser_vertices ) = 0;
  };
  
  class separator_simple_stop_rule : public stop_rule {
          public:
                  separator_simple_stop_rule(PartitionConfig & config, NodeID number_of_nodes) {
  	                num_stop = config.sep_num_vert_stop;
                          if(config.disable_max_vertex_weight_constraint) {
                                  config.max_vertex_weight = config.upper_bound_partition; 
                          } else {
                                  config.max_vertex_weight = (NodeWeight)(1.5*config.work_load/num_stop);
                          }
                  };
  
                  virtual ~separator_simple_stop_rule() {};
                  bool stop( NodeID number_of_finer_vertices, NodeID number_of_coarser_vertices );
  
          private:
                  NodeID num_stop;
  };
  
  inline bool separator_simple_stop_rule::stop(NodeID no_of_finer_vertices, NodeID no_of_coarser_vertices ) {
          double contraction_rate = 1.0 * no_of_finer_vertices / (double)no_of_coarser_vertices;
          
          return contraction_rate >= 1.1 && no_of_coarser_vertices >= num_stop;
  }
  
  class simple_stop_rule : public stop_rule {
          public:
                  simple_stop_rule(PartitionConfig & config, NodeID number_of_nodes) {
                          double x = 60;
  	                num_stop = std::max(number_of_nodes/(2.0*x*config.k), 60.0*config.k);
                          if(config.disable_max_vertex_weight_constraint) {
                                  config.max_vertex_weight = config.upper_bound_partition; 
                          } else {
                                  config.max_vertex_weight = (NodeWeight)(1.5*config.work_load/num_stop);
                          }
                  };
                  virtual ~simple_stop_rule() {};
                  bool stop( NodeID number_of_finer_vertices, NodeID number_of_coarser_vertices );
  
          private:
                  NodeID num_stop;
  };
  
  inline bool simple_stop_rule::stop(NodeID no_of_finer_vertices, NodeID no_of_coarser_vertices ) {
          double contraction_rate = 1.0 * no_of_finer_vertices / (double)no_of_coarser_vertices;
          return contraction_rate >= 1.1 && no_of_coarser_vertices >= num_stop;
  }
  class strong_stop_rule : public stop_rule {
          public:
                  strong_stop_rule(PartitionConfig & config, NodeID number_of_nodes) {
                          num_stop = config.k;
                          config.max_vertex_weight = config.upper_bound_partition;
                  };
                  virtual ~strong_stop_rule() {};
                  bool stop( NodeID number_of_finer_vertices, NodeID number_of_coarser_vertices );
  
          private:
                  NodeID num_stop;
  };
  
  inline bool strong_stop_rule::stop(NodeID no_of_finer_vertices, NodeID no_of_coarser_vertices ) {
          double contraction_rate = 1.0 * no_of_finer_vertices / (double)no_of_coarser_vertices;
          return contraction_rate >= 1.1 && no_of_coarser_vertices >= num_stop;
  }
  
  class multiple_k_stop_rule : public stop_rule {
          public:
                  multiple_k_stop_rule (PartitionConfig & config, NodeID number_of_nodes) {
                          num_stop = config.num_vert_stop_factor*config.k;
  
                          if(config.disable_max_vertex_weight_constraint) {
                                  config.max_vertex_weight = config.upper_bound_partition; 
                          } else {
                                  if(config.initial_partitioning) {
                                          //if we perform initial partitioning we relax this constraint
                                          config.max_vertex_weight = 1.5*((double)config.work_load)/(2*config.num_vert_stop_factor); 
                                  } else {
                                          config.max_vertex_weight = (NodeWeight)(1.5*config.work_load/num_stop);
                                  }
                          }
  
                  };
                  virtual ~multiple_k_stop_rule () {};
                  bool stop( NodeID number_of_finer_vertices, NodeID number_of_coarser_vertices );
  
          private:
                  NodeID num_stop;
  };
  
  inline bool multiple_k_stop_rule::stop(NodeID no_of_finer_vertices, NodeID no_of_coarser_vertices ) {
          double contraction_rate = 1.0 * no_of_finer_vertices / (double)no_of_coarser_vertices;
          return contraction_rate >= 1.1 && no_of_coarser_vertices >= num_stop;
  }
  
  
  
  
  #endif /* end of include guard: STOP_RULES_SZ45JQS6 */
  