创建横幅交换算法来旋转广告

时间:2012-12-04 18:32:21

标签: php algorithm advertising banner

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

假设我有5个广告,每个广告都有不同的展示次数,公式是什么/您如何投放广告?我希望这样做PHP。

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

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

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

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

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

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

2 个答案:

答案 0 :(得分:7)

我认为你应该使用最好的算法来获得最好的JOB我只会告诉你如何实现这样的一些可能性

我当前的示例将使用

显示

您也可以实施

  • Priory Based shuffle
  • Time Base Shuffle
  • 百分比
  • 点击随机播放
  • 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);
    }
}

正如您所看到的,这是一个示例....只是尝试使您的解决方案变得灵活

答案 1 :(得分: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.所有这些广告都支付了1000次展示,但到目前为止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之间的任意数字。让我们说141。

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

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

$winner为1,即广告B。