Python实现CBAA拍卖算法(一)

一、背景介绍

本节意在复现<Consensus-Based Decentralized Auctions for Robust Task Allocation>提出的两种分散式算法:consensus-based auction algorithm(CBAA)和consensus-based bundle algorithm(CBBA)。

二、问题介绍

假设存在A、B、C三个用户和三件商品足球、篮球、乒乓球。由于三个人的爱好不一样,因此三件商品在其心目中的价值不一样,例如A对三件商品的价值估计分别为5,2,0,B和C分别为1,4,1;4,3,2。求出使得三个人同时满足最大收获的分配方法。

三、求解思路

根据文献提出的方法,CBAA方法基于所有人共识,从自私的角度出发,对于A来说,足球是最值得买的,因此,A选择了足球A,作为自己想买的,并根据其价值提出5元,同理B和C分别选择篮球和足球,并各自提出自己的竞标价格为4元和4元,此时,A和C发生了冲突,因为对于商家来说,A出价更高,所以A获得了足球,此时C选择篮球,提出3元购买,但是B出价高,因此只剩下乒乓球留给C。

四、算法及代码

根据数学语言,将上述过程描述,需要引入以下几个符号

\boldsymbol{x}_{ij}:描述用户i和商品j的对应关系,如果用户i选择了j商品,那么为1,否则为0。

\boldsymbol{y}_{ij}:描述用户i对商品j竞标提出的价格。

\boldsymbol{J}_{i}:描述商品i被分配给的用户。

\boldsymbol{z}_{ij}:描述用户i竞标成功的商品。

\boldsymbol{g}_{ij}:描述用户i和用户j之间是否存在联系,即自己提出的价格,别人是否知晓。

\boldsymbol{c}_{ij}:描述用户i对商品j的价值估计

分为两个阶段,第一阶段是拍卖竞标阶段,每个人基于自己估计的价值选择商品,初始竞标价格均为0元,以用户A为例,\boldsymbol{y}_{1j}=\left [ 0,0,0 \right ]\boldsymbol{c}_{1j}=\left [ 5,2,0 \right ],首先找到A用户可以买到的物品并且希望找到对于自己来说价值最高的目标,Python代码如下所示:

def h_compute(c,y):          
    h = np.zeros(len(c))     
    for i in range(len(c)):  
        if c[i] > y[i]:      
            h[i] = 1         
        else:                
            h[i] = 0         
    return h

def Select_Task(c,x,y,J,z,i):                         
    if sum(x) == 0:                                   
        h = h_compute(c,y)                            
        if sum(h) != 0: #如果这里有合适的任务                   
            max_valid_c = -1                          
            for j in range(len(y)):                   
                # 找到估计价值最高的商品                         
                if h[j] == 1 and c[j] > max_valid_c:  
                    J = j                             
                    max_valid_c = c[j]                
            #  拍卖该目标                                  
            x[J] = 1                                  
            z[J] = i                                  
            y[J] = c[J]                               
    return x,y,J,z                                                    

原文里面的流程图

当完成竞拍后,由于拍卖方希望以最大的收获卖出去,所以对于同一件商品,谁给的钱最多,相应的商品会分配给谁,即共识阶段。例如:对于用户C来说,他本身也希望获得足球,但是他给出的价格只能是4元,大家互相之间首先得了解各自对该商品的报价,即在本文讨论的案例中,对于任意i和j,满足\boldsymbol{g}_{ij}=1。例如完成第一阶段的A,商家对于各个物品的报价是[5,0,0],对于B来说,其对于各个物品的报价是[5,4,0],对于C来说,是[5,4,0]。在该阶段之后开始分配,此时足球暂时归A,篮球暂时归B,C竞标失败没有分配到商品。商家对于各个物品的报价为[5,4,0],开始第二轮竞标,此时,判断是否所有人分配到商品,对于C来说,足球和篮球的报价均超过其估计范围,因此只能选择乒乓球,完成任务分配。

第二部分算法的流程图

def  Update_Task(g,c,x,y,J,z,i):                                     
    # 此时的y是矩阵                                                        
    new_y = copy.deepcopy(y)                                         
    # 根据其他竞标人的价格更新出价                                                 
    for j in range(len(y[0])):                                       
        for k in range(len(g)):     # 有联系的才更新                        
            if g[k] == 1:                                            
                if y[k][j] > new_y[i][j]:                            
                    new_y[i][j] = y[j][k]                            
    max_y =  y[i][J[i]]                                              
    # 更新邻居的竞标信息                                                      
    for k in range(len(g)):                                          
        if g[k] == 1:                                                
            if y[k][J[i]] > max_y:                                   
                z[i][J[i]] = k                                       
                max_y = y[k][J[i]]                                   
                                                                     
    if z[i][J[i]] != i:                                              
        x[J[i]] = 0                                                  
    """                                                              
    当存在相同商品 多用户出价一样的情况下,这个任务分配给索引更大的用户                               
    """                                                              
    for k in range(len(g)):                                          
        for j in range(len(y[0])):                                   
            if g[k] == 1:                                            
                if z[k][j] > z[i][j] and c[k][j] == c[i][j]:         
                    if J[i] == j:                                    
                        x[j] == 0                                    
                    z[i][j] = z[k][j]                                
    return x,new_y,J[i],z                                            

整个代码框架

import numpy as np
import copy

def CBAA_self(N_a,N_t,c,g):
    x = np.zeros((3,3))
    y = np.zeros((3,3))
    z = np.full((3,3),-1)
    # 使用列表的方式添加元素

    J = np.full((3,1),-1)
    x_history = []
    while True:
        for i in range(N_a):
            x[i],y[i],J[i],z[i] = Select_Task(c[i],x[i],y[i],J[i],z[i],i)
            x[i],y,J[i],z       = Update_Task(g[i],c,x[i],y,J,z,i)
        x_history.append(copy.deepcopy(x))
        if np.all(np.sum(x,axis=0)==1):
            break
    return x_history


def h_compute(c,y):
    h = np.zeros(len(c))
    for i in range(len(c)):
        if c[i] > y[i]:
            h[i] = 1
        else:
            h[i] = 0
    return h

def Select_Task(c,x,y,J,z,i):
    if sum(x) == 0:
        h = h_compute(c,y)
        if sum(h) != 0: #如果这里有合适的任务
            max_valid_c = -1
            for j in range(len(y)):
                # 找到估计价值最高的商品
                if h[j] == 1 and c[j] > max_valid_c:
                    J = j
                    max_valid_c = c[j]
            #  拍卖该目标
            x[J] = 1
            z[J] = i
            y[J] = c[J]
    return x,y,J,z

def  Update_Task(g,c,x,y,J,z,i):
    # 此时的y是矩阵
    new_y = copy.deepcopy(y)
    # 根据其他竞标人的价格更新出价
    for j in range(len(y[0])):
        for k in range(len(g)):     # 有联系的才更新
            if g[k] == 1:
                if y[k][j] > new_y[i][j]:
                    new_y[i][j] = y[j][k]
    max_y =  y[i][J[i]]
    # 更新邻居的竞标信息
    for k in range(len(g)):
        if g[k] == 1:
            if y[k][J[i]] > max_y:
                z[i][J[i]] = k
                max_y = y[k][J[i]]

    if z[i][J[i]] != i:
        x[J[i]] = 0
    """
    当存在相同商品 多用户出价一样的情况下,这个任务分配给索引更大的用户
    """
    for k in range(len(g)):
        for j in range(len(y[0])):
            if g[k] == 1:
                if z[k][j] > z[i][j] and c[k][j] == c[i][j]:
                    if J[i] == j:
                        x[j] == 0
                    z[i][j] = z[k][j]
    return x,new_y,J[i],z





if __name__ == "__main__":
    N_a = 3
    N_t = 3
    c   = np.array([[5,2,0],[1,4,1],[4,3,2]])
    g   = np.ones((3,3))
    x_history = CBAA_self(N_a, N_t, c, g)  #
    print(x_history[-1])  # 

### 拍卖算法详解 #### 定义与原理 拍卖算法种用于解决优化问题的方法,在分布式计算环境中特别有用。此算法通过模拟传统拍卖过程,其中物品被出售给出价最高的竞买者,来实现资源的最佳分配。在计算机科学领域,特别是对于任务调度和网络流量管理等问题,这种算法提供了有效的解决方案[^2]。 #### 工作机制 在个典型的拍卖场景中,存在两类参与者:拍卖方(即拥有待分配资源的方)以及多个潜在的竞争投标者。每个投标者根据自己对资源的需求提交报价;而拍卖方则依据这些报价以及其他因素如性能参数做出决策。具体来说: - **初始化阶段**:设定初始价格并向所有可能的投标人广播可用资源信息。 - **竞价循环**:各投标人在给定时间内提出自己的最优报价直至达到预设条件为止。在此期间,如果某个投标人的新报价超过了当前最高记录,则更新相应条目的获胜者身份及其支付金额。 - **结束判定**:旦满足终止准则——比如经过固定轮次或者没有更高出价出现时,宣布最终胜出名单并执行交易确认程序。 #### 应用实例 ##### 边缘智能节点任务分配 针对分布式的边缘计算环境下的任务分发挑战,研究者们设计了套基于上述理论框架的新颖方案。这里不仅考量了成本效益比,同时也引入了额外维度衡量参与者的硬件配置水平等因素,从而确保整体系统的高效运作和服务质量。 ```python def auction_algorithm(tasks, nodes): """ 实现简单的拍卖算法逻辑 参数: tasks (list): 待分配的任务列表 nodes (dict): 可选节点集合 {node_id: {'capacity': int, 'bid': float}} 返回: dict: 分配结果 {task_index: node_id} """ assignments = {} while tasks and any(nodes.values()): highest_bidder_per_task = {} for task_idx, _ in enumerate(tasks): best_node = max( ((n_id, n_info['bid']) for n_id, n_info in nodes.items()), key=lambda x: x[1]) highest_bidder_per_task[task_idx] = { "selected_node": best_node[0], "offered_price": best_node[1]} # 更新状态... pass return assignments ``` #### 特点优势 采用这种方式能够带来诸多好处,包括但不限于提高效率、增强灵活性以及更好地适应复杂多变的实际需求状况。特别是在面对大规模并发请求处理或是跨地域协作项目里显得尤为重要。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值