如何在Python中最大限度地分离多维数据集中的n个点?如何使用scipy.integrate.ode?

如何在Python中最大限度地分离多维数据集中的n个点?如何使用scipy.integrate.ode?,python,python-3.x,scipy,ode,Python,Python 3.x,Scipy,Ode,我需要在单位立方体中找到n个点,它们的间距大致最大。我目前正在考虑将这个问题写成一个ODE,并使用scipy.integrate.ODE来完成这项工作。也就是说,进行模拟,其中每个粒子沿立方体的壁相互排斥。我不太在乎效率 不幸的是,对于大于n=5的问题,我无法使其工作: import numpy as np def spread_points_in_cube(n, dimensions=3, rng=None): from scipy.integrate import ode

我需要在单位立方体中找到n个点,它们的间距大致最大。我目前正在考虑将这个问题写成一个ODE,并使用
scipy.integrate.ODE
来完成这项工作。也就是说,进行模拟,其中每个粒子沿立方体的壁相互排斥。我不太在乎效率

不幸的是,对于大于n=5的问题,我无法使其工作:

import numpy as np


def spread_points_in_cube(n, dimensions=3, rng=None):
    from scipy.integrate import ode
    if rng is None:
        rng = np.random

    size = n * dimensions
    y0 = np.zeros((2 * size))
    y0[:size] = rng.uniform(size=size)
    t0 = 0.0

    def clip_to_wall(positions, forces):
        forces = np.where(positions == 0.0,
                          np.clip(forces, 0, np.inf),
                          forces)
        forces = np.where(positions == 1.0,
                          np.clip(forces, -np.inf, 0.0),
                          forces)
        return forces

    def decode(y):
        positions = np.clip(y[:size].reshape((n, dimensions)), 0, 1)
        velocities = clip_to_wall(positions, y[size:].reshape((n, dimensions)))
        return positions, velocities

    def f(t, y):
        retval = np.zeros((2 * size))
        positions, velocities = decode(y)
        #print("pos", positions)
        delta_positions = positions[:, np.newaxis, :] - positions[np.newaxis, :, :]
        # print("delta_positions", delta_positions)
        distances = np.linalg.norm(delta_positions, axis=2, ord=2)
        distances += 1e-5
        # print("distances", distances)
        pairwise_forces = delta_positions * (distances ** -3)[:, :, np.newaxis]
        # print("pairwise f", pairwise_forces[0, 1])
        forces = np.sum(pairwise_forces, axis=1)
        forces -= 0.9 * velocities
        forces = clip_to_wall(positions, forces)
        #print("forces", forces)
        retval[:size] = velocities.reshape(size)
        retval[size:] = forces.reshape(size)
        return retval

    r = ode(f).set_integrator('vode', method='adams')
    r.set_initial_value(y0, t0)
    t_max = 40000
    dt = 1
    while r.successful() and r.t < t_max:
        r.integrate(r.t + dt)
    return decode(r.y)[0]
将numpy导入为np
多维数据集中的def排列点(n,尺寸=3,rng=无):
从scipy.integrate导入ode
如果rng为无:
rng=np.random
尺寸=n*尺寸
y0=np.零((2*尺寸))
y0[:尺寸]=均匀尺寸(尺寸=尺寸)
t0=0.0
def夹至墙壁(位置、力):
力=np,其中(位置=0.0,
np.clip(力,0,np.inf),
(部队)
力=np,其中(位置=1.0,
np.clip(力,-np.inf,0.0),
(部队)
返回部队
def解码(y):
位置=np。剪辑(y[:大小]。重塑((n,尺寸)),0,1)
速度=夹住墙壁(位置,y[尺寸:)。重塑((n,尺寸)))
返回位置、速度
定义f(t,y):
retval=np.零((2*大小))
位置、速度=解码(y)
#打印(“pos”,位置)
delta_positions=位置[:,np.newaxis,:]-位置[np.newaxis,:,:]
#打印(“增量位置”,增量位置)
距离=np.直线度标准(delta_位置,轴=2,ord=2)
距离+=1e-5
#打印(“距离”,距离)
成对作用力=三角形位置*(距离**-3)[:,:,np.newaxis]
#打印(“成对f”,成对作用力[0,1])
力=np.和(两两作用力,轴=1)
力-=0.9*速度
力=夹在墙上(位置、力)
#打印(“力”,力)
retval[:size]=速度。重塑(大小)
retval[size:]=力。重塑(大小)
返回返回
r=ode(f)。设置积分器('vode',方法='adams')
r、 设置初始值(y0,t0)
t_max=40000
dt=1
当r.successful()和r.t
泊松圆盘采样是一种线性时间算法。参考文献:


罗伯特·布里森。“任意维的快速泊松圆盘采样”,ACM SIGGRAPH。第2007卷。2007。

@LutzL:根据你的建议增加了摩擦力。仍然不起作用:(什么是“不起作用”的意思?具体点。你有错误吗?一个你没有预料到的输出?在后一种情况下,显示你得到的输出,并解释你期望的结果。@WarrenWeckesser:谢谢你看一看。它不会收敛。如果你想尝试,你可以自己粘贴代码。