Skip to content

Commit

Permalink
Adding effective multiplicities
Browse files Browse the repository at this point in the history
  • Loading branch information
euxhenh committed Jan 27, 2022
1 parent a7524f2 commit 14ac50b
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 1 deletion.
1 change: 1 addition & 0 deletions includes/MultiSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class MultiSet : public BaseSet {
const pair<size_t, size_t> at(size_t index) const;

vector<size_t> get_multiplicities() const;
vector<size_t> get_leftovers() const;

size_t value() const;
void consume(const vector<size_t>& upper_limits);
Expand Down
2 changes: 2 additions & 0 deletions includes/python_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ extern "C" {

static PyObject* _new_GreedyCoverInstance(PyObject* self, PyObject* args, PyObject* keywds);
static PyObject* _GreedyCoverInstance_at(PyObject* self, PyObject* args, PyObject* keywds);
static PyObject* _GreedyCoverInstance_effective_at(PyObject* self, PyObject* args, PyObject* keywds);

static PyObject* _GreedyCoverInstance_size(PyObject* self, PyObject* args, PyObject* keywds);
static PyObject* _GreedyCoverInstance_n_elements(PyObject* self, PyObject* args, PyObject* keywds);
Expand All @@ -49,6 +50,7 @@ static PyObject* _GreedyCoverInstance__n_elements_remaining(PyObject* self, PyOb
static PyMethodDef gci_methods[] = {
{ "_new_GreedyCoverInstance", (PyCFunction)_new_GreedyCoverInstance, METH_VARARGS | METH_KEYWORDS, "" },
{ "_GreedyCoverInstance_at", (PyCFunction)_GreedyCoverInstance_at, METH_VARARGS | METH_KEYWORDS, "" },
{ "_GreedyCoverInstance_effective_at", (PyCFunction)_GreedyCoverInstance_effective_at, METH_VARARGS | METH_KEYWORDS, "" },
{ "_GreedyCoverInstance_size", (PyCFunction)_GreedyCoverInstance_size, METH_VARARGS | METH_KEYWORDS, "" },
{ "_GreedyCoverInstance_n_elements", (PyCFunction)_GreedyCoverInstance_n_elements, METH_VARARGS | METH_KEYWORDS, "" },

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def run(self):
'name': 'multiset_multicover',
'description': 'MM is a package for running the greedy cover algorithm to perform multiset multicover.',
'license': 'MIT',
'version': '0.5',
'version': '0.6',
'author': 'Euxhen Hasanaj',
'author_email': 'ehasanaj@cs.cmu.edu',
'url': 'https://github.com/ferrocactus/multiset_multicover',
Expand Down
5 changes: 5 additions & 0 deletions src/multiset_multicover/MultiSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ vector<size_t> MultiSet::get_multiplicities() const
return this->_multiplicity;
}

vector<size_t> MultiSet::get_leftovers() const
{
return this->_leftovers;
}

void MultiSet::reset_leftovers()
{
this->__init_leftovers();
Expand Down
26 changes: 26 additions & 0 deletions src/multiset_multicover/python_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,32 @@ PyObject* _GreedyCoverInstance_at(PyObject* self, PyObject* args, PyObject* keyw
}
}

PyObject* _GreedyCoverInstance_effective_at(PyObject* self, PyObject* args, PyObject* keywds)
{
PyObject* py_gci = NULL;
PyObject* py_index = NULL;
static const char* kwlist[] = { "gci", "index", NULL };
if (!PyArg_ParseTupleAndKeywords(args, keywds, "OO", (char**)kwlist, &py_gci, &py_index))
return NULL;

try {
GreedyCoverInstance* gci = decapsule_GreedyCoverInstance(py_gci);
if (PyLong_Check(py_index) && PyIndex_Check(py_index)) {
auto mset = gci->at(PyLong_AsSize_t(py_index));
PyObject* elements = create_list_from_size_t_vector(mset.get_elements());
PyObject* leftovers = create_list_from_size_t_vector(mset.get_leftovers());
PyObject* pp = PyTuple_Pack(2, elements, leftovers);
return pp;
} else {
throw Exception("Non integer index found.");
}
} catch (std::exception const& e) {
string s = "Could not index element: " + string(e.what());
PyErr_SetString(PyExc_BaseException, s.c_str());
return NULL;
}
}

PyObject* _GreedyCoverInstance_size(PyObject* self, PyObject* args, PyObject* keywds)
{
PyObject* py_gci = NULL;
Expand Down
12 changes: 12 additions & 0 deletions src/multiset_multicover/python_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def __getitem__(self, index):
"""
Returns the multiset at `index`.
"""
index = int(index)
return _c_mm._GreedyCoverInstance_at(self._gci, index)

def __repr__(self):
Expand All @@ -56,6 +57,13 @@ def __repr__(self):
def __str__(self):
return f"GreedyCoverInstance({self.n_elements}) with {self.size} multisets"

def effective_at(self, index):
"""
Returns the multiset at `index` with a corrected multiplicity.
"""
index = int(index)
return _c_mm._GreedyCoverInstance_effective_at(self._gci, index)

@property
def size(self):
"""
Expand Down Expand Up @@ -122,6 +130,7 @@ def delete_multiset(self, index):
"""
Removes the multiset given by index.
"""
index = int(index)
if index >= self.size or index < 0:
raise ValueError("Index out of bound.")
_c_mm._GreedyCoverInstance_delete_multiset(self._gci, index)
Expand All @@ -147,6 +156,9 @@ def cover(self, coverage, max_iters=0):
max_iters: int
If 0, will not limit the number of iterations (multisets selected).
"""
max_iters = int(max_iters)
if isinstance(coverage, int):
coverage = int(coverage)
if max_iters < 0:
raise ValueError("Cannot accept negative number of iterations.")
return _c_mm._GreedyCoverInstance_cover(self._gci, coverage, max_iters)
Expand Down

0 comments on commit 14ac50b

Please sign in to comment.