Heim >Backend-Entwicklung >PHP-Tutorial >PHP-Probabilistischer Zufallslotteriefall

PHP-Probabilistischer Zufallslotteriefall

墨辰丷
墨辰丷Original
2018-06-05 14:56:501525Durchsuche

In diesem Artikel wird hauptsächlich der Fall der PHP-Wahrscheinlichkeitslotterie vorgestellt. Ich hoffe, dass er für alle hilfreich ist.

1. Ausgangsdaten:

Je größer das Gewicht, desto höher die Chance auf eine Verlosung
[Preis 1, Gewicht 5], [Preis 2, Gewicht 6], [Preis 3, Gewicht 7], [Preis 4, Gewicht 2]

2. Verarbeitungsschritte:

1) N = 5 + 6 + 7 + 2 = 20
2) Dann nimm eine 1-N Zufallszahl M
3) Definiere den Gewichtsbereich jedes Preises Preis 1: 1-5; Preis 3: 12-18; 20
4) Wenn M im Gewichtsbereich eines Preises liegt, geben Sie an, dass der Preis ausgelost wurde

<?php
/**
 * 奖品
 */
class Prize {
  # ID
  public $id = null;
  # 权重
  public $weight = null;
  # 奖品名
  public $name = null;
 
  # 权重范围区间起始值
  protected $start = 0;
  # 权重范围区间结束值
  protected $end = 0;
 
  public function __construct($id, $weight, $name) {
    if (!$id) {
      throw new Exception(&#39;奖品ID为空.&#39;);
    }
    $this->id = $id;
    $this->weight = $weight ? $weight : 0;
    $this->name = $name ? $name : &#39;随机奖品&#39; . $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 <= $this->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(&#39;奖池未初始化&#39;);
    }
 
    if ($poll->count() <= 0) {
      throw new Exception(&#39;奖池为空&#39;);
    }
 
    $items = $poll->getVisibleItems();
    if (count($items) <= 0) {
      throw new Exception(&#39;奖池为空&#39;);
    }
 
    $sum = 0;
    foreach ($items as $item) {
      $start = $sum + 1;
      $sum += $item->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);
}

Zusammenfassung : Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, er wird für das Studium aller hilfreich sein.

Verwandte Empfehlungen:

Zusammenfassung zur Verwendung der OpenSSL-Verschlüsselungserweiterung von PHP

Detaillierte Erklärung des 301-Redirect-Jump-Beispiels basierend auf PHP

Analyse einfangender und nicht einfangender Gruppen in regulären PHP-Ausdrücken

Das obige ist der detaillierte Inhalt vonPHP-Probabilistischer Zufallslotteriefall. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn