Ho un problema concettuale in cui ho diversi pacchetti, ogni pacchetto contiene un numero di elementi all'interno. Gli elementi sono di tipo A
o tipo B
. Voglio distribuire i pacchetti in un numero finito di contenitori in modo tale che la distribuzione tra A
e B
non differisca selvaggiamente tra i contenitori.Variazione dello zaino ... in pitone
Il problema è piuttosto complesso, quindi cercherò di spiegarlo con rigidi vincoli e un esempio concettuale.
Vincoli
A package can only be used once
A package must be used entirely
The bins should have relatively equal distributions between `A` and `B` (max 5% deviation from the original ratio)
A package can be spread across all the bins in the given batch
I want to end up with as little as batches (size <= 3 bins) as possible
Esempio (concettuale)
Plate 1: 92 * `A`
Plate 2: 92 * `A`
Plate 3: 64 * `A`
Plate 4: 42 * `A`, 50 * `B`
Plate 5: 12 * `A`, 49 * `B`
Plate 6: 92 * `B`
distribuzione totale come tale è 302 * A
e 191 * B
cedevole 493 campioni in totale, i rapporti risultanti sono dunque 61,25% di A
e 38,75% di B
risultato desiderato:
Un insieme minimizzata di lotti, dove ogni lotto contiene al massimo 3 scomparti (lunghezza < = 92) con diciamo tra 52 e 60 di tipo A
e tra 32 e 40 di tipo B
(il totale combinato non superiore a 92) per contenitore.
Domanda
Che algoritmo o metodo sarebbe uno suggerire per affrontare questo problema, un semplice schema suggerito farà (visto che quello che ho cercato finora (vedi sotto) non ottiene molto lontano)
L'idea dietro i miei tentativi finora
data = ... # This is a list containg all values in a tuple format of `(unit, [(type, location)])` format
while len(data) > 0:
batch = []
counter1 = 0
counter2 = 0
for i in data:
for j in i[1]:
if j[0] == 'A':
counter1 += 1
else:
counter2 += 1
ratio1 = counter1/(counter1+counter2)
ratio2 = counter2/(counter1+counter2)
# Now we know the maximum number of A and B per batch
counter3 = 0 # This keeps track of howmany type `A` we have in current batch
counter4 = 0 # This keeps track of howmany type `B` we have in current batch
while counter3 < ratio1:
for i in data:
for j in i[1]:
if Counter(elem[0] for elem in j)['A'] < (ratio1 - counter3) and Counter(elem[0] for elem in j)['B'] < (ratio2 - counter4):
# Add this unit (from data) to the batch
batch.append(i)
counter3 += Counter(elem[0] for elem in j)['A']
counter4 += Counter(elem[0] for elem in j)['B']
# Remove the used unit from data
questo è anche il luogo dove mi sono bloccato, questo momento non tenta di minim ize il numero di contenitori, né controlla i rapporti. Inoltre, ho l'idea fastidiosa che il modo in cui sto provando a farlo non sia vicino al modo intelligente di risolvere un simile problema.
Qual è esattamente la domanda? – jwodder
Qual è la domanda? – gustavodidomenico
E la prossima volta che finisci di scriverlo ** * prima * lo pubblichi? – jonrsharpe