编程语言
首页 > 编程语言> > 修复了Python中的关系笛卡尔积

修复了Python中的关系笛卡尔积

作者:互联网

背景:
我有兴趣通过在DWave的绝热量子计算机上编写模拟来研究各种材料的量子相变.为了更容易根据参数生成相图,我正在编写实用程序来扫描参数,使用这些参数集运行模拟,并收集数据.

输入条件背景:
在DWave上,我可以设置两组参数,h偏差和J耦合.它们输入如下:h = {qubit0:hvalue0,qubit1:hvalue1,…}和J = {(qubit0,qubit1):J01,(qubit2,qubit3):J23,…}.到目前为止,我有一个工具可以进行参数扫描,给出如下输入:{qubit:[hz1,hz2,…,hzn]}将量子位映射到h值以进行扫描和{耦合器:[J1,J2,.. .,Jn]}将耦合器映射到J值进行扫描.在这两种情况下,输出都是[{trial1},{trial2},… {trialn}]形式的列表,表示每个单独的量子位和耦合上的h和J输入的笛卡尔积.

我实际想要的东西和我写的东西:
在上面,我遇到了一个严重的问题.假设我想扫描一系列参数,其中某些量子位或耦合器在任何给定的运行中相互之间具有固定的关系.这很重要,因为必须以非平凡的方式将逻辑问题映射到DWave上.例如,假设我想运行一个问题,其中qubit0在[0,1,2]中有h,qubit1在[1,2,3]中有h,而qubit3在[5,8]中有h,但是关系qubit1_h =必须保留qubit0_h 1;即,我希望值的乘积为[(0,1,5),(0,1,8),(1,2,5),(1,2,8),…]并且不是全部由笛卡尔积给出的组合.

以下代码将对h参数执行此操作,但不适用于J参数,因为字典键是元组.另外,如果我不想要这个功能,我必须运行我的原始代码来生成护理产品,所以它似乎生成“3个案例”.

def fixed_relationship_sweep(input_params, together):
    """
    Inputs
    ------
    input_params: {0:[x1, x2], 1:[x3, x4], 2:[y1, y2], 3:[y3, y4]]}
    dictionary mapping qubits to parameter lists to iterate through
    together: [[0, 1], [2, 3]]
    list of qubit lists that specify which qubit parameters to sweep with a fixed relationship

    Output
    ------
    fixed_rel_sweep: [{trial1}, {trial2}, ...{trialn}] where qubits labelled as "together" are
    swept with fixed 1-1 relationship, ie, above produces:
    [{0:x1, 1:x3, 2:y1, 3:y3}, {0:x1, 1:x3, 2:y2, 3:y4}, {0:x2, 1:x4, 2:y1, 3:y3},
    {0:x2, 1:x4, 2:y2, 3:y4}] 
    """
    qsorcs = []
    params = []
    #index representation of params, as cartesian product must respect fixed positions
    #of arguments and not their values, ie [x1, x3] vary together in example
    tempidxrep = []
    for key, value in input_params.items():
        qsorcs.append(key)
        params.append(value)
        tempidxrep.append([i for i in range(len(value))])

    idxrep = []
    #remove redundancy in index representation governed by fixed relationships in together
    for fix_rel in together:
        idxrep.append(tempidxrep[fix_rel[0]])

    #sweep combinations via carteisan product
    idxcombos = itertools.product(*idxrep)

    #reconstruct actual parameter combinations
    param_combos = []
    for idxcombo in idxcombos:
        trial = {qsorcs[j]: params[j][idxcombo[i]] for i in range(len(idxcombo)) for j in together[i]}
        param_combos.append(trial)

    return param_combos

使用像itertools这样的内置工具可以更简单,更好的方法来处理整数或元组的键而无需编写单独的复杂函数吗?换句话说,我是从错误的方向接近这个看似简单的问题吗?

解决方法:

在发布这个问题之后,我编写了原始代码的改进版本,允许原始输入(形式为{h_n:hval}的字典,其中h为表示第n个量子位的迭代)以及形式{J_nm: Jval} J_nm是量子位n和m之间耦合强度的元组(qn,qm).此外,当一些量子比特/耦合器被排除在原始状态之外的“一起”时,它不会中断.因此,这个新代码在功能上适用于我想要做的事情.尽管如此,我怀疑还有更好的方法.

def fixed_relationship_sweep(input_params, together):
"""
Inputs
------
input_params: {qorc1:[x1, x2], qorc2:[x3, x4], qorc3:[y1, y2], qorc4:[y3, y4]]}
dictionary mapping qubits or couplers to parameter lists to iterate through
together: [[qorc1, qorc2], [qorc3, qorc4]]
list of qubit lists that specify which qubit parameters to sweep with a fixed relationship

Output
------
fixed_rel_sweep: [{trial1}, {trial2}, ...{trialn}] where qubits labelled as "together" are
swept with fixed 1-1 relationship, ie, above produces:
[{qorc1:x1, qorc2:x3, qorc3:y1, qorc4:y3}, {qorc1:x1, qorc2:x3, qorc3:y2, qorc4:y4},
{qorc1:x2, qorc2:x4, qorc3:y1, qorc4:y3},{qorc1:x2, qorc2:x4, qorc3:y2, qorc4:y4}] 
"""
#list of qubits or couplers
qsorcs = []
#index representation of params, as cartesian product must respect fixed positions
#of arguments and not their values, ie [x1, x3] vary together in example
idxrep = {}
for key, value in input_params.items():
    qsorcs.append(key)
    idxrep[key] = [i for i in range(len(value))]

#remove redundancy in index representation governed by fixed relationships in together
count = 0
for fix_rel in together:
    for j in range(len(fix_rel)):
        if j != 0:
            del idxrep[fix_rel[j]]

#sweep combinations via cartesian product
idxdict_combos = (list(dict(zip(idxrep, x)) for x in itertools.product(*idxrep.values())))

#reconstruct actual parameter combinations with "redundant" parameter values
dict_combos = []
for combo in idxdict_combos:
    #add back in "redundant" parameters
    for fix_rel in together:
        for qorc in fix_rel[1::]:
            combo[qorc] = combo[fix_rel[0]]

    #add back in true values corresponding to indices
    tempdict = {}
    for key, value in combo.items():
        tempdict[key] = input_params[key][value]

    dict_combos.append(tempdict)

return dict_combos 

标签:python,python-3-x,cartesian-product
来源: https://codeday.me/bug/20190710/1425344.html