优惠券最优使用算法

先说一下业务背景。公司做的一个投资的APP,投资金额可以用优惠券抵扣。红包面额(100,50,30,10)

优惠券使用规则:

  • 优先使用大面额的红包,即优先使用张数最少的红包组合

  • 优先使用有限制的红包,即优先使用有限制红包张数占比最大的组合

  • 优先使用即将过期的红包,即优先使用平均有效期最短的组合

  • 选择红包面额之和最大的组合(面额总值≤投资额*1%)

算法尝试

前面三个都可以通过数据库检索排序实现生成一个数组,最后一个就要使用程序算法实现了。一开始有想过背包法、穷举法。

  • 背包法:说实在的,没看懂(比较尴尬),实现是可以实现。但是无法获取具体使用了哪张优惠券(简单就是很难获得优惠券的Id)

  • 穷举法:数据太多,不可控。

优惠券最优算法1.0

算出用户本次投资最大使用优惠券总额(redAmount)、获取用户的优惠券列表(redCoupons)(已按前三规则排序)直接上代码:

    public function dealCoupon()
    {
        $redCoupons =[]; $restRedAmount = 100;

        $redCouponIdLists = []; $restRedAmounts = [];
        $arrCount = count($redCoupons);
        for ($i=0; $i<$arrCount; $i++) {
            list($redCouponIdList, $restRedAmount) = getBestCoupon($redCoupons, $restRedAmount);
            if ($restRedAmount == 0) {
                $bestCouponIdList = $redCouponIdList;
                break;
            }

            $redCouponIdLists[] = $redCouponIdList;
            $restRedAmounts[] = $restRedAmount;
            array_shift($redCoupons);
        }

        if (empty($bestCouponIdList)) {
            $pos = array_search(min($restRedAmounts), $restRedAmounts);
            $bestCouponIdList = $redCouponIdLists[$pos];
        }

    }

    /**
     * 红包最优算法
     */
    private function getBestCoupon($redCoupons, $restRedAmount)
    {
        $redCouponAmount = 0;
        foreach ($redCoupons as $redCoupon) {
            if ($restRedAmount >= $redCoupon->getAmount()) {
                $redCouponAmount   = $redCouponAmount + $redCoupon->getAmount());
                $redCouponIdList[] = $redCoupon->getCouponId();
                $restRedAmount     = $restRedAmount - $redCoupon->getAmount();

                if ($restRedAmount == 0) break;
            }
        }

        return [$redCouponIdList, $restRedAmount];
    }

实例解析:用户投资9000,用户有优惠券(50,30,30,30,30)

  • 用50块尝试,最多80

  • 用第一个30尝试,最多90,已经最优,中断程序(否则继续向下类推)

问题

  • 因为每次算完就把该红包从数组中推出,这样还是存在问题。例如投资1600,用户有(100,50,30,30)。这样就不会出现最优。

解决(算法2.0)

  • 不把计算过优惠券推出,需要每次把要计算那张优惠券单独拿出来

  • 这样程序复杂了很多,但还是可以实现的

  • 这样还是会出现算法1.0的问题,不过这种按照顺序取优惠券很难不出现问题。但是这种面额的优惠券出现几率几乎没有

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!针对O2O优惠券使用预测的问,您可以考虑使用机器学习算法来进行预测。以下是一个简单的预测流程: 1. 数据收集:收集O2O优惠券使用的历史数据,包括用户的消费行为、领取优惠券的情况以及优惠券的属性等信息。 2. 数据预处理:对收集到的数据进行清洗和处理,包括处理缺失值、异常值和重复值等,同时进行特征工程,从原始数据中提取有用的特征。 3. 特征选择:根据问的具体情况,选择合适的特征进行建模,可以考虑用户的历史消费情况、优惠券的属性、用户的个人信息等。 4. 模型选择和训练:选择适合的机器学习模型进行训练。常用的模型包括逻辑回归、决策树、随机森林、支持向量机等。可以使用交叉验证等技术来评估模型性能并选择最佳模型。 5. 模型评估和优化:使用测试集对训练好的模型进行评估,评估指标可以包括准确率、召回率、F1值等。如果模型表现不佳,可以考虑调整模型参数或者尝试其他模型。 6. 使用模型进行预测:使用训练好的模型对新数据进行预测,可以根据用户的消费行为、优惠券属性等信息,预测用户是否会使用优惠券。 需要注意的是,预测的准确性可能会受到数据质量和特征选择的影响,因此在进行预测之前,确保数据的质量和特征的有效性非常重要。另外,不同业务场景下可能需要调整模型和特征选择的方法,具体情况需要根据实际需求进行调整。希望这些信息对您有所帮助!如果还有其他问,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值