feat: prepare the use of binary partitions for signatures
This commit is contained in:
parent
a6a3f799e7
commit
11f49e58d7
3 changed files with 304 additions and 0 deletions
107
mo/src/problems/partition/moBinaryPartition.h
Normal file
107
mo/src/problems/partition/moBinaryPartition.h
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
#pragma once
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <eo>
|
||||
|
||||
template<class FitT>
|
||||
class moBinaryPartition : public EO<FitT>
|
||||
{
|
||||
public:
|
||||
using AtomType = size_t;
|
||||
using ContainerType = std::set<AtomType>;
|
||||
|
||||
ContainerType selected;
|
||||
ContainerType rejected;
|
||||
|
||||
/** Constructor
|
||||
*
|
||||
* @param total_nb_genes Total number of possible genes from whith to select.
|
||||
*/
|
||||
moBinaryPartition( const size_t total_nb_genes )
|
||||
{
|
||||
// Fill the rejected list with all possible gene indices,
|
||||
// starting from zero.
|
||||
for(size_t i = 0; i < total_nb_genes; ++i) {
|
||||
rejected.insert(i);
|
||||
}
|
||||
// No selected.
|
||||
}
|
||||
|
||||
void select(const size_t atom) {
|
||||
assert(not selected.contains(atom));
|
||||
|
||||
#ifndef NDEBUG
|
||||
size_t has_erased =
|
||||
#endif
|
||||
this->rejected.erase(atom);
|
||||
assert(has_erased == 1);
|
||||
|
||||
#ifndef NDEBUG
|
||||
auto [where, has_inserted] =
|
||||
#endif
|
||||
this->selected.insert(atom);
|
||||
assert(has_inserted);
|
||||
}
|
||||
|
||||
void reject(const size_t atom) {
|
||||
assert(not rejected.contains(atom));
|
||||
|
||||
#ifndef NDEBUG
|
||||
size_t has_erased =
|
||||
#endif
|
||||
this->selected.erase(atom);
|
||||
assert(has_erased == 1);
|
||||
|
||||
#ifndef NDEBUG
|
||||
auto [where, has_inserted] =
|
||||
#endif
|
||||
this->rejected.insert(atom);
|
||||
assert(has_inserted);
|
||||
}
|
||||
|
||||
/** Serialization of the `selected` atoms. */
|
||||
virtual void printOn(std::ostream& out) const
|
||||
{
|
||||
EO<FitT>::printOn(out); // Fitness.
|
||||
// Trailing space already inserted.
|
||||
out << selected.size() << " "; // Size.
|
||||
std::copy(std::begin(selected), std::end(selected),
|
||||
std::ostream_iterator<AtomType>(out, " ")); // Values.
|
||||
out << " ";
|
||||
out << rejected.size() << " "; // Size.
|
||||
std::copy(std::begin(rejected), std::end(rejected),
|
||||
std::ostream_iterator<AtomType>(out, " ")); // Values.
|
||||
}
|
||||
|
||||
/** Deserialization of the `selected` atoms. */
|
||||
virtual void readFrom(std::istream& in)
|
||||
{
|
||||
EO<FitT>::readFrom(in); // Fitness.
|
||||
unsigned size;
|
||||
in >> size; // Size.
|
||||
for(size_t i = 0; i < size; ++i) {
|
||||
AtomType atom;
|
||||
in >> atom; // Value.
|
||||
selected.insert(atom);
|
||||
}
|
||||
assert(selected.size() == size);
|
||||
in >> size; // Size.
|
||||
for(size_t i = 0; i < size; ++i) {
|
||||
AtomType atom;
|
||||
in >> atom; // Value.
|
||||
rejected.insert(atom);
|
||||
}
|
||||
assert(rejected.size() == size);
|
||||
}
|
||||
|
||||
bool operator==(const moBinaryPartition& other) {
|
||||
return this->selected == other.selected
|
||||
and this->rejected == other.rejected;
|
||||
}
|
||||
|
||||
virtual std::string className() const
|
||||
{
|
||||
return "moBinaryPartition";
|
||||
}
|
||||
};
|
||||
89
mo/src/problems/partition/moBinaryPartitionSwapNeighbor.h
Normal file
89
mo/src/problems/partition/moBinaryPartitionSwapNeighbor.h
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <mo>
|
||||
|
||||
#include "moBinaryPartition.h"
|
||||
|
||||
template<class EOT, class Fitness=typename EOT::Fitness>
|
||||
class moBinaryPartitionSwapNeighbor :
|
||||
public moBackableNeighbor<EOT,double>//,
|
||||
// public moIndexNeighbor<EOT,double>
|
||||
{
|
||||
public:
|
||||
using AtomType = typename EOT::AtomType;
|
||||
using ContainerType = typename EOT::ContainerType;
|
||||
using moBackableNeighbor<EOT, Fitness>::fitness;
|
||||
// using moIndexNeighbor<EOT, Fitness>::key;
|
||||
// using moIndexNeighbor<EOT, Fitness>::index;
|
||||
|
||||
moBinaryPartitionSwapNeighbor( const size_t _selected_nb ) :
|
||||
selected_nb(_selected_nb),
|
||||
is_set(false)
|
||||
{
|
||||
assert(selected_nb > 0);
|
||||
}
|
||||
|
||||
virtual void move(EOT& solution) override {
|
||||
assert(is_set);
|
||||
// Swap the two atoms.
|
||||
solution.reject(this->reject);
|
||||
solution.select(this->select);
|
||||
assert(solution.selected.size() == this->selected_nb);
|
||||
|
||||
solution.invalidate();
|
||||
}
|
||||
|
||||
virtual void moveBack(EOT& solution) override {
|
||||
assert(is_set);
|
||||
solution.reject(this->select);
|
||||
solution.select(this->reject);
|
||||
assert(solution.selected.size() == this->selected_nb);
|
||||
|
||||
solution.invalidate();
|
||||
}
|
||||
|
||||
void set(AtomType in, AtomType out) {
|
||||
this->select = in;
|
||||
this->reject = out;
|
||||
#ifndef NDEBUG
|
||||
is_set = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::pair<AtomType,AtomType> get() {
|
||||
assert(is_set);
|
||||
return std::make_pair(select, reject);
|
||||
}
|
||||
|
||||
virtual bool equals(moBinaryPartitionSwapNeighbor<EOT,Fitness>& neighbor) {
|
||||
auto [in, out] = neighbor.get();
|
||||
return this->select == in and this->reject == out;
|
||||
}
|
||||
|
||||
virtual std::string className() const override {
|
||||
return "moBinaryPartitionSwapNeighbor";
|
||||
}
|
||||
|
||||
virtual void printOn(std::ostream& out) const override {
|
||||
assert(is_set);
|
||||
out << selected_nb
|
||||
<< " -" << reject
|
||||
<< " +" << select;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
public:
|
||||
#else
|
||||
protected:
|
||||
#endif
|
||||
const size_t selected_nb;
|
||||
AtomType select;
|
||||
AtomType reject;
|
||||
#ifndef NDEBUG
|
||||
bool is_set;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
108
mo/src/problems/partition/moBinaryPartitionSwapNeighborhood.h
Normal file
108
mo/src/problems/partition/moBinaryPartitionSwapNeighborhood.h
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <mo>
|
||||
#include "moBinaryPartition.h"
|
||||
|
||||
template <class EOT, class Fitness=typename EOT::Fitness>
|
||||
class moBinaryPartitionSwapNeighborhood : public moNeighborhood<moBinaryPartitionSwapNeighbor<EOT, Fitness> >
|
||||
{
|
||||
public:
|
||||
using Neighbor = moBinaryPartitionSwapNeighbor<EOT, Fitness>;
|
||||
using AtomType = typename EOT::AtomType;
|
||||
|
||||
AtomType selected(EOT& from, const size_t i_select) {
|
||||
typename EOT::ContainerType::iterator
|
||||
it = std::begin(from.rejected);
|
||||
std::advance(it, i_select);
|
||||
return *it;
|
||||
}
|
||||
|
||||
AtomType rejected(EOT& from, const size_t j_reject) {
|
||||
typename EOT::ContainerType::iterator
|
||||
it = std::begin(from.selected);
|
||||
std::advance(it, j_reject);
|
||||
return *it;
|
||||
}
|
||||
|
||||
virtual void init(EOT& from, Neighbor& to) override {
|
||||
i_select = 0;
|
||||
j_reject = 0;
|
||||
|
||||
// std::clog << "Init neighborhood:"
|
||||
// << " -" << rejected(from, j_reject)
|
||||
// << " +" << selected(from, i_select)
|
||||
// << std::endl;
|
||||
|
||||
// First item in both lists.
|
||||
AtomType in = selected(from, i_select);
|
||||
AtomType out = rejected(from, j_reject);
|
||||
to.set(in, out);
|
||||
}
|
||||
|
||||
virtual void next(EOT& from, Neighbor& to) override {
|
||||
// If last item of the inner loop.
|
||||
if( i_select == from.rejected.size()-1 ) {
|
||||
i_select = 0; // Reset inner loop.
|
||||
j_reject++; // Next outer loop.
|
||||
} else {
|
||||
i_select++; // Next inner loop.
|
||||
}
|
||||
|
||||
// std::clog << "Next in neighborhood:"
|
||||
// << " -" << rejected(from, j_reject)
|
||||
// << " +" << selected(from, i_select)
|
||||
// << std::endl;
|
||||
|
||||
assert( from.rejected.contains(selected(from,i_select)) );
|
||||
assert( from.selected.contains(rejected(from,j_reject)) );
|
||||
assert( selected(from,i_select) != rejected(from,j_reject) );
|
||||
|
||||
// Implant this move in the neighbor.
|
||||
to.set(
|
||||
selected(from, i_select),
|
||||
rejected(from, j_reject)
|
||||
);
|
||||
}
|
||||
|
||||
virtual bool cont(EOT& from) override {
|
||||
// Outer loop on selected,
|
||||
// inner loop on rejected.
|
||||
// std::clog << "cont neighborhood?"
|
||||
// << " " << j_reject << "(-" << rejected(from, j_reject) << ")/" << from.selected.size()
|
||||
// << " " << i_select << "(-" << selected(from, i_select) << ")/" << from.rejected.size()
|
||||
// << std::endl;
|
||||
|
||||
// If reached the last item of the outer loop.
|
||||
if( i_select == from.rejected.size()-1
|
||||
and j_reject == from.selected.size()-1) {
|
||||
// We should also have reached the end of the inner loop,
|
||||
// and have set the inner loop to zero.
|
||||
// std::clog << "\tnope" << std::endl;
|
||||
return false;
|
||||
|
||||
} else { // There is still some items in the outer loop.
|
||||
// and thus also in the inner loop.
|
||||
// std::clog << "\tyes" << std::endl;
|
||||
assert( j_reject < from.selected.size() );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool hasNeighbor(EOT& solution) override {
|
||||
return solution.rejected.size() > 0;
|
||||
}
|
||||
|
||||
virtual std::string className() const override {
|
||||
return "moBinaryPartitionSwapNeighborhood";
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
public:
|
||||
#else
|
||||
protected:
|
||||
#endif
|
||||
size_t i_select;
|
||||
size_t j_reject;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue