4. Cas complexe

Ici, on considère que la somme réclamée par les clients est la même que celle contenue dans les caisses. Si ce n'est pas le cas, on utilise l'algorithme vu dans la page précédente.
Prenons un exemple. Supposons que la banque possède 4 caisses de contenances respectives 30, 30, 60 et 40. D'autre part, 3 clients réclament respectivement 20, 60 et 80 pièces d'or. On obtiendra alors les attributions suivantes :
CaisseClientQuantité
0020
0110
1130
2120
2220
3260
Mais on aurait pu faire mieux si on avait mélangé autrement les clients et les caisses. Par exemple avec des caisses contenant 40, 60, 30 et 30 et des clients réclamant 20, 80 et 60, on économise une attribution :
CaisseClientQuantité
0020
0120
1160
2230
3230
Posons n le plus grand entre le nombre de caisses et le nombre de clients (dans l'exemple précédent, on avait n = 4). Puisque les clients doivent être entièrement satisfaits et que les caisses doivent être entièrement vides, on voit bien que le nombre minimal d'attributions doit être égal à n.
L'algorithme d'allocation est le suivant :
# -*- coding: utf-8 -*-

def allocate(A, B):
    allocations = []
    a = 0  # indice dans la liste A
    b = 0  # indice dans la liste B
    qa = 0 # quantité déjà attribuée pour un élément de A
    qb = 0 # quantité déjà attribuée pour un élément de B
    while a < len(A) and b < len(B):
        if A[a] - qa > B[b] - qb:
            q = B[b] - qb
            qa += q
            qb = B[b]
        else:
            q = A[a] - qa
            qb += q
            qa = A[a]
        allocations.append((a, b, q))
        if A[a] == qa:
            a += 1
            qa = 0
        if B[b] == qb:
            b += 1
            qb = 0
    return allocations
Pages : 1 2
Attribution
22 mai 2013
Sommaire général