找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1852|回复: 0
打印 上一主题 下一主题

php实现概率性随机抽奖代码

[复制链接]

2588

主题

2588

帖子

7694

积分

论坛元老

Rank: 8Rank: 8

积分
7694
跳转到指定楼层
楼主
发表于 2018-2-14 05:40:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

            1、初始数据:
权重越大,抽取的几率越高
[奖品1, 权重 5], [ 奖品2, 权重6], [ 奖品3, 权重 7], [ 奖品4, 权重2]
2、处理步骤:
1)N = 5 + 6 + 7 + 2 = 20
2)然后取1-N的随机数M
3)界定各 奖品的权重范围值 奖品 1 : 1-5 ; 奖品2 : 6-11; 奖品3: 12-18; 奖品4: 19-20
4) 如果M在某个奖品的权重范围值内,标识这个奖品被抽取到
id = $id;
    $this->weight = $weight ? $weight : 0;
    $this->name = $name ? $name : '随机奖品' . $id;
  }

  # id
  public function getId() {
    return $this->id;
  }

  # 权重
  public function getWeight() {
    return $this->weight;
  }

  # 设置权重范围区间
  public function setRange($start, $end) {
    $this->start = $start;
    $this->end = $end;
  }

  # 判断随机数是否在权重范围区间
  public function inRange($num) {
    return ($num >= $this->start) && ($num end);
  }
}

/**
* 奖品池
*/
class PrizePoll implements IteratorAggregate, Countable {
  # 奖品集
  protected $items = array();

  # 加入奖品
  public function addItem(Prize $item) {
    $this->items[$item->getId()] = $item;
    return $this;
  }

  # 删除奖品
  public function removeItem($itemId) {
    if (isset($this->items[$itemId])) {
      unset($this->items[$itemId]);
    }
    return $this;
  }

  # 更新奖品
  public function updateItem(Prize $item) {
    if (isset($this->items[$item->getId()])) {
      $this->items[$item->getId()] = $item;
    }
    return $this;
  }

  # 获取所有奖品
  public function getItems() {
    return $this->items;
  }

  # 所有所有可用奖品(如果权重为0,说明这个奖品永远不可能抽到)
  public function getVisibleItems() {
    $items = array();
    foreach ($this->items as $item) {
      if ($item->getWeight()) {
        $items[$item->getId()] = $item;
      }
    }
    return $items;
  }

  # Countable::count
  public function count() {
    return count($this->items);
  }

  # IteratorAggregate::getIterator()
  public function getIterator() {
    return new ArrayIterator($this->items);
  }
}

/**
* 简单的抽奖类
*/
class SimpleTurn {
  # 奖池
  protected $poll = null;
   
  public function __construct(PrizePoll $poll) {
    if ($poll) {
      $this->setPoll($poll);
    }
  }

  # 抽奖
  public function run(PrizePoll $poll) {
    $poll = $poll ? $poll : $this->poll;
    if ( ! $poll) {
      throw new Exception('奖池未初始化');
    }

    if ($poll->count() getVisibleItems();
    if (count($items) getWeight();
      $end = $sum;

      # 设置奖品的权重范围区间
      $item->setRange($start, $end);
    }

    # 随机数
    $rand = $this->getRandNum(1, $sum);

    # 区间段判断
    foreach ($items as $item) {
      if ($item->inRange($rand)) {
        return $item;
      }
    }
    return null;
  }

  # 获取随机数
  public function getRandNum($min, $max) {
    return mt_rand($min ? $min : 1, $max);
  }

  # 设置奖池
  public function setPoll(PrizePoll $poll) {
    $this->poll = $poll;
  }
}

# 示例
try {
  $prizePoll = new PrizePoll();
  $prizePoll->addItem(new Prize(1, 5))
    ->addItem(new Prize(2, 6))
    ->addItem(new Prize(3, 7))
    ->addItem(new Prize(4, 2));

  $turn = new SimpleTurn($prizePoll);
  $prize = $turn->run();
  var_dump($prize);
} catch (Exception $e) {
  print_r($e);
}
            
            
您可能感兴趣的文章:
  • php中通过数组进行高效随机抽取指定条记录的算法
  • php实现可以设置中奖概率的抽奖程序代码分享
  • 适用于抽奖程序、随机广告的PHP概率算法实例
  • php编写的抽奖程序中奖概率算法
  • 基于PHP代码实现中奖概率算法可用于刮刮卡、大转盘等抽奖算法
  • php抽奖概率算法(刮刮卡,大转盘)
  • 微信随机生成红包金额算法php版
  • 微信红包随机生成算法php版
  • php实现自定义中奖项数和概率的抽奖函数示例
  • PHP编程实现计算抽奖概率算法完整实例
            
  • 分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    用户反馈
    客户端