我试着写一个Python函数,它可以完成以下任务:
为了更清楚地说明这一点,下面是一个例子:
请注意带有权重的点是如何“推动”其他点的。
t3psigkw1#
一种可能性是制定一个规则,例如:两个相邻点之间的距离应该与它们的权重之和成比例。这个规则似乎与你的例子并不完全一致。在你的例子中,看起来每个点都排斥其他每个点,而不仅仅是相邻的点。但它的优点是规则简单。下面是这个规则在python中的实现:
from itertools import pairwise, accumulate def place_points(weights): if all(w == 0 for w in weights): return [p / (len(weights)-1) for p in range(0, len(weights))] else: dists = [w1+w2 for w1,w2 in pairwise(weights)] positions = list(accumulate(dists, initial=0)) total_dist = positions[-1] normalised_positions = [p / total_dist for p in positions] return normalised_positions for weights in ([0,0,0,0,0], [1,0,0,0,2], [1,0,10,0,2]): print('weights: ', weights) print('points: ', place_points(weights)) print() # weights: [0, 0, 0, 0, 0] # points: [0.0, 0.25, 0.5, 0.75, 1.0] # weights: [1, 0, 0, 0, 2] # points: [0.0, 0.333, 0.333, 0.333, 1.0] # weights: [1, 0, 10, 0, 2] # points: [0.0, 0.043, 0.478, 0.913, 1.0]
nnsrf1az2#
这是一个物理模型,它缓慢地移动这些点,就像它们是滑动的磁铁一样。在每次迭代中,计算施加在每个磁体上的力,并且磁体相应地移动。一个磁铁对另一个磁铁的排斥力,正比于两个磁铁间距离平方的倒数,因为实际的磁铁就是这样工作的.
import numpy as np #import matplotlib.pyplot as plt ## uncomment those lines for graphics output def move_points(weights, points=None, left=0, right=1, n_iter = 1000, learning_rate = 0.0001): n = weights.shape[0] if not points: points = np.linspace(0, 1, n) assert(points.shape == weights.shape == (n,)) #plt.scatter(points, [0]*n) for t in range(1, n_iter+1): dists = (points - points.reshape((n,1))) coeffs = np.sign(dists) / dists**2 forces = np.nansum(weights*coeffs, axis=1) points = points - learning_rate * forces points[0] = max(left, points[0]) points[-1] = min(points[-1], right) #plt.scatter(points, [t]*n) #plt.show() return points
测试:
for weights in map(np.array, ([0,0,0,0,0], [1,0,0,0,2], [1,0,10,0,2])): print('weights: ', weights) print('points: ', move_points(weights, n_iter=100)) print() # weights: [0 0 0 0 0] # points: [0. 0.25 0.5 0.75 1. ] # weights: [1 0 0 0 2] # points: [0. 0.32732937 0.46804381 0.59336546 1. ] # weights: [ 1 0 10 0 2] # points: [0. 0.11141358 0.46804381 0.83729092 1. ]
轨迹的图形输出:
权重= [0 0 0 0 0]
权重= [1 0 0 0 2]
权重= [1 0 10 0 2]
2条答案
按热度按时间t3psigkw1#
一种可能性是制定一个规则,例如:
两个相邻点之间的距离应该与它们的权重之和成比例。
这个规则似乎与你的例子并不完全一致。在你的例子中,看起来每个点都排斥其他每个点,而不仅仅是相邻的点。
但它的优点是规则简单。
下面是这个规则在python中的实现:
nnsrf1az2#
这是一个物理模型,它缓慢地移动这些点,就像它们是滑动的磁铁一样。
在每次迭代中,计算施加在每个磁体上的力,并且磁体相应地移动。
一个磁铁对另一个磁铁的排斥力,正比于两个磁铁间距离平方的倒数,因为实际的磁铁就是这样工作的.
测试:
轨迹的图形输出:
权重= [0 0 0 0 0]
权重= [1 0 0 0 2]
权重= [1 0 10 0 2]