Condividi:        

Massimizza barattando oculatamente [VbaExcel]

Vuoi potenziare i tuoi documenti Word? Non sai come si fa una macro in Excel? Devi creare una presentazione in PowerPoint?
Oppure sei passato a OpenOffice e non sei sicuro di come lavorare al meglio?

Moderatori: Anthony47, Flash30005

Massimizza barattando oculatamente [VbaExcel]

Postdi recalcatiiti » 06/03/17 22:51

Buonasera a tutti,

supponiamo che un certo bene possa essere prodotto tramite l'assemblaggio di un certo numero di componenti A, B e C, in oltre supponiamo che il componente C possa essere barattato con un'azienda esterna per A o B. Chiaramente, questo baratto avviene attraverso un tasso di scambio variabile: "tasso A" (nel caso C venga barattato con A) o "tasso B" (nel caso C venga barattato con B). Supponiamo di aver a disposizione inizialmente certe quantità di A, B e C, che chiameremo startA, startB e startC.
Il quesito del problema, a cui la macro deve rispondere è il seguente:

Dato il costo del bene per la produzione di una singola unità (ad esempio: 500 pezzi di A, 1325 pezzi di B e 650 di C), dati i tassi di scambio (ad esempio: tasso A = 1:3 e tasso B = 1:2) e dati i componenti a disposizione per la produzione (ad esempio: 12500 di A, 8000 di B e 125000 di C), quale è il massimo numero di unità (del bene) che la mia azienda può produrre a seguito di un oculato scambio del componente C con le aziende esterne?

Difatti, è facilmente intuibile che ci sia un massimo nel numero di unità prodotte considerando gli scambi. Il ragionamento è questo:
se baratto troppo C acquisendo A e B, mi troverò nella situazione in cui avrò carenza di C rispetto alla quantità di A e B che posseggo in seguito allo scambio (ricordiamoci che C è anch'esso un componente utilizzato nella produzione del bene).
Se non baratto abbastanza C, mi troverò nella situazione in cui avrò un eccesso di C rispetto alla quantità di A e B che posseggo a seguito dello scambio.

Ne consegue che esiste un'esatta quantità di C da barattare affinché sia massimizzato il numero di unità prodotte.

Ho risolto la questione con questa pessima macro:

Codice: Seleziona tutto
Sub massimizza()
Dim vValue As Variant
Dim k As Long
m = Range("A2").Value
c = Range("B2").Value
d = Range("C2").Value
md = Range("A4").Value
cd = Range("B4").Value
dd = Range("C4").Value
ms = Range("A6").Value
cs = Range("B6").Value
acomp = 0
bcomp = 0
k = 1 '<--- Definisce la minima quantità di C barattata, chiaramente più è piccola più è accurato il risultato.
Do
    cven = cven + k '<--- Tengo conto della quantità di C barattata
    d = d - k
    rm = m / md'<--- Calcolo i rapporti
    rc = c / cd
    rd = d / dd
'Determina minimo rapporto
    vValue = Application.WorksheetFunction.Min(rm, rc, rd)
'Determina l'acquisto della risorsa con rapporto minore
    If vValue = rm Then
        m = m + ms * k '<--- Tengo conto della quantità di A acquisita dopo lo scambio
        acomp = acomp + ms * k
    End If
    If vValue = rc Then
        c = c + cs * k '<--- Tengo conto della quantità di B acquisita dopo lo scambio
        bcomp = bcomp + cs * k
    End If
Loop Until vValue = rd '<--- Condizione affinché lo scambio sia interrotto
cven = Application.WorksheetFunction.RoundUp(cven, 0)
acomp = Application.WorksheetFunction.RoundDown(acomp, 0)
bcomp = Application.WorksheetFunction.RoundDown(bcomp, 0)
vValue = Application.WorksheetFunction.RoundDown(vValue, 0)

MsgBox ("Vendi: " & cven & " di C." & Chr(13) & "Ottieni: " & acomp & " di A e " & bcomp & " di B." & Chr(13) & "Produci: " & vValue & " unità.")

End Sub

Allego il file associato alla macro (contiene anche l'esempio sopra scritto):
https://www.dropbox.com/s/4ypukhq54jw4hmu/massimizza_barattando.xlsm?dl=0

Come al solito il problema è la velocità (quando le quantità possedute inizialmente sono grandi, nell'ordine di 10^6/10^7), vorrei sapere se esiste un modo più efficiente per fare questo calcolo.

Grazie a tutti, a disposizione di qualsiasi chiarimento,

Ciao
Excel 2021
recalcatiiti
Utente Junior
 
Post: 95
Iscritto il: 12/10/15 15:03

Sponsor
 

Re: Massimizza barattando oculatamente [VbaExcel]

Postdi wallace&gromit » 08/03/17 09:28

È un quesito che assomiglia alla stechiometria, se c'è un chimico "in sala" è pregato di annunciarsi, magari con la sua esperienza sa risolvere anche semplicemente con le formule, senza ricorrere a macro.
Office2016 + 2019 su win11
Avatar utente
wallace&gromit
Utente Senior
 
Post: 2174
Iscritto il: 16/01/12 14:21

Re: Massimizza barattando oculatamente [VbaExcel]

Postdi Anthony47 » 08/03/17 12:53

Ricordo cosa sia il rapporto stechiometrico, ma per il resto in chimica ero e sono rimasto scarso. Devo quindi ricorrere al vba.

Ho risolto la questione con questa pessima macro
Per definizione se una macro funziona allore e' ottima..

Comunque l'algoritmo usato da questa macro mi pare che vada piu' rapidamente al risultato:
Codice: Seleziona tutto
Sub makedeal()
Dim stA, stB, stC, uA, uB, uC, C2A, C2B, iA, iB, iC
Dim iReal, nwA, nwB, nwC, I, C4A, C4B
'
stA = Range("A2").Value
stB = Range("B2").Value
stC = Range("C2").Value
uA = Range("A4").Value
uB = Range("B4").Value
uC = Range("C4").Value
C2A = Range("A6").Value
C2B = Range("B6").Value
'
iA = stA / uA
iB = stB / uB
iC = stC / uC
iReal = Int(Application.WorksheetFunction.Min(iA, iB, iC))
stA = stA - iReal * uA
stB = stB - iReal * uB
stC = stC - iReal * uC
For I = 1 To 100000
    nwA = stA - uA * I
    nwB = stB - uB * I
    nwC = stC
    If nwA < 0 Then nwC = nwC + nwA / C2A
    If nwB < 0 Then nwC = nwC + nwB / C2B
    If nwC / uC < I Then
        Exit For
    End If
Next I
C4A = Application.WorksheetFunction.RoundUp((uA * (I - 1) - stA) / C2A, 0)
C4B = Application.WorksheetFunction.RoundUp((uB * (I - 1) - stB) / C2B, 0)
'
MsgBox ("C per A: " & C4A & vbCrLf & "C per B: " & C4B & vbCrLf & _
   "Pezzi: " & iReal + I - 1) & vbCrLf & "Residuo C: " & (stC - C4A - C4B - (I - 1) * uC)
End Sub

Nel calcolo c'e' un limite di 1Mill di pezzi costruibili, penso che sia compatibile con le tue esigenze; ho preferito il ciclo For I=1 to 1Mill invece che il Do /Loop per assicurare l'uscita dal loop anche se qualcosa andasse storto, tipo numeri negativi inseriti per errore tra i dati di partenza.

Ci sono delle discrepanze nei calcoli tra la tua macro e la mia, es prova con 12500 /80000 /1250000; ma penso che sia corretto il mio calcolo :D

Ciao
Avatar utente
Anthony47
Moderatore
 
Post: 19263
Iscritto il: 21/03/06 16:03
Località: Ivrea

Re: Massimizza barattando oculatamente [VbaExcel]

Postdi recalcatiiti » 08/03/17 18:09

Sì Anthony, hai ragione, il tuo calcolo è più accurato e più veloce, mille grazie.

Il problema, risiede nel k iniziale, utilizzando valori più piccoli riesco ad ottenere risultati via via più corretti e tempi via via più lunghi ( :lol: ). Ovvio è che il tuo metodo è migliore, anche se simile al mio.

A breve pubblicherò un problema affine, che date le scarse conoscenze potremo rendere più efficiente come abbiamo fatto in questo caso.

Ciao, grazie ancora e a presto.

Stefano
Excel 2021
recalcatiiti
Utente Junior
 
Post: 95
Iscritto il: 12/10/15 15:03


Torna a Applicazioni Office Windows

Chi c’è in linea

Visitano il forum: Nessuno e 27 ospiti

cron