多智能体MDP变量消元动作选择算法的代码实现咨询
背景
我在开展硕士论文研究过程中,需要编码实现应用于多智能体MDP、面向动作选择的变量消元算法,算法流程参考如下示例:
我对算法本身的原理不存在理解障碍,但在代码结构设计层面遇到瓶颈,特此求助。
现有实现方案
单个Q函数的存储
以智能体1的个体Q函数Q1为例,该函数同时受智能体2的动作影响,我采用矩阵存储Q1的值:
- 矩阵行对应智能体1的可选动作
- 矩阵列对应智能体2的可选动作
- 矩阵元素为对应动作对的奖励值
矩阵样例如下:
[ [0.59852164, 0.39597276, 0.7602051 , 0.13295899], [0.41479068, 0.03774037, 0.44269462, 0.68948537], [0.14632375, 0.83137715, 0.79722578, 0.50048093], [0.03223895, 0.89804766, 0.83578682, 0.95018204] ]
Q函数与关联智能体的存储
这是我目前存疑、亟需优化建议的部分:当前采用元组结构存储相关信息:
- 元组第一个元素:前述Q值矩阵
- 元组第二个元素:Q函数所属的智能体标识(如Q1对应
'a1') - 元组第三个元素:对该Q函数存在影响的其他关联智能体标识
元组样例如下:
( [ [0.59852164, 0.39597276, 0.7602051 , 0.13295899], [0.41479068, 0.03774037, 0.44269462, 0.68948537], [0.14632375, 0.83137715, 0.79722578, 0.50048093], [0.03223895, 0.89804766, 0.83578682, 0.95018204] ], 'a1', 'a2' )
算法入口elimination函数的入参为上述元组构成的数组,入参样例如下(其中a12即前述Q1对应的Q值矩阵):
elimination([(a12, "a1", "a2"), (a24, "a2", "a4"), (a13, "a3", "a1"), (a34, "a4", "a3")])
我认为当前的表示方式过于繁琐,但暂未找到更优的实现方案。
消元流程的初步实现思路
我计划随消元流程动态生成新函数:例如示例第一步为消去智能体a4,此时需要生成函数e4(a2,a3),该函数根据智能体2、3的动作输入,返回智能体4的最优动作——因为智能体4仅出现在Q2、Q4两个Q函数中,关联的邻接智能体为2和3。
我采用矩阵存储e4的计算结果:
- 矩阵行对应智能体2的动作
- 矩阵列对应智能体3的动作
- 矩阵元素值为对应场景下智能体4的最优动作索引
矩阵样例如下:
[ [0, 1, 0, 2], [1, 2, 0, 3], [1, 3, 0, 0], [0, 2, 2, 0] ]
坐标示例:矩阵
[0,1]位置的值为1,代表当智能体2选择动作0、智能体3选择动作1时,智能体4选择动作1可获得最优值,该结果通过遍历Q2、Q4函数、计算不同a4动作对应的总奖励得到。
目前已经实现了待消元智能体关联函数的筛选逻辑:由于a4是第一个被消去的智能体,首先遍历传入的Q数组,将包含a4的Q函数存入e4数组用于后续生成e4函数,其余不包含a4的Q函数存入qual1数组供后续流程使用,对应代码如下:
def elimination(Q): qual = Q qual1 = [] qual2= [] e4 = [] e4final = [] e4args= [] e3 = [] e2 = [] e1 = [] # 消去智能体a4 for q in Q: if q[1] == "a4" or q[2] == "a4": e4.append(q) else: qual1.append(q)
筛选得到的e4数组内容如下:
[ ( array([ [0.59852164, 0.39597276, 0.7602051 , 0.13295899], [0.41479068, 0.03774037, 0.44269462, 0.68948537], [0.14632375, 0.83137715, 0.79722578, 0.50048093], [0.03223895, 0.89804766, 0.83578682, 0.95018204] ]), 'a2', 'a4' ), ( array([ [0.67738865, 0.59291644, 0.60924388, 0.04292563], [0.14199367, 0.50405062, 0.62515779, 0.59868234], [0.4568713 , 0.97801569, 0.95928574, 0.67878902], [0.5427607 , 0.29061713, 0.7378397 , 0.37298815] ]), 'a4', 'a3' ) ]
以智能体2、3均选择动作0的场景为例,a4最优动作的计算逻辑为:取第一个矩阵的第0行(对应a2动作为0时,不同a4动作的Q值)、第二个矩阵的第0列(对应a3动作为0时,不同a4动作的Q值),计算相同索引(即a4的同一动作)对应两个Q值的和,取和最大的索引为a4的最优动作。该场景下索引0对应的和最大(0.59852164 + 0.67738865),因此a4选择动作0,我可以通过遍历智能体2、3的所有动作组合完成e4矩阵的全量计算。
核心诉求
我目前可以独立完成e4函数的计算,但完成该步骤后就陷入了实现瓶颈,怀疑问题根源在于初始的代码结构设计不合理,但暂未找到更合适的设计思路。需要实现的算法需满足以下要求:
- 具备灵活性,可适配不同的智能体连接关系(暂不需要支持3个及以上智能体共同影响单个Q函数的场景)
- 支持消元过程中生成的中间函数(如e4)参与后续消元流程(例如消去智能体a3时需要用到已生成的e4函数)
恳请各位提供数据表示方式、代码结构设计相关的建议。
内容的提问来源于stack exchange,提问作者MuchoG

