You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于商品数量折扣的家电采购策略优化及代码改进问询

家电采购折扣优化问题

折扣规则

商店按单次购买的商品数量提供如下阶梯折扣:

  • 购买2件:该组内最低价商品享25%折扣
  • 购买3件:该组内最低价商品享55%折扣
  • 购买4件:该组内最低价商品享80%折扣
  • 购买5件:该组内最低价商品享99%折扣

需求目标

确定最优采购分组策略,最大化总折扣节省(即最小化采购总成本)。例如:

  • 采购5件时,对比「一次性买5件」和「分2件+3件两次购买」哪种更划算
  • 采购多件商品(如A、B、C、D、E)时,需遍历所有可能的分组组合(如[(A,B),(C,D,E)]、[(A,B),(C,D),E]等),筛选出总节省最高的方案

原代码实现

from itertools import combinations

products = {
    'fridge': 3009,
    'washing_machine': 1449,
    'stove': 2299.99,
    'dish_washer': 1599,
    'tv': 3999,
    'oven': 1899
}


def get_discount(n_products: int) -> float:
    discounts = {
        1: 0.,
        2: .25,
        3: .55,
        4: .8,
        5: .99
    }
    return discounts[n_products]


def get_prices(in_products: list) -> list:
    prices = []
    for i in range(len(in_products)):
        prices.append(products[in_products[i]])
    return sorted(prices,)


def get_best_pair(products: dict, n_products: int) -> tuple:
    max_saved = -9999
    best_pair = None
    best_discount = None

    for pair in combinations(products.keys(), n_products):
        prices = get_prices(pair)
        discount = get_discount(n_products)

        tot_price = sum(prices)
        prices[0] -= prices[0] * discount
        tot_discounted_price = sum(prices)
        saved = tot_price - tot_discounted_price

        if saved > max_saved:
            max_saved = saved
            best_pair = pair
            best_discount = tot_discounted_price

        print(pair, prices, tot_price, tot_discounted_price, saved, max_saved)

    return best_pair, max_saved, best_discount


n_products = 5
results = {}

for i in range(2, n_products + 1):
    to_buy = products.copy()
    buy_strategy = []
    tot_saved = 0.
    tot_price = 0.

    print(f'{i}, to buy: {to_buy}, products: {products}')
    best_pair, saved, best_discount = get_best_pair(to_buy, i)

    buy_strategy.append(best_pair)
    tot_price += best_discount
    tot_saved += saved

    for product in best_pair:
        to_buy.pop(product)

    if len(to_buy) == 1:
        buy_strategy.append(*(to_buy.keys()))
        tot_price += [*to_buy.values()][0]

    print(f'Best combination for: {best_pair}, total discounted price: {tot_price}, tot saved: {saved}')

    left_to_buy = to_buy.copy()
    if len(left_to_buy) >= 2:
        for j in range(2, len(left_to_buy) + 1):
            left_to_buy = to_buy.copy()
            left_to_buy_strategy = buy_strategy.copy()
            left_to_buy_tot_price = tot_price
            left_to_buy_tot_saved = tot_saved

            print(f'{j}, to buy: {to_buy}, left to buy: {left_to_buy}')
            best_pair, saved, best_discount = get_best_pair(left_to_buy, j)

            left_to_buy_strategy.append(best_pair)
            left_to_buy_tot_price += best_discount
            left_to_buy_tot_saved += saved

            print(f'Best combination for: {best_pair}, total discounted price: {best_discount}, tot saved: {saved}')

            for product in best_pair:
                left_to_buy.pop(product)

            if len(left_to_buy) == 1:
                print(f'left to buy: {left_to_buy}, price: {[*left_to_buy.values()][0]}')
                left_to_buy_strategy.append([*left_to_buy.keys()][0])
                left_to_buy_tot_price += [*left_to_buy.values()][0]

            strategy_key = 'buy_strategy' + str(i) + str(j)
            results[strategy_key] = buy_strategy

            sep = '-' * 15 + '\n'
            print(f'{sep}Buy strategy {left_to_buy_strategy}\nTot price: {left_to_buy_tot_price}\nTot saved: {left_to_buy_tot_saved}\n{sep}')

优化方案与代码实现

优化思路

  1. 简化核心计算:将「计算一组商品的折扣节省」封装为独立函数,避免重复逻辑
  2. 遍历所有分组可能:通过递归枚举所有合法的分组组合(如6件商品可分为5+1、4+2、3+3、2+2+2等),计算每种组合的总节省
  3. 全局最优筛选:对比所有分组方案的总节省,保留最大值对应的策略
  4. 可读性提升:使用清晰的变量名、函数注释,拆分复杂逻辑

优化后代码

from itertools import combinations
from typing import List, Dict, Tuple

# 折扣规则:键=购买数量,值=最低价商品的折扣率
DISCOUNT_RULES = {
    1: 0.0,
    2: 0.25,
    3: 0.55,
    4: 0.80,
    5: 0.99
}

def calculate_group_savings(prices: List[float], group_size: int) -> float:
    """计算一组商品的折扣节省金额"""
    sorted_prices = sorted(prices)
    discount = DISCOUNT_RULES[group_size]
    # 仅对组内最低价商品打折
    return sorted_prices[0] * discount

def get_all_possible_groups(products: Dict[str, float], min_size: int = 2) -> List[Tuple[Tuple[str, ...], Dict[str, float]]]:
    """生成所有可能的商品分组(从min_size到最大允许的5件),返回(分组, 剩余商品)的列表"""
    possible_groups = []
    max_group_size = min(5, len(products))
    for size in range(min_size, max_group_size + 1):
        # 生成所有该尺寸的商品组合
        for group in combinations(products.keys(), size):
            # 计算剩余商品
            remaining = {k: v for k, v in products.items() if k not in group}
            possible_groups.append((group, remaining))
    return possible_groups

def find_optimal_strategy(products: Dict[str, float]) -> Tuple[float, List[Tuple[str, ...]]]:
    """递归查找最优采购策略,返回(总节省金额, 分组策略)"""
    product_count = len(products)
    
    # 终止条件:无商品或只剩1件(无折扣)
    if product_count <= 1:
        return 0.0, []
    
    max_total_savings = -1
    best_strategy = []
    
    # 遍历所有可能的初始分组
    for group, remaining_products in get_all_possible_groups(products):
        # 计算当前分组的节省
        group_prices = [products[item] for item in group]
        group_savings = calculate_group_savings(group_prices, len(group))
        # 递归计算剩余商品的最优节省
        remaining_savings, remaining_strategy = find_optimal_strategy(remaining_products)
        # 总节省
        total_savings = group_savings + remaining_savings
        
        # 更新最优策略
        if total_savings > max_total_savings:
            max_total_savings = total_savings
            best_strategy = [group] + remaining_strategy
    
    # 处理剩余1件的情况(直接加入策略,无折扣)
    if len(best_strategy) == 0 and product_count == 1:
        best_strategy = [(next(iter(products.keys())),)]
    
    return max_total_savings, best_strategy

# 示例使用
if __name__ == "__main__":
    products = {
        'fridge': 3009,
        'washing_machine': 1449,
        'stove': 2299.99,
        'dish_washer': 1599,
        'tv': 3999,
        'oven': 1899
    }
    
    total_savings, optimal_strategy = find_optimal_strategy(products)
    original_total = sum(products.values())
    final_cost = original_total - total_savings
    
    print("=== 最优采购策略 ===")
    print(f"总原价: {original_total:.2f}")
    print(f"总节省: {total_savings:.2f}")
    print(f"最终成本: {final_cost:.2f}")
    print("分组方案:")
    for idx, group in enumerate(optimal_strategy, 1):
        group_prices = [products[item] for item in group]
        group_size = len(group)
        savings = calculate_group_savings(group_prices, group_size)
        print(f"  第{idx}组: {group} | 组内节省: {savings:.2f}")

内容的提问来源于stack exchange,提问作者drkg4b

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 21:25:41