按权重随机调用算法

本文介绍了一种基于权重的随机算法实现方案,通过设置不同来源系统的调用阈值和权重,实现了对第三方接口的智能调用分配。算法首先计算所有第三方接口的权重总和,然后生成一个介于0和权重总和之间的随机数,根据这个随机数和各接口的权重范围确定最终调用的接口。此外,还提供了一个使用TreeMap实现的更高效算法,确保了权重分配的准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路是:给每个来源系统设置每天的最大调用量、调用阈值等信息,该来源系统调用不同的第三方接口,给每个第三方接口设置权重,以实现按权重随机调用第三方接口的效果

代码实现

配置表 POJO

public class TwoElementConfig {
    @Id
    private Long id;
    /**来源系统*/
    private String source;
    /**第三方接口*/
    private String targetSource;
    /**是否开启(1启用,0禁用,默认禁用)*/
    private Integer open;
    /**调用次数上限*/
    private Integer callLimit;
    /**预警阈值,总值100(达到上限的x%进行提醒)*/
    private Integer warnThreshold;
    /**权重*/
    private Integer weight;
    /**调用系统负责人姓名*/
    private String name;
    /**调用系统负责人手机号*/
    private String mobile;
    /**创建时间*/
    private Date createTime;
    /**更新时间*/
    private Date updateTime;

}

核心算法接口

  • 方式一
// 配置信息列表
List<TwoElementConfig> configs=twoElementConfigService.listTwoElementConfig(vo);

// 2、获取权重
Integer weightSum = 0;
String targetSource = "";
for (TwoElementConfig co : configs) {
    weightSum += co.getWeight();
}
if (weightSum <= 0) {
    throw new IllegalArgumentException("权重信息不能小于等于0");
}
// n in [0, weightSum)
Integer n = new Random().nextInt(weightSum);
Integer m = 0;
for (TwoElementConfig co : configs) {
    if (m <= n && n < m + co.getWeight()) {
        targetSource = co.getTargetSource();
        break;
    }
    m += co.getWeight();
}

// 调用第三方接口
if (Objects.equals(targetSource, "AA")) {
    result = nanJingYiShuService.verifyAA(cerName, cerNo);
}
if (Objects.equals(targetSource, "BB")) {
    result = juFengService.verifyByBB(cerName, cerNo);
}

  • 方式二
package cn.yto.ias.base.util;

import cn.yto.ias.common.entity.TwoElementConfig;
import org.apache.commons.lang3.StringUtils;

import java.util.Random;
import java.util.TreeMap;

/**
 * @Author yanyg
 * @Date 2020/6/23 14:01
 * @Descripetion admin
 */
public class WeightUtil {

    /**
     * @param config
     * @return 二要素接口名称
     */
    public static String getTargetSource(TwoElementConfig config) {
        // 获取权重
        Integer weightSum = 0;
        String[] twoElementArr = config.getWeight().split(",");

        //以权重区间段的后面的值作为key存当前信息
        TreeMap<Integer, String> map = new TreeMap<>();
        for (String element : twoElementArr) {
            String eleName = element.split(":")[0];
            String weight = element.split(":")[1];
            weightSum += Integer.valueOf(weight);
            map.put(weightSum, eleName);
        }
        if (weightSum <= 0) {
            throw new IllegalArgumentException("权重信息不能小于等于0");
        }

        // random in [1, weightSum]
        Integer random = new Random().nextInt(weightSum) + 1;
        // ceilingKey(K key) 方法用于返回map中最小键大于或等于给定的入参random,如果不存在这样的最小键,返回null
        return map.get(map.ceilingKey(random));
    }


    public static void main(String[] args) {
        String weight = "JuFeng:30,NanJingYiShu:90,AA:60";
        TwoElementConfig config = new TwoElementConfig();
        config.setWeight(weight);
        int count1 = 0;
        int count2 = 0;
        int count3 = 0;

        for (int i = 1; i <= 180; i++) {
            String targetSource = getTargetSource(config);
            switch (targetSource) {
                case "JuFeng":
                    count1++;
                    break;
                case "NanJingYiShu":
                    count2++;
                    break;
                case "AA":
                    count3++;
                    break;
                default:
                    break;
            }
        }
        System.out.println("JuFeng 出现次数:" + count1);
        System.out.println("NanJingYiShu 出现次数:" + count2);
        System.out.println("AA 出现次数:" + count3);
        System.out.println("总次数:" + (count1 + count2 + count3));

    }
}

参考文档

### 带权重随机选择算法权重随机选择是一种常见的需求,在许多场景下用于模拟概率事件的发生。以下是基于 Lua 的一种实现方法,该方法通过累积权重来计算每个选项被选中的概率。 #### 算法原理 为了实现带权重随机选择,通常会采用如下策略: 1. 将所有选项的权重累加起来形成总权重。 2. 随机生成一个介于 `[0, 总权重)` 之间的数值。 3. 遍历选项列表,逐步减去当前项的权重直到剩余值小于等于零为止,此时对应的选项即为所选目标[^4]。 下面是具体的 Lua 实现: ```lua function weighted_random_choice(items) local total_weight = 0 -- 计算总权重 for _, item in ipairs(items) do total_weight = total_weight + item.weight end -- 生成一个位于 [0, total_weight) 范围内的随机数 local random_value = math.random() * total_weight -- 找到对应的选择 for _, item in ipairs(items) do if random_value < item.weight then return item.value end random_value = random_value - item.weight end end -- 测试数据结构定义 local items = { {value = "A", weight = 1}, {value = "B", weight = 2}, {value = "C", weight = 3} } for i = 1, 10 do print(weighted_random_choice(items)) end ``` 上述代码片段展示了如何创建一个函数 `weighted_random_choice` 来完成带权重随机选择操作。其中输入参数是一个数组形式的数据集,每条记录包含两个属性:`value`(表示实际的内容),以及`weight`(代表其相对重要程度)。 #### 关键点解析 - **随机数范围控制**:确保产生的随机浮点数严格处于指定区间内,从而避免边界条件引发错误判断。 - **效率考量**:虽然这里采用了简单的线性扫描方式查找匹配项目,但对于大规模或者频繁调用场合可能需要进一步优化成二分查找等高效手段。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值