获得最大产量的算法

时间:2018-06-05 12:19:49

标签: python algorithm hungarian-algorithm

这是情景:

B1,B2,B3,B4,B5,B6是块

S1,S2,S3是插槽

每个块都可以放入特定的插槽中。

即,B1 = [“S1”,“S2”,“S3”]。装置B1可以放入这3个插槽中。

B2 = [S1,S2]

B3 = [S3]

您可以通过从每个插槽中取出一个块来制作产品 -

即,产品的配方是(1来自S1)+(1来自S2)+(1来自S3)

需要一个函数/算法将这些块放在每个插槽中以产生最大数量的产品。

在给定的示例中 - B3将在S3中,因为B3只允许放入该槽。然而,尽管B1可以放在任何3个插槽中,我们应该放入S1,因为要制作设备我们需要S1 + S2 + S3和B3只能在S3中。因此,在插槽之间分配块的最佳方式是:B1-> S1,B2 - > S2,B3 - > S3

所以我们可以根据食谱制作一种产品,即(S1中的1 + S2中的S2 + 1)

Example Input
============
block_slots = {
    "BLOCK1" : ["SLOT - 1","SLOT - 3", "SLOT - 2"],
    "BLOCK2" : ["SLOT - 1","SLOT - 3"],
    "BLOCK3" : ["SLOT - 1","SLOT - 3", "SLOT - 2"],
    "BLOCK4" : ["SLOT - 1","SLOT - 2"],
    "BLOCK5" : ["SLOT - 3", "SLOT - 2"],
    "BLOCK6" : ["SLOT - 1","SLOT - 3", "SLOT - 2"],
    "BLOCK7" : ["SLOT - 1","SLOT - 3", "SLOT - 2"],
    "BLOCK8" : ["SLOT - 1","SLOT - 3", "SLOT - 2"],
    "BLOCK9" : ["SLOT - 3", "SLOT - 2"],
    "BLOCK10" : ["SLOT - 3", "SLOT - 2"],
    "BLOCK11" : ["SLOT - 1"],
    "BLOCK12" : ["SLOT - 2"],
}

Output
==========
{
    "BLOCK8": "SLOT - 1",
    "BLOCK9": "SLOT - 3",
    "BLOCK2": "SLOT - 1",
    "BLOCK3": "SLOT - 2",
    "BLOCK1": "SLOT - 3",
    "BLOCK6": "SLOT - 2",
    "BLOCK7": "SLOT - 1",
    "BLOCK4": "SLOT - 2",
    "BLOCK5": "SLOT - 3",
    "BLOCK10": "SLOT - 3",
    "BLOCK11": "SLOT - 1",
    "BLOCK12": "SLOT - 2"
}

> 4 Blocks in each slot. 4 Products can be made from 12 blocks which is
> maximum yield.

我尝试了以下代码:

blocks = {
"B1" : ["S1","S3", "S2"],
"B2" : ["S1","S3"],
"B3" : ["S1","S3", "S2"],
"B4" : ["S1","S2"],
"B5" : ["S3", "S2"],
"B6" : ["S1","S3", "S2"],
"B7" : ["S1","S3", "S2"],
"B8" : ["S1","S3", "S2"],
"B9" : ["S3", "S2"]
}
slot_count = {}
block_slot_final = {}

for block,block_slots in blocks.iteritems():

    for slot in block_slots:

         if slot in slot_count:
             slot_count[slot] = slot_count[slot] + 1
          else:
              slot_count[slot] = 0

blocks_sorted = sorted(blocks.items(), key=lambda items: len(items))

for block,slots in blocks_sorted:
    final_slot = slots[0]
    for slot in slots:
        if slot_count[slot] < slot_count[final_slot]:
            final_slot = slot
    block_slot_final[block] = final_slot

print block_slot_final

它给出了这个输出

  

{'B4':'S1','B5':'S3','B6':'S1','B7':'S1','B1':'S1','B2':'S1 ','B3':'S1','B8':'S1','B9':'S3'}

有了这个,我们不能制作任何产品,因为S2中没有阻止。

尝试了另一个更好但仍然不完美的解决方案。下面是代码。 它给出了这个输出:

  

{'B4':'S1','B5':'S3','B6':'S2','B7':'S1','B1':'S3','B2':'S1 ','B3':'S2','B8':'S3','B9':'S2'}

def get_least_consumed_slot(block_slot,slots):

    least_consumed_slot = slots[0]
    for slot in slots:
        if slot_block_count[slot] < slot_block_count[least_consumed_slot]:
            least_consumed_slot = slot

    return least_consumed_slot

blocks = {
    "B1" : ["S1","S3", "S2"],
    "B2" : ["S1","S3"],
    "B3" : ["S1","S3", "S2"],
    "B4" : ["S1","S2"],
    "B5" : ["S3", "S2"],
    "B6" : ["S1","S3", "S2"],
    "B7" : ["S1","S3", "S2"],
    "B8" : ["S1","S3", "S2"],
    "B9" : ["S3", "S2"]
}

slot_occurance_count = {}
block_slot_final = {}
all_slots = []
slot_block_count = {}

for block,block_slots in blocks.iteritems():

    for slot in block_slots:
        if slot not in all_slots:
            all_slots.append(slot)
            slot_block_count[slot] = 0

        if slot in slot_occurance_count:
            slot_occurance_count[slot] = slot_occurance_count[slot] + 1
        else:
            slot_occurance_count[slot] = 1

blocks_sorted = sorted(blocks.items(), key=lambda items: len(items))

for block,slots in blocks_sorted:
    # final_slot = slots[0]
    # for slot in slots:
    #     if slot_occurance_count[slot] < slot_occurance_count[final_slot]:
    #         final_slot = slot
    # block_slot_final[block] = final_slot
    least_consumed_slot = get_least_consumed_slot(block_slot_final,slots)
    block_slot_final[block] = least_consumed_slot

    slot_block_count[least_consumed_slot] = slot_block_count[least_consumed_slot] + 1


print block_slot_final

2 个答案:

答案 0 :(得分:0)

在澄清之前,这是枚举所有最大匹配(1)或找到一个最大匹配(2)的问题。

(1)枚举所有完美,最大值和最大值的算法 二分图中的极大匹配 Takeaki UNO http://research.nii.ac.jp/~uno/papers/isaac97web.pdf

(2)例如,Hopcroft - Karp https://en.wikipedia.org/wiki/Hopcroft%E2%80%93Karp_algorithm

答案 1 :(得分:0)

这是这里描述的二分匹配问题,可以用Ford-Fulkerson算法解决:https://en.wikipedia.org/wiki/Matching_(graph_theory)#In_unweighted_bipartite_graphs