清除的文本:
如何创建m=5的随机数,将upp相加,比如n=100。但是,第一个随机数是10<;x1<;30,第二个随机nr是5<;x2<;20,第三个随机nr是10<;x3<;25等等,所以这五个随机数加起来就是100。如何创建这些受约束的五个数字?
是的。
[[
相关问题A1):创建五个加起来等于100的随机数的标准方法是在[0100]之间抽样四个数,并添加边界0和100,然后对这六个数进行排序[0、x1、x2、x3、x4100]。我寻找的五个随机数,是三角。也就是说
100 - x[4] = delta 5
x[4]- x[3] = delta 4
x[3]- x[2] = delta 3
x[2]- x[1] = delta 2
x[1] - 0 = delta 1
这五个三角洲现在加起来是100个。例如,它们可能是0,1,2,7,90。下面是一些解决此问题的代码:
total_sum = 100
n = 5
v = numpy.random.multinomial(total_sum, numpy.ones(n)/n)
]]
是的。
对于我的问题,我不能允许大的间隔发生,上面最大的间隔是90-7=83,太宽了。所以,我必须指定一个更紧密的排列,比如说[10,30]。这意味着最大的随机数是30,这不允许像83这样的大价差。
是的。
[[
相关问题A2):创建5个边界为10<;x庘i<;30且相同的的数字的部分解决方案,其总和为100,如下所示:只需在A1)中将下边界10添加到delta。所以我得到五个随机数,我寻找如下:
100 - x[4] = delta 5 + 10
x[4]- x[3] = delta 4 + 10
x[3]- x[2] = delta 3 + 10
x[2]- x[1] = delta 2 + 10
x[1] - 0 = delta 1 + 10
基本上,我完全喜欢A1),但不是从0开始,而是从10开始。因此,每个数字都有下边界10,但它们没有上边界,它可能太大,太大。如何将上限限制为30?这里的问题是如何限制上边界
]]
是的。
概括地说,我试图解决的问题的类型如下:我需要5个随机数,加起来是100,我需要分别为每个数指定边界,比如第一个随机数为[10,30],第二个随机数为[5,10],第三个随机数为[15,35],等等,它们加起来必须是100。
但我使用的真实数据,有大约100个数字xòI(m=50),所有这些加起来就是大约40万。对于一个数字x}i,这个范围通常是[30005000],这些数字并不是很准确,我只是想传达一些关于问题大小的信息。目的是做一个MCMC模拟,所以这些数字需要快速生成。人们已经提出了非常优雅的解决方案,这些方案确实有效,但它们花费的时间太长,所以我不能使用它们。这个问题还没有解决。理想情况下,我想要一个O(m)解决方案和O(1)内存解决方案。
这个问题不应该是NP难的,它感觉不像。应该有多项式时间解,对吧?
试试这个:
编辑:
下面是如何生成给定
n
范围约束和所需目标和的n
随机数的列表:这就是你使用它的方法:
不过,请注意:如果约束不能保证最终达到总和,则会出现无限循环和堆栈溢出错误,例如:
首先,定义范围:
然后列举所有可能性:
等效一层:
然后从中选择一个随机元素:
编辑:
笛卡尔积(用
itertools.product
计算)本身不占用太多RAM(这是因为itertools.product
返回一个生成器,它使用O(1)空间,但正如您所指出的,它占用了很多时间)。只有计算列表(answer
)才可以。坏消息是,为了使用random.choice
,您需要一个列表。如果你真的不想使用列表,那么你可能需要提出一个衰减概率函数。下面是一个非常简单的概率函数,您可以使用它:衰减概率允许您增加选择符合约束的下一个向量的概率。这样想:你有很多限制。很可能,会有相对较少的向量满足这些约束。这意味着每次你决定不使用一个向量时,有另一个这样的向量的概率就会降低。因此,随着时间的推移,您需要逐渐地更偏向于将当前向量返回为“随机选择的向量”。当然,仍然可以遍历整个循环结构而不返回向量。这就是为什么代码从符合约束条件的第一个向量的默认值开始(假设存在约束条件),如果衰减概率不允许返回向量,则返回最后一个向量。
注意,这种衰减概率思想允许您不必迭代所有候选向量。随着时间的推移,代码返回所考虑的当前向量的概率增加,从而降低了代码继续并考虑其他向量的概率。因此,这个想法也有助于减轻您对运行时的担忧(不过,我很不好意思补充,不是很担心)
假设需要n_1 in[10,30]、n_2 in[20,40]、n_3 in[30,50]和n1+n2+n3=90
如果你需要每一个可能的三重态(n_1,n_2,n_3)的可能性相等,那就很困难了。形式的三元组(20,nã2,nã3)的数目大于三元组(10,nã2,nã3)的数目,因此不能只均匀地选取nã1。
令人难以置信的缓慢但准确的方法是在正确的范围内生成所有5个随机数,如果总和不正确则拒绝整个组。
。啊哈!
我找到了一种有效地参数化选择的方法。不过,首先,为简单起见,请注意下界之和是可能的最小和。如果从目标数中减去下界之和,然后从每个生成的数中减去下界,则会出现一个问题,其中每个数都在区间[0,max_k-min_k]内。这简化了数学和数组(列表)处理。设n_k为基于0的选择,0<;=n_k<;=max_k-min_k
和的顺序是字典式的,所有的和首先以n_1=0(如果有的话)开始,然后n_1==1和,等等。在每个组中,和按n_2排序,然后按n_3排序,依此类推。如果你知道有多少和加在目标上(称为T),以及有多少和以n_1=0,1,2开头。。。然后您可以在该列表中找到和数S的起始数n1。然后你可以把这个问题简化为添加n嫒2+n嫒3+。。。要得到T-n_1,求和数S(从小于n_1的数开始计算原始和)。
假设pulse(n)是n+1个1的列表:(n+1)*[1],用Python术语来说。设max_k,min_k为第k个选择的限制,m_k=max_k-min_k为基于0的选择的上限。然后有1+mç1不同的“和”从第一个数的选择,并且脉冲(mçk)给出了分布:1是使每个和从0到mç1。对于前两个选择,有m_1+m_1不同的和。结果表明,脉冲(m~1)与脉冲(m~2)的卷积给出了分布。
是时候停止一些代码了:
这是专门为使用“脉冲”阵列进行卷积而编码的,因此卷积中的每个线性组合只是一个和。
这些只在最终类解决方案的构造函数中使用:
将其用于:
……等等,这个类可以稍微减少一点,但是主空间开销在rconv列表中,该列表包含存储的卷积。大约是N*T/2,用于O(NT)存储。
卷积只使用范围,在相同的约束条件下产生大量随机数,表的构建时间“摊销”为零。next()的时间复杂度平均约为T/2,而O(T)则是进入rconv列表的索引数。
为了了解算法的工作原理,假设一个序列有3个基于零的选择,最大值(5,7,3)和一个基于0的目标T=10。在空闲会话中定义或导入pulse和stepconv函数,然后:
K3[i]显示不同选择n_1,n_2,n_3的数目,使得0<;=n_k<;=m_k和∑n_k=i。当应用于其中两个列表时,让*表示卷积。然后脉冲(m_2)*脉冲(m_3)给出n_2和n_3的和的分布:
从0到T=10的每个值(几乎)都是可能的,所以第一个数字的任何选择都是可能的,并且有R23[T-n_1]个可能的三元组加上以N1开头的T=10。因此,一旦发现有18个可能的和加上10,就生成一个随机数S=randint(18),并通过R23[T:T-m_1-1:-1]数组进行倒计时:
请注意,该列表的总和是上述K3[10]中计算的总和。健康检查。不管怎样,如果S==9是随机选择,那么求出该数组中可以求和的前导项有多少,而不超过S。这就是n_1的值。在本例中,1+2+3<;=S,但1+2+3+4>;S,所以n_1是3。
如上所述,您可以找到第二个问题。最后的数字(本例中的n_3)将唯一确定。
相关问题 更多 >
编程相关推荐