php - Advertisement System Tips -
i creating advertisement system shows highest bidder's ads more frequently.
here example of table structure using, simplified...
+----+----------+------------------------+----------------------+-----+ | id | name | image | destination | bid | +----+----------+------------------------+----------------------+-----+ | 1 | abc, co | htt.../blah | htt...djkd.com/ | 3 | +----+----------+------------------------+----------------------+-----+ | 2 | facebook | htt.../blah | htt...djkd.com/ | 200 | +----+----------+------------------------+----------------------+-----+ | 3 | google | htt.../blah | htt...djkd.com/ | 78 | +----+----------+------------------------+----------------------+-----+
now, right selecting values database , inserting them array , picking 1 out random similar following:
$ads_array = []; $ads = ad::where("active", "=", 1)->orderby("price", "desc"); if ($ads->count() > 0) { $current = 0; foreach ($ads->get() $ad) { ($i = 0; $i <= ($ad->price == 0 ? 1 : $ad->price); $i++) { $ads_array[$current] = $ad->id; $current++; } } $random = rand(0,$current-1); $ad = ad::where("id", "=", $ads_array[$random])->first(); ... }
so, doing is, inserting advert's id array 1*$bid
times. inefficient, sadly (for obvious reasons), best way think of doing this.
is there better way of picking out random ad database; while still giving higher bidders higher probability of being shown?
looks might trick (but credit go guy in comments)
select ads.* ads order -log(1.0 - rand()) / ads.bid limit 1
a script test :
<?php $pdo = new pdo('mysql:host=localhost;dbname=test;', 'test', 'test'); $times = array(); // repeat lot have real values ($i = 0; $i < 10000; $i++) { $stmt = $pdo->query('select ads.* ads order -log(1.0 - rand()) / bid limit 1'); $bid = $stmt->fetch()['bid']; if (isset($times[$bid])) { $times[$bid] += 1; } else { $times[$bid] = 1; } } // echoes number of times 1 bid represented var_dump($times);
the figures comes me out of test pretty :
// key bid, value number of times bid represented array (size=3) 200 => int 7106 78 => int 2772 3 => int 122
further reference on mathematical explanation
many important univariate distributions can sampled inversion using simple closed form expressions. of useful ones listed here.
example 4.1 (exponential distribution). standard exponential distribution has density f(x) = e−x on x > 0. if x has distribution, e(x) = 1, , write x ∼ exp(1). cumulative distribution function f(x) = p(x x) = 1 − e−x, f−1(u) = −log(1 − u). therefore taking x = − log(1 − u ) u ∼ u(0, 1), generates standard exponential random variables. complementary inversion uses x = − log(u ).
the exponential distribution rate λ > 0 (and mean θ = 1/λ) has pdf λexp(−λx) 0 x < ∞. if x has distribution, write x ∼ exp(1)/λ or equivalently x ∼ θexp(1), depending on whether problem more naturally formulated in terms of rate λ or mean θ. may generate x taking x = − log(1 − u )/λ.
coming http://statweb.stanford.edu/~owen/mc/ch-nonunifrng.pdf