iloveyou
V2EX  ›  问与答

算法苦逼又来求解决方案,一个很简单的问题,大牛们来啊

  •  
  •   iloveyou · Aug 3, 2013 · 4802 views
    This topic created in 4840 days ago, the information mentioned may be changed or developed.
    从a、b、c中随机挑出一个,a出现的几率为20%,b出现的记录为50%,c出现的几率为70%。
    求最简洁效率最高的算法,最好用php。
    Supplement 1  ·  Aug 3, 2013
    把我最终的代码发出来,我遇到的情况更复杂,对象个数未知,对象权重未知。当然原理都是一样的。

    $total_weightiness = 0; //符合条件内容的权重之和
    $weightiness_arr = array(); //存放每个对象权重的范围
    foreach ($final_rules as $key => $value) {
    $weightiness_arr[$key] = $total_weightiness + $value->weightiness;
    $total_weightiness += $value->weightiness;
    }
    $rand = rand(1,$total_weightiness);
    foreach ($weightiness_arr as $key => $value) {
    if($rand < $value)
    return $final_rules[$key];
    }
    Supplement 2  ·  Aug 5, 2013
    又发现一种牛掰的方法:

    $weight = 0;
    $tempdata = array();
    foreach ($data as $one) {
    $weight += $one['weight'];
    for ($i = 0; $i < $one['weight']; $i ++) {
    $tempdata[] = $one;
    }
    }
    $use = rand(0, $weight – 1);
    $one = $tempdata[$use];
    Supplement 3  ·  Aug 5, 2013
    @Mutoo 根据mutoo的方法进一步精简

    $total_weightiness = 0; //符合条件内容的权重之和
    foreach ($final_rules as $key => $value) {
    $total_weightiness += $value->weightiness;
    }
    $rand = rand(1,$total_weightiness);
    foreach ($final_rules as $value) {
    $temp = $rand -= $value->weightiness;
    if($temp < 0)
    return $value;
    }
    19 replies  •  1970-01-01 08:00:00 +08:00
    dndx
    dndx
    Aug 3, 2013 via iPad
    1
    70 + 50 + 20 > 100

    这如何实现?
    iloahz
    iloahz
    Aug 3, 2013
    2
    r = rand() % 100;
    if r < 20:
    return a
    else if r < 70:
    return b
    else:
    return c
    wang2191195
    wang2191195
    Aug 3, 2013 via iPhone
    3
    这个要求太高了=_=
    iloveyou
    iloveyou
    OP
    Aug 3, 2013
    4
    @dndx 你可以把百分比理解为权重,就是出现的几率有多大
    iloveyou
    iloveyou
    OP
    Aug 3, 2013
    5
    @iloahz 你这不对,如果a b的权重一样呢
    rwx
    rwx
    Aug 3, 2013
    6
    自己都说是权重了,那就按权重来办啊
    总权重=20+50+70
    取一个 1 到总权重的随机数
    看随机数落到哪个权重范围就选哪个
    iloveyou
    iloveyou
    OP
    Aug 3, 2013
    7
    @rwx 我目前就是这个思路,但是代码很繁琐。求最优解
    binux
    binux
    Aug 3, 2013
    8
    @iloveyou 2L是对的(虽然他没想到你概率加起来不是100%)
    iloveyou
    iloveyou
    OP
    Aug 3, 2013
    9
    @binux 如果有权重一样的呢
    binux
    binux
    Aug 3, 2013
    10
    @iloveyou 你没看到b的条件是a+b吗?
    windywinter
    windywinter
    Aug 3, 2013
    11
    把2L的% 100改成%140就对了。
    iloveyou
    iloveyou
    OP
    Aug 3, 2013
    12
    @binux 恩 sorry,没注意,2楼和6楼思路一样,我也是这样想的,看来只有这种解了。
    binux
    binux
    Aug 3, 2013
    13
    @iloveyou 你自己写过你会注意不到?
    iloveyou
    iloveyou
    OP
    Aug 3, 2013
    14
    @binux 我的情况更复杂,所以代码也和2楼不一样,所以没仔细看
    jjplay
    jjplay
    Aug 3, 2013
    15
    我觉得你是体彩中心新招聘的程序员!!!!!!!!!
    Mutoo
    Mutoo
    Aug 3, 2013
    16
    你需要《代码大全》第12章,表驱动法。

    不需要有百分数表示,用整数就好。
    1) 先求合sum
    2) 产生0~sum之间的随机数
    3) sum依次减去各个权重,直到sum为负数,被减的那个就是被抽中的

    这个算法要求每次减的顺序是一致的,这样才可以保证概率。
    其实就是把古典概型(权数)转化成几何概型(一维长度)
    best1a
    best1a
    Aug 3, 2013
    17
    @Mutoo +1,遗传算法中貌似把这叫做轮盘赌选择法
    justfindu
    justfindu
    Aug 5, 2013
    19
    http://www.helloweba.com/view-blog-216.html

    类似于这种?

    表示不会贴代码~

    只是这个示例里面有一个转盘范围 min和max , v表示权重或者叫做概率~ 然后就可以抽奖了~
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1537 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 72ms · UTC 18:06 · PVG 02:06 · LAX 10:06 · JFK 13:06
    ♥ Do have faith in what you're doing.