首页/ 填坑/ 文章详情

PHP 食堂随机点餐

记得那年,青葱的我加入了生鲜水果团队。刚好公司成立不久,正处招兵买马阶段,员工先后有隔壁的老王,一口蹩脚粤语的东北大哥和初入社会装逼十足中二小青年,加上我,公司组成了水果4F天团。

公司的建立正好在生鲜水果赛道初期,给了足够时间让成员磨合。到了中期,赛道的玩家都杀红了眼,每周都推出活动,即要拉新又要留住旧用户,疯狂的让利补贴。推陈出新的活动,导致我们每周任务直接拉满,忙的经常加班加点。导致吃什么时候,不想思考了,不知谁提了一句,要不要我们弄个随机点餐程序。

是的,随机点餐程序其实在那个时候有想法,后来太忙,忙得下班都不想敲代码。再后来公司压中了新晋赛道,直接腾飞。忙变得更忙了,人员的增多,公司整体气氛变得浮燥,直到离开公司未能完成该项目。

需求始终存在,不经意间一次交流,遗忘的记忆终归唤醒。在编写程序前,先介绍下食堂情况:10元任点3样菜,白饭任加,例汤任喝。需要随机的是3样菜式,根据菜的类型,分别为:大荤、小荤和素菜

食堂菜谱:

PHP$data = array(
    '0' => array( 'id' => 0, 'name' => '百味结红烧肉','type'=> 0, 'status' => 1,'weight' => 1),
    '1' => array( 'id' => 1, 'name' => '红烧排骨','type'=> 0, 'status' => 1,'weight' => 1),
    '2' => array( 'id' => 2, 'name' => '回锅肉','type'=> 0, 'status' => 1,'weight' => 1),
    '3' => array( 'id' => 3, 'name' => '糖醋排骨','type'=> 0, 'status' => 1,'weight' => 1),
    '4' => array( 'id' => 4, 'name' => '四喜肉','type'=> 0, 'status' => 1,'weight' => 1),
    '5' => array( 'id' => 5, 'name' => '炸鸡翅','type'=> 0, 'status' => 1,'weight' => 1),
    '6' => array( 'id' => 6, 'name' => '口水鸡','type'=> 0, 'status' => 1,'weight' => 1),
    '7' => array( 'id' => 7, 'name' => '酱鸭','type'=> 0, 'status' => 1,'weight' => 1),
    '8' => array( 'id' => 8, 'name' => '板栗鸡块','type'=> 0, 'status' => 1,'weight' => 1),
    '9' => array( 'id' => 9, 'name' => '炸鸡腿','type'=> 0, 'status' => 1,'weight' => 1),
    '10' => array( 'id' => 10, 'name' => '剁椒青鱼','type'=> 0, 'status' => 1,'weight' => 1),
    '11' => array( 'id' => 11, 'name' => '水煮鱼片','type'=> 0, 'status' => 1,'weight' => 1),
    '12' => array( 'id' => 12, 'name' => '芝麻鱼肉','type'=> 0, 'status' => 1,'weight' => 1),
    '13' => array( 'id' => 13, 'name' => '清蒸鱼段','type'=> 0, 'status' => 1,'weight' => 1),
    '14' => array( 'id' => 14, 'name' => '咸菜烧带鱼','type'=> 0, 'status' => 1,'weight' => 1),

    '15' => array( 'id' => 15, 'name' => '肉末粉皮','type'=> 1, 'status' => 1,'weight' => 1),
    '16' => array( 'id' => 16, 'name' => '肉末茄子','type'=> 1, 'status' => 1,'weight' => 1),
    '17' => array( 'id' => 17, 'name' => '烂糊肉丝','type'=> 1, 'status' => 1,'weight' => 1),
    '18' => array( 'id' => 18, 'name' => '黄瓜炒蛋','type'=> 1, 'status' => 1,'weight' => 1),
    '19' => array( 'id' => 19, 'name' => '番茄炒蛋','type'=> 1, 'status' => 1,'weight' => 1),
    '20' => array( 'id' => 20, 'name' => '豇豆肉丝','type'=> 1, 'status' => 1,'weight' => 1),
    '21' => array( 'id' => 21, 'name' => '笋丝雪菜肉丝','type'=> 1, 'status' => 1,'weight' => 1),
    '22' => array( 'id' => 22, 'name' => '百叶包','type'=> 1, 'status' => 1,'weight' => 1),
    '23' => array( 'id' => 23, 'name' => '青椒肉丝','type'=> 1, 'status' => 1,'weight' => 1),
    '24' => array( 'id' => 24, 'name' => '花菜肉片','type'=> 1, 'status' => 1,'weight' => 1),
    '25' => array( 'id' => 25, 'name' => '平菇炒鸡片','type'=> 1, 'status' => 1,'weight' => 1),
    '26' => array( 'id' => 26, 'name' => '干烧豇豆','type'=> 1, 'status' => 1,'weight' => 1),
    '27' => array( 'id' => 27, 'name' => '玉米鸡丁','type'=> 1, 'status' => 1,'weight' => 1),

    '28' => array( 'id' => 28, 'name' => '红烧冬瓜','type'=> 2, 'status' => 1,'weight' => 1),
    '29' => array( 'id' => 29, 'name' => ' 红烧豆腐','type'=> 2, 'status' => 1,'weight' => 1),
    '30' => array( 'id' => 30, 'name' => ' 炒白菜','type'=> 2, 'status' => 1,'weight' => 1),
    '31' => array( 'id' => 31, 'name' => ' 炒冬瓜 ','type'=> 2, 'status' => 1,'weight' => 1),
    '32' => array( 'id' => 32, 'name' => '粉丝包菜 ','type'=> 2, 'status' => 1,'weight' => 1),
    '33' => array( 'id' => 33, 'name' => '土豆青椒丝','type'=> 2, 'status' => 1,'weight' => 1),
    '34' => array( 'id' => 34, 'name' => '青椒炒香干','type'=> 2, 'status' => 1,'weight' => 1),
    '35' => array( 'id' => 35, 'name' => '香菜粉皮','type'=> 2, 'status' => 1,'weight' => 1),
    '36' => array( 'id' => 36, 'name' => '油焖茄子','type'=> 2, 'status' => 1,'weight' => 1),
    '37' => array( 'id' => 37, 'name' => '剁椒包菜 ','type'=> 2, 'status' => 1,'weight' => 1),
    '38' => array( 'id' => 38, 'name' => '蒜泥炒白菜','type'=> 2, 'status' => 1,'weight' => 1),
); 

 不同的人,有不同的口味。有些菜别人无法接受,拒绝尝试,status状态控制菜是否加入菜谱;有些菜有别人喜欢吃,恨不得天天都吃上一口,weight权重控制菜出现频次。随机点餐的核心算法不言而喻:随机权重算法。 

不要小看随机权重算法,曾用该方法开发过抽奖游戏,维持老用户不离不弃。简单来说,该算法简单易懂,实用。扯远了,继续回归主题。考虑到人的口味,预设模式:肉食主义、均衡主义和素食主义

Food 随机权重类

PHPclass Food {
    private static $model = array(
        'meat' => array(
            '0' => array('id'=> 0,'type'=>'大荤','weight'=>100),
            '1' => array('id'=> 1,'type'=>'小荤','weight'=>0),
            '2' => array('id'=> 2,'type'=>'素菜','weight'=>0),
        ),
        'balance' => array(
            '0' => array('id'=> 0,'type'=>'大荤','weight'=>10),
            '1' => array('id'=> 1,'type'=>'小荤','weight'=>80),
            '2' => array('id'=> 2,'type'=>'素菜','weight'=>10),
        ),
        'vegetable' => array(
            '0' => array('id'=> 0,'type'=>'大荤','weight'=>0),
            '1' => array('id'=> 1,'type'=>'小荤','weight'=>0),
            '2' => array('id'=> 2,'type'=>'素菜','weight'=>100),
        )
    );

    public function __construct(){

    }

    /**
     * 获取随机模式数据
     * @method getModel
     * @param {String} $key 关键字
     * @return Array
     */
    private static function getModelData($key) {
        return self::$model[$key];
    }

    /**
     * 重构随机数组
     * @method resetRandData
     * @param {Array} $data 数组
     * @param {String} $field 字段
     * @return Array
     */
    private static function resetRandData($data, $field = 'weight') {
        foreach ($data as $key => $value) {
            $arr[$key] = $value[$field];
        }

        return $arr;
    }

    /**
     * 获取随机数下标
     * @method getRand
     * @param {Array} $data 数组
     * @return int|string
     */
    private static function getRandSub($data) {
        $result = '';
        $total = array_sum($data); //计算数组中元素的和

        //概率数组循环
        foreach ($data as $key => $value) {
            $num = mt_rand(1, $total);
            if ($num <= $value) { //如果这个随机数小于等于数组中的一个元素,则返回数组的下标
                $result = $key;
                break;
            } else {
                $total -= $value;
            }
        }

        unset ($data);
        return $result;
    }

    /**
     * 获取模式
     * @method getModel
     * @param {String} $key 关键字
     * @return Array
     */
    public static function getModel($key) {
        $data = self::getModelData($key);
        $rand = self::resetRandData($data);
        $index = self::getRandSub($rand);

        return $data[$index];
    }


    /**
     * 获取随机食物
     * @method getRandFood
     * @param {Array} $data 数组
     * @param {String} $type 菜的类型
     * @return  Array
     */
    public static function getRandFood($data, $type) {
        $tmp = [];
        foreach ($data as $key => $value) {
            if($value['type'] == $type && $value['status'] == 1) {
                array_push($tmp,$value);
            }
        }

        $rand = self::resetRandData($tmp);
        $index = self::getRandSub($rand);

        return $tmp[$index];
    }

    /**
     * 获得点餐
     * @method getOrder
     * @param {Array} $data 数组
     * @param {String} $type 菜的类型
     * @param {Nubmer} $num
     * @return String
     */
    public static function getOrder($data, $type, $num = 2) {
        $result = '';
        for($i = 0; $i < $num; $i++) {
            $item = self::getRandFood($data,$type);
            $data = self::removeData($data,$item['id']);
            $result .= $item['name'].',';
        }

        return trim($result,',');
    }

    /**
     * 移除数组
     * @method removeData
     * @param {String} $data 数组
     * @param {String} $id 菜id
     * @return mixed
     */
    private static function removeData($data, $id) {
        foreach($data as $key => $value) {
            if($value['id'] == $id) {
                array_splice($data, $key, 1);
                break;
            }
        }

        return $data;
    }
}

 在随机点菜前,先分下大类,再从菜谱选菜,保证每个菜式不重样。 

PHP$key = 'balance';
$model = Food::getModel($key);
$result = Food::getOrder($data, $model['id'],3);

print_r('K酱食堂开业了
');
print_r('10元3菜任点,白饭任加

');
print_r('今天中午准备吃:');
print_r($result);
 随机模式设置均衡主义,有时出现点了三个大荤,出人意料啊!随机权重点餐投产前还需要多调整权重下,降低/抬高某个大类的权重。除了权重微调外,食堂有个不可避免的状况,食堂每日售卖的菜品,需要额外实时调整数据。 

文章评论0 records

最新 最早

0

最新评论Latest comments

big2catbig2cat 08-27 16:11
然而没什么用,smartpss不兼容老录像机,就算能看回放,很多时间点在回放里也看不到
HentaiCatHentaiCat 2020-12-30 10:22
考科目二全程很紧张,考了三次才过,有次侧方入库直接pass,100分扣完,呜呜呜~
猫猫酱猫猫酱 2020-11-12 10:56
一入多肉深似海,说多都是泪
soulkunsoulkun 2020-11-05 15:54
IconFont的图标真的很好用!!!
无限链霉球菌无限链霉球菌 2020-11-03 11:41
药店,了解一下(`・ω・´)