【问题标题】:Weightage Logic Implementation权重逻辑实现
【发布时间】:2018-07-19 12:52:21
【问题描述】:

假设我有 4 个广告横幅:

  • 横幅 A - 价格 10 美元
  • 横幅 B - 价格 5 美元
  • 横幅 C - 价格 3 美元
  • 横幅 D - 价格 1 美元

现在的要求是根据权重展示广告。比如横幅 A 出现的时间比横幅 B 多。横幅 B 的出现时间比横幅 C 多,以此类推。

没有限制,例如广告横幅可以显示多少次或横幅可以显示多长时间。当用户刷新屏幕时,他们将获得一个横幅,但基于上述权重。

现在我不确定需要什么样的逻辑或数学公式。我想在 PHP 中构建该逻辑,因此添加 php 标记。

我的想法是我将拥有一个横幅表,并在此基础上根据权重逻辑生成一个队列并一一发送横幅。

【问题讨论】:

  • 如果需要更多细节,请告诉我。
  • 您在存储视图吗?
  • 是的,会这样做的。
  • 数字相加。选择一个介于 1 和总和之间的随机数。如果随机数为 1,则使用第一个广告。如果是 2-4,请使用第二个。等
  • @RakeshaShastri 我发表了评论,而不是答案。我们希望提问者付出一些努力来解决他们自己的问题。 OP 应该借此机会尝试对所提供的策略进行编码。我已经解释得很好,可以开始了。

标签: php math logic


【解决方案1】:

这里是一个例子,剩下的由你来构建:

  • $ads 是您的广告数组(id 和权重),将从活动广告数据库中选择。
  • show_ad 是算法,它将所有广告组合成它们的权重,然后选择一个随机数,然后减去,直到达到最接近的权重,随着时间的推移,这是随机移动的。
  • simulate_views 只是运行了 100 多个视图,向您展示它是加权的。

在获得随机 id 后,您将使用它来获取广告内容。

<?php
// id => weight
$ads = [
    10 => 5,    
    20 => 10,    
    30 => 15    
];

function show_ad($ads) {
    // calculate the total of all weights
    $combined = array_sum($ads);

    // pick a random number from $combined weights
    $random = rand(0, $combined - 1);

    // keep subtracting weight until we drop below an ad weight
    foreach ($ads as $id => $weight) {
        if ($random < $weight) return $id;

        $random -= $weight;
    }

    return $random;
}

function simulate_views($ads, $rounds = 100) {
    $result = [];

    for ($i = 0; $i < $rounds; $i++) {
        $id = show_ad($ads);

        $result[$id] = isset($result[$id]) ? $result[$id]+1: 1;
    }
    return $result;
}

print_r(simulate_views($ads));

一些结果(100 次迭代):

Array
(
    [30] => 56
    [10] => 14
    [20] => 30
)

.

Array
(
    [20] => 35
    [30] => 51
    [10] => 14
)

.

Array
(
    [20] => 32
    [30] => 57
    [10] => 11
)

https://3v4l.org/1Giuc

注意:一定要在 >= PHP7.1 上运行,否则使用 mt_rand。

【讨论】:

    【解决方案2】:

    感谢@Rakesha Shastri 和@Lawrence Cherone,我能够弄明白。

    我所做的是创建了 2 个表。

    CREATE TABLE `ad_banner` (
      `banner_id` int(11) NOT NULL AUTO_INCREMENT,
      `banner_name` varchar(255) NOT NULL,
      `weightage` int(3) NOT NULL,
      `price` decimal(5,2) NOT NULL,
      PRIMARY KEY (`banner_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1
    
    
    CREATE TABLE `ad_banner_queue` (
      `ad_quque_id` int(11) NOT NULL AUTO_INCREMENT,
      `banner_name` varchar(255) NOT NULL,
      `is_sent` tinyint(1) NOT NULL,
      PRIMARY KEY (`ad_quque_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1
    

    之后在 ad_banner 表中添加了一些条目。

    public function actionGeneratequeue(){
        /* First check that there is existing queue, if so don't generate it */
        $data_exist = Yii::app()->db->createCommand()
                    ->select('ad_quque_id')
                    ->from('ad_banner_queue')
                    ->where('is_sent=0')
                    ->queryScalar();
    
        if($data_exist===false){
            /* Fetch all banner */
            $ads = Yii::app()->db->createCommand()
                        ->select('*')
                        ->from('ad_banner')
                        ->queryAll();
    
            if(!empty($ads)){
                foreach($ads as $ad){
                    /* Make entry as per that weightage, example, if weightage is 10 then make entry 10 times */
                    for($i=1;$i<=$ad['weightage'];$i++){
                        $command = Yii::app()->db->createCommand();
                        $command->insert('ad_banner_queue', array(
                            'banner_name' => $ad['banner_name'],
                        ));
                    }
                }
            } else{
                echo "No Banner Found!";
                exit;
            }
        } else{
            echo "Queue already exist";
            exit;
        }
    }
    
    
    /* Fetch banner */
    public function actionFetchbanner(){
        /* Fetch the Random from table */
        $ads_queue = Yii::app()->db->createCommand()
                        ->select('*')
                        ->from('ad_banner_queue')
                        ->where('is_sent=0')
                        ->order('RAND()')
                        ->queryRow();
    
        if($ads_queue===false){
            $this->actionGeneratequeue();
        } 
        /* Now, marked that one as is_sent */
        $command = Yii::app()->db->createCommand();
        $command->update('ad_banner_queue', array(
                    'is_sent'=>1,
        ), 'ad_quque_id=:ad_quque_id', array(':ad_quque_id'=>$ads_queue['ad_quque_id']));
    
        echo "<pre>";print_r($ads_queue);echo "</pre>";exit();
    }
    

    然后简单地调用actionFetchbanner函数。

    【讨论】:

      猜你喜欢
      • 2022-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-20
      相关资源
      最近更新 更多