Skip to content

Commit

Permalink
N-type(h) (Kuroiwa & Beck 2022) ported from https://github.com/Kuroro…
Browse files Browse the repository at this point in the history
  • Loading branch information
guicho271828 committed Jan 15, 2025
1 parent f3d02b4 commit b3c00bf
Show file tree
Hide file tree
Showing 5 changed files with 472 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/search/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,14 @@ create_fast_downward_library(
open_lists/linear_weighted_type_based_open_list
)

create_fast_downward_library(
NAME NTH_BEST_FIRST_OPEN_LIST
HELP "Open list that randomly selects from the n th best element. (Kuroiwa and Beck, ICAPS2022)"
SOURCES
open_lists/nth_best_first_open_list
open_lists/nth_type_based_open_list
)

create_fast_downward_library(
NAME dynamic_bitset
HELP "Poor man's version of boost::dynamic_bitset"
Expand Down
158 changes: 158 additions & 0 deletions src/search/open_lists/nth_best_first_open_list.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#include "nth_best_first_open_list.h"

#include "../evaluator.h"
#include "../open_list.h"

#include "../plugins/plugin.h"
#include "../utils/memory.h"

#include <cassert>
#include <deque>
#include <map>

using namespace std;

namespace nth_best_first_open_list {
template<class Entry>
class NthBestFirstOpenList : public OpenList<Entry> {
typedef deque<Entry> Bucket;

int n;
map<int, Bucket> buckets;
int size;

shared_ptr<Evaluator> evaluator;

protected:
virtual void do_insertion(EvaluationContext &eval_context,
const Entry &entry) override;

public:
explicit NthBestFirstOpenList(const plugins::Options &opts);
NthBestFirstOpenList(int n, const shared_ptr<Evaluator> &eval, bool preferred_only);
virtual ~NthBestFirstOpenList() override = default;

virtual Entry remove_min() override;
virtual bool empty() override;
virtual void clear() override;
virtual void get_path_dependent_evaluators(set<Evaluator *> &evals) override;
virtual bool is_dead_end(
EvaluationContext &eval_context) const override;
virtual bool is_reliable_dead_end(
EvaluationContext &eval_context) const override;
};


template<class Entry>
NthBestFirstOpenList<Entry>::NthBestFirstOpenList(const plugins::Options &opts)
: OpenList<Entry>(opts.get<bool>("pref_only")),
n(opts.get<int>("n")),
size(0),
evaluator(opts.get<shared_ptr<Evaluator>>("eval")) {
}

template<class Entry>
NthBestFirstOpenList<Entry>::NthBestFirstOpenList(
int n, const shared_ptr<Evaluator> &evaluator, bool preferred_only)
: OpenList<Entry>(preferred_only),
n(n),
size(0),
evaluator(evaluator) {
}

template<class Entry>
void NthBestFirstOpenList<Entry>::do_insertion(
EvaluationContext &eval_context, const Entry &entry) {
int key = eval_context.get_evaluator_value(evaluator.get());
buckets[key].push_back(entry);
++size;
}

template<class Entry>
Entry NthBestFirstOpenList<Entry>::remove_min() {
assert(size > 0);
auto it = buckets.begin();
assert(it != buckets.end());
int i = 1;
while (next(it) != buckets.end() && i < n) {
++it;
++i;
}
Bucket &bucket = it->second;
assert(!bucket.empty());
Entry result = bucket.front();
bucket.pop_front();
if (bucket.empty())
buckets.erase(it);
--size;
return result;
}

template<class Entry>
bool NthBestFirstOpenList<Entry>::empty() {
return size == 0;
}

template<class Entry>
void NthBestFirstOpenList<Entry>::clear() {
buckets.clear();
size = 0;
}

template<class Entry>
void NthBestFirstOpenList<Entry>::get_path_dependent_evaluators(
set<Evaluator *> &evals) {
evaluator->get_path_dependent_evaluators(evals);
}

template<class Entry>
bool NthBestFirstOpenList<Entry>::is_dead_end(
EvaluationContext &eval_context) const {
return eval_context.is_evaluator_value_infinite(evaluator.get());
}

template<class Entry>
bool NthBestFirstOpenList<Entry>::is_reliable_dead_end(
EvaluationContext &eval_context) const {
return is_dead_end(eval_context) && evaluator->dead_ends_are_reliable();
}

NthBestFirstOpenListFactory::NthBestFirstOpenListFactory(
const plugins::Options &options)
: options(options) {
}

unique_ptr<StateOpenList>
NthBestFirstOpenListFactory::create_state_open_list() {
return utils::make_unique_ptr<NthBestFirstOpenList<StateOpenListEntry>>(options);
}

unique_ptr<EdgeOpenList>
NthBestFirstOpenListFactory::create_edge_open_list() {
return utils::make_unique_ptr<NthBestFirstOpenList<EdgeOpenListEntry>>(options);
}

class NthBestFirstOpenListFeature : public plugins::TypedFeature<OpenListFactory, NthBestFirstOpenListFactory> {
public:
NthBestFirstOpenListFeature(): TypedFeature("nth") {
document_title("n th best-first open list");
document_synopsis(
"Open list that uses a single evaluator and FIFO tiebreaking and returns a node having the n th best evaluation value.");
document_note(
"Implementation Notes",
"Elements with the same evaluator value are stored in double-ended "
"queues, called \"buckets\". The open list stores a map from evaluator "
"values to buckets. Pushing and popping from a bucket runs in constant "
"time. Therefore, inserting and removing an entry from the open list "
"takes time O(log(n)), where n is the number of buckets.");
add_option<shared_ptr<Evaluator>>("eval", "evaluator");
add_option<bool>(
"pref_only",
"insert only nodes generated by preferred operators", "false");
add_option<int>("n", "n", "2");
}
};

static plugins::FeaturePlugin<NthBestFirstOpenListFeature> _plugin;
}

27 changes: 27 additions & 0 deletions src/search/open_lists/nth_best_first_open_list.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef OPEN_LISTS_NTH_BEST_FIRST_OPEN_LIST_H
#define OPEN_LISTS_NTH_BEST_FIRST_OPEN_LIST_H

#include "../open_list_factory.h"
#include "../plugins/options.h"


/*
Open list indexed by a single int, using FIFO tie-breaking.
Implemented as a map from int to deques.
*/

namespace nth_best_first_open_list {
class NthBestFirstOpenListFactory : public OpenListFactory {
plugins::Options options;
public:
explicit NthBestFirstOpenListFactory(const plugins::Options &options);
virtual ~NthBestFirstOpenListFactory() override = default;

virtual std::unique_ptr<StateOpenList> create_state_open_list() override;
virtual std::unique_ptr<EdgeOpenList> create_edge_open_list() override;
};
}

#endif

Loading

0 comments on commit b3c00bf

Please sign in to comment.