Is there a Python library for handling complicated

2019-04-17 22:38发布

I often work with multidimensional arrays whose array indices are generated from a complicated user-specified set.

I'm looking for a library with classes for representing complicated sets with an arbitrary number of indices, and arbitrarily complicated predicates. Given a set description, the desired output would be a generator. This generator would in turn produce either dicts or tuples which correspond to the multidimensional array indices.

Does such a library exist?


Example

Suppose we had the following user-specified set (in set-builder notation), which represents the indices of some array variable x[i][j]:

{i in 1..100, j in 1..50: i >= 20, j >= 21, 2*(i + j) <= 100}

I'd like to put this into some sort of a lazy class (a generator expression perhaps) that will allow me to lazily evaluate the elements of the set to generate the indices for my array. Suppose this class were called lazyset; this would be the desired behavior:

>>> S = lazyset("{i in 1..100, j in 1..50: i >= 20, j >= 21, 2*(i+j) <= 100}")
>>> S
<generator object <genexpr> at 0x1f3e7d0>
>>> next(S)
{'i': 20, 'j': 21}
>>> next(S)
{'i': 20, 'j': 22}

I'm thinking I could roll my own using generator expressions, but this almost seems like a solved problem. So I thought I'd asked if anyone's come across an established library that handles this (to some extent, at least). Does such a library exist?

2条回答
我只想做你的唯一
2楼-- · 2019-04-17 22:55

Although I am not certain if this specifically (the set-builder notation) is supported by scipy. I think scipy is your best bet regardless.

There is support for sparse arrays/sets in scipy so you can easily let it handle the allocation of those without actually allocating the space :)

查看更多
对你真心纯属浪费
3楼-- · 2019-04-17 23:05

This looks more like a constraint-solver problem to me:

import constraint as c

p = c.Problem()
p.addVariable(0, range(1,101))
p.addVariable(1, range(1,51))
p.addConstraint(lambda i: i >= 20, [0])
p.addConstraint(lambda j: j >= 21, [1])
p.addConstraint(c.MaxSumConstraint(50))

indices = ((s[0], s[1]) for s in p.getSolutionIter())  # convert to tuple generator

then if you do

for ij in indices:
    print ij

you get

(29, 21)
(28, 22)
(28, 21)
(27, 23)
(27, 22)
(27, 21)

...

(20, 25)
(20, 24)
(20, 23)
(20, 22)
(20, 21)
查看更多
登录 后发表回答