2

1か月を通して広告を均等に表示するインプレッションに基づいて、広告バナーローテーションスクリプトの作成に取り組んでいます。計算は、広告の表示が要求されるたびに実行されます。したがって、これはオンザフライで実行されます。広告は次々と回転して表示され、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

最高のJOBには、最高のタイプのアルゴリズムを使用する必要があると思います。そのような実装方法については、いくつかの可能性のみを示します。

私の現在の例は、

実装することもできます

  • プライオリーベースのシャッフル
  • タイムベースシャッフル
  • パーセンテージ
  • シャッフルをクリックします

シンプルな概念実証

// 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の4つの広告を考えてみましょう。これらはすべて、1,000インプレッションを支払いましたが、これまでのところ、Aは不運でゼロになり、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に等しくなります。

$rand1から201までの任意の数にすることができます。141としましょう。

この場合、ループを開始します。

  • $rand -= 100、今は41です。41は真実であり、広告が残っています。
  • $rand -= 50、今は-9です。ゼロに達したので、ループを終了します。

$winner1で、これは広告Bです。

于 2012-12-04T18:42:52.987 に答える