如何生成一个随机的凸分段线性函数。

6

我想在python中生成一个玩具示例来说明一个凸分段线性函数,但我无法找到最好的方法。我想要做的是指示线条数量并随机生成函数。

一个凸分段线性函数定义如下:

1

例如,如果我想要四条直线,那么我想要生成如下所示的内容。

enter image description here

因为有四条线。我们需要生成四个递增的随机整数来确定 x 轴上的区间。

import random 
import numpy as np
random.seed(1)

x_points = np.array(random.sample(range(1, 20), 4))
x_points.sort()
x_points = np.append(0, x_points)

x_points
[0 3 4 5 9]

我现在可以使用前两个点并创建一个随机线性函数,但我不知道接下来该如何保持凸性。请注意,如果函数的图形上任意两点之间的线段不在这两点之间的图形下方,则称函数为凸函数。


每个线段的斜率都需要增加。 - mkrieger1
@mkrieger1 我相信还应该有其他规则来确保块之间的连接。 - belcansi
1
碎片相连是规则。如果您有x间隔和坡度,这将定义所有片段。 - mkrieger1
2个回答

2
斜率从0开始,以[0,1)范围内的随机值单调递增。第一个y值也是零,请参阅注释。
import numpy as np
np.random.seed(0)

x_points = np.random.randint(low=1, high=20, size=4)
x_points.sort()
x_points = np.append(0, x_points)  # the first 0 point is 0

slopes = np.add.accumulate(np.random.random(size=3))
slopes = np.append(0,slopes)  # the first slope is 0

y_incr = np.ediff1d(x_points)*slopes
y_points = np.add.accumulate(y_incr)
y_points = np.append(0,y_points)  # the first y values is 0

一个可能的输出看起来像这样:
print(x_points)
print(y_points)
# [ 0  1  4 13 16]
# [ 0.          0.          2.57383685 17.92061306 24.90689622]

enter image description here

打印此图形:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot(x_points,y_points, '-o', label="convex piecewise-linear function")
ax.legend()
fig.patch.set_facecolor('white')
plt.show()

感谢您的详细解释。如果我生成一个随机的x点,并想要得到相应的y值,在您的示例中该如何实现?此外,您能否友好地分享一下您用于绘制图形的代码?谢谢。 - belcansi
请查看最后一段关于图表的更新。代码不是逐个生成点,而是以向量化的方式为整个范围生成。如果您需要更多的点,最简单的方法是使用不同的设置重新运行整个程序,并请求更多的点。 - DanielTuzes
我正在分析代码,发现根据你的代码,第一个线性函数总是零函数。我猜你应该生成四个点来计算斜率,而不是添加零。 - belcansi
请问您能否以适当的方式在您的帖子中添加绘图代码?我在我的端上尝试时出现了错误。 - belcansi
1
这不是Python。Gnuplot是一个很棒的绘图程序,与LaTeX配合使用效果很好。我用Python将图形替换为matplotlib的输出。 - DanielTuzes
显示剩余2条评论

0

确保梯度(=dx/dy)是递增的。 伪代码:

s = 1;
x = 0;
y = 0;
n = 4;
while(--n>0)
{
  //increase x randomly
  dx = rand(3);
  dy = dx * s;
  x += dx;
  y += dy; 
  //increase gradient randomly
  s += rand(3);
  print x + "/" +y;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接