2

我正在构建一个基于展示次数的广告横幅轮换脚本,该脚本在整个月内均匀地展示广告。每次请求显示广告时都会进行计算。所以这将在飞行中完成。广告应该一个接一个地轮播,而不是只展示一个广告 1000 次展示,然后另一个广告展示 1000 次展示。它在大多数情况下应该显示 1 次展示,然后切换广告(当然,除非一个广告的展示次数比另一个要多得多)。

假设我有 5 个广告,每个广告的购买次数都不同,那么公式是什么/您如何投放广告?我正在寻找在 PHP 中执行此操作。

广告 #1:1,000 次购买的展示次数

广告 #2:购买了 12,000 次展示

广告 #3:购买了 3,000 次展示

广告 #4:购买了 20,000 次展示

广告 #5:10,000 次购买的展示次数

如果有多个广告在同一时间范围内购买了 1000 次展示,则应该一个接一个地展示,直到展示次数用完为止。不过,我认为如果一个人在短时间内购买 1000 次展示可能会很好,我应该考虑到这一点并以更快的速度展示它们。我愿意接受建议。

4

2 回答 2

7

我认为你应该为最好的工作使用最好的算法类型我只会向你展示一些关于如何实现这样的可能性

我当前的示例将显示使用

你也可以实现

  • 基于修道院的洗牌
  • 时基随机播放
  • 百分比
  • 单击随机播放
  • ETC

简单的概念证明

// Create Add Infroamtion
$ads = array();
$ads[] = new Ad(10, "A.jpg", 2);
$ads[] = new Ad(12, "B.gif", 3);
$ads[] = new Ad(30, "C.png", 7);
$ads[] = new Ad(20, "D.swf", 5);

// Add ads to banner
$banner = new Banner($ads);

// You can also add addional ads
$banner->add(new Ad(10, "E.swf"));

echo "<pre>";

//Lets Emulate first 100 rotations 
for($i = 0; $i < 1000; $i ++) {
    // Select Algorithm
    $banner->randomise("ratioShuffle");

    // Display Add
    echo $banner->getDisplay(), PHP_EOL;
}

可以使用的简单随机播放功能

function fisherYatesShuffle(array &$items) {
    for($i = count($items) - 1; $i > 0; $i --) {
        $j = @mt_rand(0, $i);
        $tmp = $items[$i];
        $items[$i] = $items[$j];
        $items[$j] = $tmp;
    }
}

function robinShuffle(array &$items) {
    usort($items, function ($a, $b) {
        $a = $a->getDisplay();
        $b = $b->getDisplay();
        return $a == $b ? 0 : ($a < $b ? - 1 : 1);
    });
}

function ratioShuffle(array &$items) {
    static $called = false;
    if ($called === false) {
        $ads = array();
        foreach ( $items as &$ad ) {
            for($i = 0; $i < $ad->getRatio(); $i ++) {
                $ads[] = $ad;
            }
        }
        $called = true;
        $items = $ads;
    }
    shuffle($items);
}

使用的类

class Ad implements JsonSerializable {
    private $impressions;
    private $media;
    private $ratio = 1;
    private $display = 0;

    function __construct($impressions, $media = null, $ratio = 1) {
        $this->impressions = $impressions;
        $this->media = $media;
        $this->ratio = $ratio;
    }

    function torch() {
        $this->impressions --;
        $this->display ++;
    }

    public function getImpression() {
        return $this->impressions;
    }

    public function getDisplay() {
        return $this->display;
    }

    public function getRatio() {
        return $this->ratio;
    }

    public function getMeadia() {
        return $this->media;
    }

    public function __toString() {
        return json_encode($this->jsonSerialize());
    }

    public function jsonSerialize() {
        return get_object_vars($this);
    }
}


class Banner implements Countable, JsonSerializable {
    private $totalImpressions;
    private $ads = array();

    function __construct(array $ads) {
        foreach ( $ads as $ad )
            $this->add($ad);
    }

    public function add(Ad $ad) {
        $this->ads[] = $ad;
        $this->totalImpressions += $ad->getImpression();
    }

    public function randomise($function = null) {
        if (is_callable($function, false, $callable_name)) {
            return $callable_name($this->ads);
        } else {
            return shuffle($this->ads);
        }
    }

    public function getDisplay() {
        foreach ( $this->ads as &$ad ) {
            if ($ad->getImpression() < 1) {
                unset($ad);
                continue;
            }
            $ad->torch();
            break;
        }
        return isset($ad) ? $ad : null;
    }

    public function jsonSerialize() {
        $array = $this->ads;
        foreach ( $array as &$ad ) {
            $ad = $ad->jsonSerialize();
        }
        return $array;
    }

    public function __toString() {
        return json_encode($this->jsonSerialize());
    }

    function count() {
        return count($this->ads);
    }
}

如您所见,这是一个示例....尝试使您的解决方案灵活

于 2012-12-04T20:40:52.083 回答
2

就个人而言,我会计算出每个广告获得的展示次数与付费次数的百分比,并将其用作它不会出现的机会。像这样的东西:

$show = Array();
foreach($ads as $id=>$ad) {
    $show[$id] = ceil((1-$ad['impressions']/$ad['paid'])*100);
}
$total = array_sum($show);
$rand = rand(1,$total);
$winner = -1;
do {$rand -= array_shift($show); $winner++;} while($rand && $show);
$ad_to_display = $ads[$winner];

例如,考虑四个广告,A、B、C 和 D。它们都支付了 1,000 次展示,但到目前为止 A 运气不佳并获得了 0 次展示,而 B 和 C 都获得了 500 次展示,而 D 获得了 999 次展示.

这意味着$show广告具有以下值:

A: ceil((1-0/1000)*100) = 100
B: ceil((1-500/1000)*100) = 50
C: ceil((1-500/1000)*100) = 50
D: ceil((1-999/1000)*100) = 1

$total因此等于 201。

$rand可以是 1 到 201 之间的任何数字(包括 1 到 201)。比如说141。

在这种情况下,我们开始我们的循环:

  • $rand -= 100,现在是 41。41 是真实的,我们还有广告。
  • $rand -= 50,现在是-9。它已经达到零,所以结束循环。

$winner1,即广告 B。

于 2012-12-04T18:42:52.987 回答