Генератор Python, чтобы произвести целых точек на N-симплекс.


Ищем комментарий кода, и, надеюсь, чему-то научиться, если у кого-то есть лучше решение. Вот что я писал:

from __future__ import division, print_function
from future_builtins import *
import numpy as np

def _walk(num_dims, samples_per_dim, max_):
    if num_dims == 0:
        yield np.array([(max_ - 1) / (samples_per_dim - 1)])
    else:
        for i in range(max_):
            for rest in _walk(num_dims - 1, samples_per_dim, max_ - i):
                yield np.concatenate((np.array([i]) / (samples_per_dim - 1),
                                      rest))

def walk(num_dims, samples_per_dim):
    """
    A generator that returns lattice points on an n-simplex.
    """
    return _walk(num_dims, samples_per_dim, samples_per_dim)

Итак, список(ходьбы(2, 3)) дает:

[array([ 0.,  0.,  1.]),
 array([ 0. ,  0.5,  0.5]),
 array([ 0.,  1.,  0.]),
 array([ 0.5,  0. ,  0.5]),
 array([ 0.5,  0.5,  0. ]),
 array([ 1.,  0.,  0.])]


1123
2
задан 7 июня 2011 в 10:06 Источник Поделиться
Комментарии
2 ответа

Используя предложения Уинстон Эверт использовать модуле itertools, и использование списков вместо массивов numpy внутренне, вот это альтернативное решение:

def walk(num_dims, samples_per_dim):
"""
A generator that returns lattice points on an n-simplex.
"""
max_ = samples_per_dim + num_dims - 1
for c in combinations(range(max_), num_dims):
c = list(c)
yield [(y - x - 1) / (samples_per_dim - 1)
for x, y in izip([-1] + c, c + [max_])]

1
ответ дан 8 июня 2011 в 07:06 Источник Поделиться

Конкатенация массивов numpy-это не очень хорошая идея, потому что это не так, как они были разработаны, чтобы использоваться.

Лучшим способом может быть такой:

def walk(num_dims, samples_per_dim):
"""
A generator that returns lattice points on an n-simplex.
"""
values = np.arange(samples_per_dim) / (samples_per_dim - 1)
for items in itertools.product(values, repeat = num_dims+1):
if sum(items) == 1.0:
yield items

В основном, мы переберем все возможные комбинации этих точек, и отфильтровать недействительные. Это может показаться расточительным, но поскольку модуле itertools написан на C, его, вероятно, на самом деле быстрее, чем ваше решение. Она производит кортежей, а затем массивы numpy.

2
ответ дан 7 июня 2011 в 11:06 Источник Поделиться