根据销量随机分布的合理算法

这里先上图,然后我会说需求和我的做法,当然我的做法很low,感觉属于最简单的那种想法。所以贴出来想要优化一下

function virtualSalesByProvince($product_id, $sale)
{
    if(!StoreProduct::be($product_id)){
        return false;
    };
    if($sale <= 0){
        return false;
    }

    if(Cache::has('product_province_virtual_sale_'.$product_id)){//查看是否有缓存
        $sale_amount = json_decode(Cache::get('product_province_virtual_sale_'.$product_id),true);
    }else{
        $sale_amount = [];
        $system_city = SystemCity::where('level',0)->column('point');
        foreach ($system_city as $v){
            $sale_amount[$v] = 0;
        }
    }
    $system_count = count($sale_amount);
    $sale_old = array_sum($sale_amount);
    if($sale_old == $sale){
        return $sale_amount;
    }

    if($sale_old < $sale){
        $sale_diff = $sale - $sale_old;
        if($sale_diff > $system_count){
            $limit = mt_rand(1,$system_count);
        }else{
            $limit = mt_rand(1,$sale_diff);
        }

        $system_city_selected = SystemCity::where('level',0)->orderRaw('rand()')->limit($limit)->column('point');//随机获取对应省
        $data = self::saleRand($sale_diff,$limit,1,$sale_diff);

        foreach ($system_city_selected as $k=>$v){
            $sale_amount[$v] = $sale_amount[$v] + $data[$k];
        }
        Cache::set('product_province_virtual_sale_'.$product_id,json_encode($sale_amount));
    }
    return $sale_amount;
}

需求:

他要做的是根据商品和销量,随机排列到34个省份(这里只涉及到省)。同一个商品,当销量一致时返回一个结果,保证每次返回结果是一样的。当销量增加时,增加的销量再次随机分配到34个省份中,然后保存起来

我的做法

每次销量sale和商品product_id传给我时,我会先判断有没有这个的缓存,
(1)如果没有先初始化,初始化的原则是从城市表里取出省份id,然后以省份id为键,值统一为0

$system_city = SystemCity::where('level',0)->column('point');
        foreach ($system_city as $v){
            $sale_amount[$v] = 0;
}

(2)如果缓存存在则取出来,将数组值相加,然后判断总数和传入的sale的大小
如果差值sale_diff 大于数值34,也就是34个省份,从1-34随机取值,命名变量limit
如果插值sale_diff 小于数值34,从1-sale_diff随机取值limit

  $system_count = count($sale_amount);
  $sale_old = array_sum($sale_amount);
  if($sale_old == $sale){
      return $sale_amount;
  }

  $sale_diff = $sale - $sale_old;
  if($sale_diff > $system_count){
      $limit = mt_rand(1,$system_count);
  }else{
      $limit = mt_rand(1,$sale_diff);
  }

ps:问题主要就是出现在这里,一会儿我会单独描述
(3)根据随机变量Limit从省分表随机取出limit个值。得到的省份就是销量差值要分配的省份了

 $system_city_selected = SystemCity::where('level',0)->orderRaw('rand()')->limit($limit)->column('point');//随机获取对应省

问题

问题就是这个limit,永远都是从1-某个值,最大是34.会出现销量为100是,随机出个1,或者2.全国只有这个省份在买么,感觉数据就假了

颠倒的玉石
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
最佳答案
$sale_diff = 20;
// 向上取整平均销量
$avg = ceil($sale_diff / 36); 

$sale_arr = array();

for ($i = 0; $i < 36; $i++) {

    // 销量为0情况
    if ($sale_diff <= 0) {
        $sale_arr[$i] = 0;
        continue;
    }

    // 本次增加销量
    $sum = $avg;

    // 随机销量
    $rand = 0;
    // 是否加上随机销量
    if (rand(0, 100) % 2 == 0) {
       // 这里随机可以根据实际情况做调整 也可以选择不增加随机销量
       $rand = rand(1, $sale_diff);  
    }

    // 是否增加随机销量
    if ($i % 2 == 0) {
        $sum += $rand;
    } 

    // 剩余销量不足情况
    if ($sale_diff <= $sum) {
       $sum = $sale_diff;
       $sale_diff = 0;
    }
    $sale_arr[$i] = $sum;

    $sale_diff -= $sum;
}
shuffle($sale_arr); // 打乱数组
echo "<pre>";
print_r($sale_arr);

写过一个类似的,可以做参考,随机销量我当初是作为一个偏差值,使得每个随机都不是平均值,更为好看

3年前 评论
颠倒的玉石 (楼主) 3年前
讨论数量: 3
颠倒的玉石

写的太繁琐了,所以没有人理么 :joy: :joy: :joy:

3年前 评论

代码用截图,所以没人理吧

3年前 评论
颠倒的玉石 (楼主) 3年前
$sale_diff = 20;
// 向上取整平均销量
$avg = ceil($sale_diff / 36); 

$sale_arr = array();

for ($i = 0; $i < 36; $i++) {

    // 销量为0情况
    if ($sale_diff <= 0) {
        $sale_arr[$i] = 0;
        continue;
    }

    // 本次增加销量
    $sum = $avg;

    // 随机销量
    $rand = 0;
    // 是否加上随机销量
    if (rand(0, 100) % 2 == 0) {
       // 这里随机可以根据实际情况做调整 也可以选择不增加随机销量
       $rand = rand(1, $sale_diff);  
    }

    // 是否增加随机销量
    if ($i % 2 == 0) {
        $sum += $rand;
    } 

    // 剩余销量不足情况
    if ($sale_diff <= $sum) {
       $sum = $sale_diff;
       $sale_diff = 0;
    }
    $sale_arr[$i] = $sum;

    $sale_diff -= $sum;
}
shuffle($sale_arr); // 打乱数组
echo "<pre>";
print_r($sale_arr);

写过一个类似的,可以做参考,随机销量我当初是作为一个偏差值,使得每个随机都不是平均值,更为好看

3年前 评论
颠倒的玉石 (楼主) 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!