派单算法——找到手上工单最少者,然后派送给TA

1 题目

一个简单的派单算法。有一群可接单人员,来了一个单子,需要给他们派单。派单规则,就是均衡分配:找到谁手上的单子最少,就分配给TA;如果找到的人多于1位,则从中随机抽取1位

2 思路

抛砖引玉,目前我的思路:

  • 从正在执行的单子中,计算每个人手中的单子数量
  • 遍历所有人中,找到持有最小单子数的人员集合
  • 从集合中随机抽取一位,把单子分配给TA

有更好的算法,麻烦提供一下,感谢!

3 代码

public static void main(String[] args) {
    arrangeOrder();
}

private static void arrangeOrder() {
    // 所有的人员
    List<Member> members = new ArrayList<>();
    members.add(new Member("id001", "name001"));
    members.add(new Member("id002", "name002"));
    members.add(new Member("id003", "name003"));

    // 正在进行中的单子
    List<Order> orders = new ArrayList<>();
    orders.add(new Order("id002", "order001"));
    orders.add(new Order("id001", "order002"));
    orders.add(new Order("id002", "order003"));
    orders.add(new Order("id002", "order004"));
    orders.add(new Order("id003", "order005"));

    // 1. 计算已接单人员的单子数量
    Map<String, Integer> memberCountMap = new HashMap<>();
    for (Order order : orders) {
        Integer count = memberCountMap.get(order.memberId);
        memberCountMap.put(order.memberId, count == null ? 0 : count + 1);
    }

    // 2. 找到单子最小的待选人员集合
    List<String> candidates = new ArrayList<>();
    if (memberCountMap.size() == members.size()) {
        // 找接单数量最少的人员
        int minCount = 0;
        Set<String> keySet = memberCountMap.keySet();
        for (String key : keySet) {
            Integer count = memberCountMap.get(key);
            if (minCount == 0) {
                // 第一位人员
                minCount = count;
                candidates.add(key);
            } else {
                if (count == minCount) {
                    candidates.add(key);
                } else if (count < minCount) {
                    minCount = count;
                    candidates.clear();
                    candidates.add(key);
                }
            }
        }
    } else {
        for (Member m : members) {
            if (!memberCountMap.containsKey(m.id)) {
                candidates.add(m.id);
            }
        }
    }

    // 打印所有候选人id
    StringBuilder sb = new StringBuilder("[");
    for (String id : candidates) {
        sb.append(id).append(",");
    }
    sb.deleteCharAt(sb.length() - 1);
    sb.append("]");
    System.out.println("The candidates=" + sb);

    // 随机派单
    String selectedMemberId;
    if (candidates.size() == 1) {
        selectedMemberId = candidates.get(0);
    } else {
        selectedMemberId = candidates.get(new Random(System.currentTimeMillis()).nextInt(candidates.size()));

    }
    System.out.println("The order will belong to " + selectedMemberId);
}

/**
 * 人员信息
 */
private static class Member {
    /**
     * 人员id
     */
    public String id;
    /**
     * 人员姓名
     */
    public String name;
    /**
     * 已接单总数
     */
    public int sum = 0;

    public Member(String id, String name) {
        this.id = id;
        this.name = name;
    }
}

/**
 * 订单信息
 */
private static class Order{
    /**
     * 接单人id
     */
    public String memberId;
    /**
     * 订单名称
     */
    public String orderName;
    public Order(String memberId, String orderName) {
        this.memberId = memberId;
        this.orderName = orderName;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值