<commit_before>/*
 * opencog/learning/moses/optimization/hill-climbing.h
 *
 * Copyright (C) 2002-2008 Novamente LLC
 * Copyright (C) 2012 <NAME>
 * All Rights Reserved
 *
 * Written by <NAME>
 *            <NAME>
 *            <NAME>
 *            <NAME>
 *            <NAME>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#ifndef _MOSES_HILL_CLIMBING_H
#define _MOSES_HILL_CLIMBING_H

#include <opencog/util/oc_assert.h>
#include <opencog/util/platform.h>

#include "../representation/instance_set.h"
#include "../moses/scoring.h"
#include "optimization.h"

namespace opencog { namespace moses {

/// Hill-climbing paramters
struct hc_parameters
{
    hc_parameters(bool widen = false,
                  bool step = false,
                  bool cross = false,
                  unsigned max_evals = 20000,
                  double _fraction_of_nn = 2.0) // > 1.0 since works on estimate only.
        : widen_search(widen),
          single_step(step),
          crossover(cross),
          max_nn_evals (max_evals),
          fraction_of_nn(_fraction_of_nn),
          score_range(5.0),
          max_allowed_instances(10000)
    {
        OC_ASSERT(0.0 < fraction_of_nn);
    }
    
    bool widen_search;
    bool single_step;
    bool crossover;

    // Evaluate no more than this number of instances per iteration.
    // Problems with 100 or more features easily lead to exemplars with
    // complexity in excess of 100; these in turn, after decorating with
    // knobs, can have 20K or more nearest neighbors.  Doing a full
    // nearest neighbor scan for such cases will eat up a huge amount of
    // RAM in the instance_set, and its not currently obvious that a full
    // scan is that much better than a random sampling.  XXX Or is it?
    //
    // XXX This parameter should probably be automatically adjusted with
    // free RAM availability!?  Or something like that !?
    unsigned max_nn_evals;

    // fraction_of_nn is the fraction of the nearest-neighbrohood (NN)
    // that should be searched.  For exhaustive NN search, this fraction
    // should be 1.0.  However, setting this lower seems to be OK,
    // especially when used with cross-over, since a fraction seems enough
    // to discover some decent instances that can be crossed-over.  And,
    // by not doing an exhaustive search, the run-time can be significantly
    // improved.
    //
    // XXX I don't understand what the below is saying.
    // One should probably try first to tweak pop_size_ratio to
    // control the allocation of resources. However in some cases (for
    // instance when hill_climbing is used for feature-selection),
    // there is only one deme to explore and tweaking that parameter
    // can make a difference (breadth vs depth)
    // XXX pop_size_ratio disabled in hill-climbing, since its definition
    // was insane/non-sensical.  I can't figure out how it was supposed
    // to work.
    double fraction_of_nn;

    // Range of scores for which to keep instances.  This *should* be
    // set to the value given by metapopulation::useful_score_range().
    // XXX TODO make sure this value is appropriately updated.
    //
    // The range of scores is used to keep the size of the deme in check.
    // The issue is that, for large feature sets, a large number of knobs
    // get created, which means that instances are huge.  It is easy to
    // end up with demes in the tens-of-gigabytes in size, and that's bad,
    // especially when most of the instances have terrible scores.<commit_msg>add comment about RAM-based control and determinism<commit_after>/*
 * opencog/learning/moses/optimization/hill-climbing.h
 *
 * Copyright (C) 2002-2008 Novamente LLC
 * Copyright (C) 2012 <NAME>
 * All Rights Reserved
 *
 * Written by <NAME>
 *            <NAME>
 *            <NAME>
 *            <NAME>
 *            <NAME>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#ifndef _MOSES_HILL_CLIMBING_H
#define _MOSES_HILL_CLIMBING_H

#include <opencog/util/oc_assert.h>
#include <opencog/util/platform.h>

#include "../representation/instance_set.h"
#include "../moses/scoring.h"
#include "optimization.h"

namespace opencog { namespace moses {

/// Hill-climbing paramters
struct hc_parameters
{
    hc_parameters(bool widen = false,
                  bool step = false,
                  bool cross = false,
                  unsigned max_evals = 20000,
                  double _fraction_of_nn = 2.0) // > 1.0 since works on estimate only.
        : widen_search(widen),
          single_step(step),
          crossover(cross),
          max_nn_evals (max_evals),
          fraction_of_nn(_fraction_of_nn),
          score_range(5.0),
          max_allowed_instances(10000)
    {
        OC_ASSERT(0.0 < fraction_of_nn);
    }
    
    bool widen_search;
    bool single_step;
    bool crossover;

    // Evaluate no more than this number of instances per iteration.
    // Problems with 100 or more features easily lead to exemplars with
    // complexity in excess of 100; these in turn, after decorating with
    // knobs, can have 20K or more nearest neighbors.  Doing a full
    // nearest neighbor scan for such cases will eat up a huge amount of
    // RAM in the instance_set, and its not currently obvious that a full
    // scan is that much better than a random sampling.  XXX Or is it?
    //
    // XXX This parameter should probably be automatically adjusted with
    // free RAM availability!?  Or something like that !?
    //
    // Nil: If it is adjusted with free RAM it should be able to be
    // turned off to keep as much determinism as possible
    unsigned max_nn_evals;

    // fraction_of_nn is the fraction of the nearest-neighbrohood (NN)
    // that should be searched.  For exhaustive NN search, this fraction
    // should be 1.0.  However, setting this lower seems to be OK,
    // especially when used with cross-over, since a fraction seems enough
    // to discover some decent instances that can be crossed-over.  And,
    // by not doing an exhaustive search, the run-time can be significantly
    // improved.
    //
    // XXX I don't understand what the below is saying.
    // One should probably try first to tweak pop_size_ratio to
    // control the allocation of resources. However in some cases (for
    // instance when hill_climbing is used for feature-selection),
    // there is only one deme to explore and tweaking that parameter
    // can make a difference (breadth vs depth)
    // XXX pop_size_ratio disabled in hill-climbing, since its definition
    // was insane/non-sensical.  I can't figure out how it was supposed
    // to work.
    double fraction_of_nn;

    // Range of scores for which to keep instances.  This *should* be
    // set to the value given by metapopulation::useful_score_range().
    // XXX TODO make sure this value is appropriately updated.
    //
    // The range of scores is used to keep the size of the deme in check.
    // The issue is that, for large feature sets, a large number of knobs
    // get created, which means that instances are huge.  It is easy to
    // end up with demes in the tens-of-gigabytes in size, and that's bad,
    // especially when most of the instances have terrible scores.
{'fraction_non_alphanumeric': 0.07256657750901267, 'fraction_numerical': 0.012094429584835446, 'mean_word_length': 2.6440677966101696, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6810369', 'n_tokens_mistral': 2482, 'n_tokens_neox': 2342, 'n_words': 1050}