净订单的最佳算法

时间:2016-02-26 12:24:47

标签: algorithm

我正在建立一个市场,我想为市场参与者订单建立一个匹配机制。

例如我收到这些订单:

A buys 50
B buys 100
C sells 50
D sells 20

可以表示为List<Orders>,其中Order是包含ParticipantBuySellAmount

的类

我想创建一个Match函数,它输出两件事:

  1. 一组不匹配的订单(List<Order>
  2. 一组匹配的订单(List<MatchedOrder>其中MatchOrderBuyerSellerAmount
  3. 约束是最小化订单数量(不匹配和匹配),同时不会撤消任何可能的匹配(即最终只能购买或卖出无与伦比的订单)

    所以在上面的例子中,结果将是:

    A buys 50 from C
    B buys 20 from D
    B buys 80 (outstanding)
    

    这似乎是一个相当复杂的编写算法,但在实践中很常见。有什么指针可以看哪儿?

2 个答案:

答案 0 :(得分:0)

您可以将其建模为二分图中的流问题。每个销售节点都在左侧,每个购买节点都在右侧。像这样:

graphviz]

然后,您必须找到可以从source传递到sink的最大流量。

您可以使用所需的任何最大流量算法,例如Ford Fulkerson。要最小化订单数,您可以使用最大流量/最小成本算法。有许多技术可以做到这一点,包括在找到正常的MaxFlow解决方案后应用循环取消。

运行算法后,您可能会有以下残留网络:

enter image description here

答案 1 :(得分:0)

  1. 创建一个包含2个成员的WithRemainingQuantity结构:订单的pointeur o和存储不匹配数量的整数
  2. 考虑2个List<WithRemainingQuantity>,1个用于购买Bq,1个用于销售Sq,均按包含订单的降序排序。
  3. algo匹配每个队列的头部,直到其中一个为空
  4. Algo(meta和c ++的混合):

    struct WithRemainingQuantity
    {
        Order * o;
        int remainingQty; // initialised with o->getQty
    }
    
    
    struct MatchedOrder
    {
        Order * orderBuy;
        Order * orderSell;
        int matchedQty=0;
    }
    
    List<WithRemainingQuantity> Bq;
    List<WithRemainingQuantity> Sq;
    
    /*
    populate Bq and Sq and sort by quantities descending, 
    this is what guarantees the minimum of matched.
    */    
    
    List<MatchedOrder> l;
    while( ! Bq.empty && !Sq.empty)
    {
        int matchedQty = std::min(Bq.front().remainingQty, Sq.front().remainingQty)
    
        l.push_back( MatchedOrder(orderBuy=Bq.front(), sellOrder=Sq.front(), qtyMatched=matchedQty) )
    
        Bq.remainingQty -= matchedQty
        Sq.remainingQty -= matchedQty
    
        if(Bq.remainingQty==0)
            Bq.pop_front()
    
        if(Sq.remainingQty==0)
            Sq.pop_front()
    }
    

    不匹配的订单是Bq或Sq中的剩余订单(根据while条款,其中一个订单是致命空的。)