加权随机选择的最pythonic方法

-----开始PGP签名消息-----
哈希:sha1
亲爱的清单,
谁对以下问题有审美建议?我有一些
两个不同事件的关节概率PR(x = x,y = y),存储在a中
浮子列表,每行都代表可能
X的结果和一排中的每个浮子y(y)的可能结果(
我现在将致电我的矩阵,Altough我无法使用numpy或数字
这),例如m = [[0.2,0.4,0.05],[0.1,0.05,0.2]].所有列表中
列表同样长,扁平列表的值汇总
至1.0,即sum(m]行的[sum(row))== 1.实际上,此
"矩阵"大约为20x40,即一个列表Á每个40个浮标.
现在,任务是根据关节为X和Y选择一个结果
概率,之后检查结果是否有一定
标准.如果不符合某些条件,则一对新结果
必须选择,对于其他条件,仍将选择
一定概率.我的方法是选择一个随机数,并且
然后浏览列表,将值添加在一起,直到
累积的总和大于我的随机阈值:
导入随机
r = random.random()
s = 0.0
p = 0.2#如果不实现结果,则选择结果的概率
标准2
break_loop = false
而不是break_loop:
对于rang_index(len(m)):
对于range(Len(Row))的Col_index:
s += m [row_index] [col_index]
如果s> = r:
如果不符合f​​unders_criterion_a(row_index,col_index):
break_loop = true
Elif不符合符合人_CRITERION_B(ROW_INDEX,COL_INDEX):
如果random.random()<= p:
返回row_index,col_index
别的:
break_loop = true
别的:
返回row_index,col_index
如果break_loop:休息
如果break_loop:休息
break_loop = false
现在看起来很丑陋,我想知道您是否会发现
在不使用numpy等的情况下进行此操作的方式稍微更优雅.
最好的
曼努埃尔
-----开始PGP签名-------------
版本:gnupg v1.4.7(darwin)
ID8DBQFIUWONCZ70OCIGLECRARV4AJ9YNHC/MCEGMIYTWOOOW4P44T3RWGCBBJVM
1JRHY5KP1QIGLDACTXXFCSS =
= x6sv
-----结束PGP签名-----

# 回答1


Manuel Ebert,这可能是相关的/有用的:http://code.activestate.com/recipes/498229/
请注意,numpy具有可能是分合方法/函数
更快.
再见,
# 回答2


曼努埃尔·埃伯特(Manuel Ebert)写道:
[狙击]
对于累积概率列表,您可以使用BISECT模块
要找到0,1均匀变量的插入点(您可以
然后映射回单元索引).
另外,您可以使用别名表,http://amath.colorado.edu/courses/74.../web/ss-10.ppt.
您可以产生一个概率表,以考虑您的
标准,因此您无需检查它们.即每个单元
不满足标准A的概率为0.每个
其他单元具有与其成正比的概率
原始值如果满足标准B或其原始值 * P
否则.标准化值 总结到1,你就完成了
需要符合标准.
因此,预处理您的表格,创建相应的累积列表
概率并使用一分为二模型(是一种可能性).
邓肯
# 回答3


在2008年8月30日星期六17:41:27 +0200,曼努埃尔·埃伯特(Manuel Ebert)写道:
...
[删除丑陋的代码]
永远不要害怕将代码件分为小功能.
写一个巨大的循环,不仅很难
阅读,很难编写并且很难调试,但也可以慢慢运行. (它
取决于许多因素.)
无论如何,这是我尽力解决问题的尝试
明白它:
导入随机
def eq(x,y,tol = 1e-10):
#在某些公差内的浮点平等
返回ABS(X-Y)<= TOL
m = [[0.2,0.4,0.05],[0.1,0.05,0.2]]
#每行的总和必须总和1.0
断言等式(1.0,sum([m]行的row的sum(row))))​​)
#构建累积概率矩阵
cm = []
对于M中的行:
对于P中的P:
cm.append(p)#初始化原始概率
对于我的范围(1,len(cm)):
cm [i] += cm [i-1]#,并变成累积概率
断言CM [0]> = 0.0
断言等式(CM [-1],1.0)
DEF索引(数据,P):
"""在数据中返回项目的索引
不小于浮点p.
"""
#注意:这使用线性搜索.如果太慢,
#您可以使用Bisect模块重写它.
对于i,x中的x(数据):
如果x> = p:
返回i
返回Len(Data-1)
def index_to_rowcolumn(i,num_columns):
"""将线性索引号i转换为(行,列)元组."""
#转换[[a,b,c,...],[...]
#array [a,b,c,... z]我们具有身份:
#索引号=行号 *列号 +列号
返回Divmod(i,num_columns)
#现在使用这两个助手功能,我们可以找到行和列
#在M中的第一个条目的数量
#超过给定值.
#您需要定义自己的Efferills_criterion_a和
#funlills_criterion_b,但这里有几个模拟功能
#用于测试:
def funerills_criterion_a(行,列):
返回random.random()<0.5
fundils_criterion_b = fundills_criterion_a
def find_match(p = 0.2):
而真:
r = random.random()
i =索引(cm,r)
行,列= index_to_rowcolumn(i,len(m [0]))
如果Efferills_criterion_a(行,列)或\
fundills_criterion_b(行,列):
返回行,列
别的:
如果random.random()<= p:
返回行,列
这是我的测试:
(1,2)
希望这可以帮助.
- -
史蒂文

标签: python

添加新评论