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