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

Posted a10615

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了派单算法——找到手上工单最少者,然后派送给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;
    

以上是关于派单算法——找到手上工单最少者,然后派送给TA的主要内容,如果未能解决你的问题,请参考以下文章

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

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

创业日记薄Go出行:要借助SAAS系统帮助传统车企解决日常派单问题

氚云派单文档介绍

基于mongodb的地理检索实现

PHP 延迟执行