首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有倾斜的python随机

带有倾斜的python随机
EN

Software Engineering用户
提问于 2013-03-07 21:14:16
回答 5查看 2.6K关注 0票数 3

我试图为一个生物模拟器创建一个非常简单的进化算法,我想要的是,这两种生物都有一个特性和一个优势水平,都是由国家统计局注意到的。他们的孩子的特征将是一个随机数之间的生物A和生物的特征,然后倾斜到更占优势的。因此,如果A的性状为5,优势为2,B为10,优势为7,则偏斜为-5,因此它更倾向于B。他们的孩子更可能有8而不是6。有什么好的方法可以做到这一点呢?我把它想象成这样:A5-6--7--8-9-10B

在我能够测试结果之前,我不知道这个斜率应该有多大,所以暂时它是任意的。

谢谢大家抽出时间来帮助我。

EN

回答 5

Software Engineering用户

回答已采纳

发布于 2013-03-07 23:21:40

我的解决方案会让你更倾向于更大的优势差异:

它使用的事实是,将一个值在0到1之间提高到一个正幂会使结果在相同的范围内倾斜。

如你所愿,设置微调。

代码语言:javascript
复制
import random
a_trait = 5
a_dominance = 2
b_trait = 10
b_dominance = 7

target = random.random()
skew = abs(a_dominance - b_dominance) + 1
fine_tuning_multiplier = 0.3
skewed_target = target ** (skew * fine_tuning_multiplier)

trait_delta = abs(a_trait - b_trait)
target_trait = trait_delta * (1 - skewed_target)

if a_dominance > b_dominance:
  val = b_trait - target_trait
else:
  val = a_trait + target_trait

print "val:", int(round(val))

请注意,在此解决方案中,必须对特征进行排序。(即a_trait < b_trait)

连续40次跑步,结果是:

8 8 9 8 9 10 6 7 7 10 8 8 9 9 10 9 9 7 10 6 10 7 10 9 10 10 7 8 8 7 10 5 6 6 9 9 10 10 6 6

票数 1
EN

Software Engineering用户

发布于 2013-03-07 21:23:25

当然,这很简单。

只需取两个主导值之和,并取这些值的random.randrange()值。

如果该值低于父本A的优势值,则您选择了该父母亲的性状,否则它就是您选择的父本B的性状:

代码语言:javascript
复制
import random

if random.randrange(parentA.dominance + parentB.dominance) < parentA.dominance:
    trait = parentA.trait
else:
    trait = parentB.trait

换句话说,这是两个选项之间非常简单的加权随机选择。

对于您的具体示例,优势的总和为9,因此randrange()值为0到8之间的值;如果选择0或1,则选择父A的特征,如果选择2、3、4、5、6、7或8,则选择父B的特征。

如果你说的是从父母A的特征值到父母B的特征值,然后将特征作为一个范围来处理,那么你的优势值就会被用来“拉”一个或另一个父母的性状值。

基本上可以归结为父母之间的拔河。在平衡优势的情况下,平均而言,选择的性状可以归结为这两个性状的平均值。但是,当父母一方主宰另一方时,特质价值就会选择“转移”给占主导地位的父母。

这意味着,中点以下的值是为父A有机会在(parentA.dominance + parentB.dominance)中选择的,而中点以上的值有可能被选择为parentB.dominance in (parentA.dominance + parentB.dominance)。

代码语言:javascript
复制
import random

pick = random.random()

# sort parents by trait; smallest trait first
parents = sorted((parentA, parentB), key=attrgetter('trait'))
average = (parents[0].trait + parents[1].trait) / 2.0
weights = []
slots = (parents[1].trait - parents[0].trait + 1.0) * (parents[0].dominance + parents[1].dominance)
for i in range(parents[0].trait, parents[1].trait + 1):
    if i <= average:
        weights.append(sum(weights) + (parents[0].dominance / slots))
    else:
        weights.append(sum(weights) + (parents[1].dominance / slots))
    if weights[-1] > pick:
        return i

利用上面的计算,在父母A和父母B之间进行快速的特征选择:

代码语言:javascript
复制
>>> for i in range(40): print pickTrait(),
... 
9 9 9 10 6 9 8 10 7 9 9 8 8 8 9 8 9 9 7 5 8 8 9 5 9 9 10 10 10 10 5 5 9 9 8 9 10 7 8 9
票数 2
EN

Software Engineering用户

发布于 2013-03-07 22:15:38

据我所见,您需要一个加权随机选择,来自range(parent_a.trait, parent_b.trait)

要线性地分配权重,最简单的方法是构造一个浮动范围,使范围的sum()1.0,而每一步都表示选择这一步的概率。

示例:

代码语言:javascript
复制
trait_delta = abs(pacent_a.trait - trait_b.trait)
trait_delta_sum = trait_delta * (trait_delta+1.) / 2.
weights = [x/trait_delta_sum for x in range(1, trait_delta+1)]

正如我前面所说,权重之和应等于1:

代码语言:javascript
复制
assert sum(weights) == 1.

然后生成权重的累积和:

代码语言:javascript
复制
cumulative_weihts = [sum(weights[:x]) for x in range(trait_delta)]

现在只需选择一个随机数,并找到比所述随机数小的最大数的索引:

代码语言:javascript
复制
rand = random.random()
shift = sum[-1 for x in cumulative_weightn if r<x])

最后,将倾斜作为与具有较大优势的性状的抵消:

代码语言:javascript
复制
if parent_a.dominance > parent_b.dominance:
    trait = parent_a.dominance + skew
else:
    trait = parent_b.dominance + skew
票数 2
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/189663

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档