java案例如何分配不同场景的权重?

wen java案例 1

本文目录导读:

java案例如何分配不同场景的权重?

  1. 简单权重分配(比例分配)
  2. 基于配置文件的权重管理
  3. 基于权重的影响因子模型
  4. 动态权重调整(基于用户行为)
  5. 实用建议

在Java中分配不同场景的权重,常见的有以下几种方法,我根据实际需求逐一说明:

简单权重分配(比例分配)

适用于按固定比例分配,比如抽奖、A/B测试。

import java.util.Random;
public class WeightedRandom {
    // 场景枚举
    enum Scenario {
        SCENARIO_A(0.5),   // 50%概率
        SCENARIO_B(0.3),   // 30%概率
        SCENARIO_C(0.2);   // 20%概率
        private final double weight;
        Scenario(double weight) {
            this.weight = weight;
        }
        public double getWeight() {
            return weight;
        }
    }
    public static Scenario getRandomScenario() {
        double random = Math.random();
        double cumulativeWeight = 0;
        for (Scenario scenario : Scenario.values()) {
            cumulativeWeight += scenario.getWeight();
            if (random < cumulativeWeight) {
                return scenario;
            }
        }
        return Scenario.values()[0]; // 兜底
    }
    public static void main(String[] args) {
        // 测试10000次
        int countA = 0, countB = 0, countC = 0;
        for (int i = 0; i < 10000; i++) {
            switch (getRandomScenario()) {
                case SCENARIO_A: countA++; break;
                case SCENARIO_B: countB++; break;
                case SCENARIO_C: countC++; break;
            }
        }
        System.out.printf("A: %.2f%%, B: %.2f%%, C: %.2f%%%n",
            countA/100.0, countB/100.0, countC/100.0);
    }
}

基于配置文件的权重管理

适合需要动态调整权重的场景。

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class ConfigurableWeight {
    private Map<String, Double> weights = new HashMap<>();
    // 从配置加载权重
    public void loadWeights(Properties config) {
        config.stringPropertyNames().forEach(key -> {
            if (key.startsWith("scenario.")) {
                String scenario = key.substring("scenario.".length());
                double weight = Double.parseDouble(config.getProperty(key));
                weights.put(scenario, weight);
            }
        });
    }
    public String getScenarioByWeight() {
        double random = Math.random();
        double cumulative = 0;
        // 按权重排序后选择
        for (Map.Entry<String, Double> entry : weights.entrySet()) {
            cumulative += entry.getValue();
            if (random < cumulative) {
                return entry.getKey();
            }
        }
        return null;
    }
    public static void main(String[] args) {
        // 模拟配置
        Properties config = new Properties();
        config.setProperty("scenario.new_user", "0.3");
        config.setProperty("scenario.vip_user", "0.5");
        config.setProperty("scenario.normal_user", "0.2");
        ConfigurableWeight weightManager = new ConfigurableWeight();
        weightManager.loadWeights(config);
        // 获取场景
        System.out.println("选中场景: " + weightManager.getScenarioByWeight());
    }
}

基于权重的影响因子模型

适用于推荐系统、业务决策等复杂场景。

import java.util.HashMap;
import java.util.Map;
public class WeightFactorModel {
    // 场景权重因子
    private static class Factor {
        double baseWeight;      // 基础权重
        Map<String, Double> ifFactors;  // 条件因子
        Factor(double baseWeight) {
            this.baseWeight = baseWeight;
            this.ifFactors = new HashMap<>();
        }
        void addFactor(String condition, double weight) {
            ifFactors.put(condition, weight);
        }
        double calculateWeight(String... conditions) {
            double totalWeight = baseWeight;
            for (String condition : conditions) {
                if (ifFactors.containsKey(condition)) {
                    totalWeight *= ifFactors.get(condition);
                }
            }
            return totalWeight;
        }
    }
    public static void main(String[] args) {
        Map<String, Factor> scenarioFactors = new HashMap<>();
        // 定义场景A及其因子
        Factor factorA = new Factor(1.0);
        factorA.addFactor("user_is_new", 1.5);      // 新用户权重加倍
        factorA.addFactor("user_is_mobile", 1.2);    // 移动端增加权重
        scenarioFactors.put("scenario_A", factorA);
        // 定义场景B
        Factor factorB = new Factor(0.8);
        factorB.addFactor("user_is_vip", 2.0);       // VIP用户权重加倍
        scenarioFactors.put("scenario_B", factorB);
        // 实际使用
        String userType = "user_is_vip";
        boolean isMobile = false;
        for (Map.Entry<String, Factor> entry : scenarioFactors.entrySet()) {
            String scenario = entry.getKey();
            Factor factor = entry.getValue();
            double weight = factor.calculateWeight(userType);
            System.out.printf("场景: %s, 计算权重: %.2f%n", scenario, weight);
        }
    }
}

动态权重调整(基于用户行为)

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class DynamicWeightAdjuster {
    // 用户ID -> 场景权重映射
    private Map<String, Map<String, Double>> userScenarioWeights = new ConcurrentHashMap<>();
    // 初始化默认权重
    private static final Map<String, Double> DEFAULT_WEIGHTS = new HashMap<>() {{
        put("detail_page", 0.6);   // 详情页
        put("comment_page", 0.3);  // 评论页
        put("recommend_page", 0.1); // 推荐页
    }};
    // 记录用户行为并调整权重
    public void recordBehavior(String userId, String scenario, int times) {
        Map<String, Double> userWeights = 
            userScenarioWeights.computeIfAbsent(userId, k -> new HashMap<>(DEFAULT_WEIGHTS));
        // 根据行为次数调整权重
        userWeights.computeIfPresent(scenario, (key, weight) -> 
            weight * (1 + times * 0.1));  // 每次行为增加10%权重
    }
    // 获取用户场景权重
    public String getNextScenario(String userId) {
        Map<String, Double> weights = 
            userScenarioWeights.getOrDefault(userId, DEFAULT_WEIGHTS);
        // 权重归一化并随机选择
        double total = weights.values().stream().mapToDouble(Double::doubleValue).sum();
        double random = Math.random() * total;
        double cumulative = 0;
        for (Map.Entry<String, Double> entry : weights.entrySet()) {
            cumulative += entry.getValue();
            if (random < cumulative) {
                return entry.getKey();
            }
        }
        return "detail_page";  // 默认
    }
}

实用建议

选择权重分配方案时考虑:

  • 固定比例:简单场景用轮询/随机
  • 可配置:需要运营调整用配置文件
  • 动态计算:考虑多种因素用因子模型
  • 个性化:需要用户差异化用动态调整

性能优化提示

// 预计算累积权重,避免每次循环
private static final NavigableMap<Double, Scenario> WEIGHT_MAP = 
    new TreeMap<>();
static {
    double cumulative = 0;
    for (Scenario s : Scenario.values()) {
        cumulative += s.getWeight();
        WEIGHT_MAP.put(cumulative, s);
    }
}
public static Scenario getFastRandom() {
    double random = Math.random() * WEIGHT_MAP.lastKey();
    return WEIGHT_MAP.higherEntry(random).getValue();
}

根据具体业务选择合适的方案,保持代码简洁和可维护性。

抱歉,评论功能暂时关闭!