APÉNDICE E CÓDIGO DEL PROGRAMA E.1 CÓDIGO DEL PROGRAMA A continuación se presenta el código del sistema, el cual se encuentra en lenguaje Visual Basic. E.1.1 INICIALIZACIÓN DE VARIABLES Las variables siguientes corresponden a todo el proceso de simulación-optimización y de los dos modelos de inventarios. Public CTA As Double Public QMejor As Double Public sMejor As Double Public T() As Double Public Qw As Long Public sw As Long Public SSw As Long Public PCTA(8) As Double Public AuxP As Integer Public Conta As Integer Public VecQs(2, 8) As Double Private VecCTA As Double Public SolActual As Double Public SolMejor As Double Public QActual As Double Public sActual As Double Public DA As Double Public Const inc As Double = 0.1 Public Final As Integer Public Eventos(2) As Integer Public bandera As Bolean Public NumPed As Integer Public D As Integer Public TED As Integer Public TEP As Integer Public k As Integer Public INVF As Integer Public II As Integer Public Ca As Single Public Co As Single Public Cc As Single Public Q As Long Public s As Long Public SS As Long Public Reloj As Integer Public Retraso As Boolean Public Perdida As Boolean Public j As Integer Public m As Integer Public CAT As Single Public RelojAux As Integer Public AGOT As Integer Public AGO As Integer Public NumDem As Integer Public NumRev As Integer Public n As Integer Public RECEPAUX() As Integer Public ATED() As Integer Public Bandera4 As Boolean Public Bandera5 As Boolean Public txt1 As Double Public txt2 As Double Public txt3 As Double Public txt4 As Double Public txt5 As Double Public txt6 As Double Public Simulacion As Boolean Public ListD As Integer Public ListTEP As Integer Public DIARIO As Integer Public c As Integer Public Ite As Integer Public BanIte As Boolean Public BanQs As Boolean Public BanNS As Boolean Public estocas As Boolean Public Cont As Integer E.1.2 MODELO (s,Q) Visual Basic Applications trabaja a través de unidades de trabajo denominadas como macros o rutinas, las siguientes rutinas corresponden al simulador del modelo (s,Q). Public Sub Simula() With Captura Ca = .txtCa.Value Co = .txtCo.Value Cc = .txtCc.Value II = .txtII.Value ListD = .ListBox1.ListIndex ListTEP = .ListBox2.ListIndex If ListD = 0 Then D = .txtD.Value If ListTEP = 0 Then TEP = .txtTEP.Value TED = 1 PINV = .txtII.Value Retraso = .FrameQr.OptionRetraso Perdida = .FrameQr.OptionPerdida DA = .txtDA.Value End With CTA = 0 CAT = 0 COT = 0 CCT = 0 Reloj = 0 Final = 313 bandera = False NumPed = 0 INVF = II m=0 c=0 n=1 RelojAux = 0 NumDem = 1 NumRev = 1 Bandera4 = True AGO = 0 AGOT = 0 ReDim RECEPAUX(1) RECEPAUX(1) = Final + 1 Eventos(1) = TED Eventos(2) = Final + 1 SigEvento End Sub Private Sub SigEvento() RelojAux = Reloj If Eventos(1) <= Final And Bandera4 = True Then m=m+1 ReDim Preserve ATED(m) ATED(m) = Eventos(1) End If If Eventos(2) <= Final And Bandera5 = True Then n=n+1 ReDim Preserve RECEPAUX(n) RECEPAUX(n) = Eventos(2) End If If ATED(NumDem) < RECEPAUX(NumRev) Then Reloj = ATED(NumDem) Else Reloj = RECEPAUX(NumRev) RECEPAUX(NumRev) = Final + 1 End If Bandera4 = False Bandera5 = False ChecaReloj End Sub Sub ChecaReloj() Divi = Reloj / 6 If Reloj = Eventos(2) Then Recepcion Demanda Revision If Divi = Int(Divi) Then CAT = CAT + Ca * (INVF) / 365 If Reloj = 313 Then CostoTotal Else SigEvento End If Else Demanda Revision If Divi = Int(Divi) Then CAT = CAT + Ca * (INVF) / 365 If Reloj = 313 Then CostoTotal Else SigEvento End If End If End Sub Public Sub Demanda() GeneraD Bandera4 = True Eventos(1) = ATED(m) + 1 If Eventos(1) <= Final Then NumDem = NumDem + 1 CAT = CAT + Ca * (Reloj - RelojAux) * (INVF) / 365 Select Case INVF Case Is >= D INVF = INVF - D Case Is < D AGO = AGO + (D - INVF) AGOT = AGOT + (D - INVF) INVF = 0 End Select End Sub Public Sub GeneraD() Select Case ListD Case 1 Range("n1").Formula = "=RiskBinomial(" & txt1 & "," & txt2 & ", RiskTruncate(0, ))" D = Range("n1").Value Case 2 Range("n1").Formula = "=RiskNegbin(" & txt1 & "," & txt2 & ")" D = Range("n1").Value Case 3 Range("n1").Formula = "=INT(RiskGamma(" & txt1 & "," & txt2 & ")" D = Range("n1").Value Case 4 Range("n1").Formula = "=RiskHypergeo(" & txt1 & "," & txt2 & "," & txt3 & ", RiskTruncate(0, ))" D = Range("n1").Value Case 5 Range("n1").Formula = "=INT(RiskNormal(" & txt1 & "," & txt2 & ", RiskTruncate(0, )))" D = Range("n1").Value Case 6 Range("n1").Formula = "=RiskPoisson(" & txt1 & ", RiskTruncate(0, ))" D = Range("n1").Value Case 7 Range("n1").Formula = "=INT(RiskUniform(" & txt1 & "," & txt2 & ", RiskTruncate(0, )))" D = Range("n1").Value Case 8 Range("n1").Formula = "=INT(RiskTriang(" & txt1 & "," & txt2 & "," & txt3 & ", RiskTruncate(0, )))" D = Range("n1").Value Case 9 Range("n1").Formula = "=INT(RiskStudent(" & txt1 & ", RiskTruncate(0, )))" D = Range("n1").Value Case 10 Range("n1").Formula = "=INT(RiskWeibull(" & txt1 & "," & txt2 & "))" D = Range("n1").Value Case 11 Range("n1").Formula = "=INT(RiskChisq(" & txt1 & ", RiskTruncate(0, )))" D = Range("n1").Value End Select End Sub Public Sub GeneraTEP() Select Case ListTEP Case 1 Range("o1").Formula = "=RiskBinomial(" & Parametros.TextBox4.Value & "," & txt5 & ", RiskTruncate(1, ))" TEP = Range("o1").Value Case 2 Range("o1").Formula = "=RiskNegbin(" & txt4 & "," & txt5 & ", RiskTruncate(1, ))" TEP = Range("o1").Value Case 3 Range("o1").Formula ="=INT(RiskGamma(" RiskTruncate(1,)))" TEP = Range("o1").Value & txt4 & "," & txt5 & ", Case 4 Range("o1").Formula = "=RiskHypergeo(" & txt4 & "," & txt5 & "," & txt6 & ",RiskTruncate(1, ))" TEP = Range("o1").Value Case 5 Range("o1").Formula = "=INT(RiskNormal(" & txt4 & "," & txt5 & ", RiskTruncate(1, )))" TEP = Range("o1").Value Case 6 Range("o1").Formula = "=RiskPoisson(" & txt4 & ", RiskTruncate(1, ))" TEP = Range("o1").Value Case 7 Range("o1").Formula = "=Int(RiskUniform(" & txt4 & "," & txt5 & " , RiskTruncate(1, )))" TEP = Range("o1").Value Case 8 Range("o1").Formula = "=INT(RiskTriang(" & txt4 & "," & txt5 & "," & txt6 & ", RiskTruncate(1, )))" TEP = Range("o1").Value Case 9 Range("o1").Formula = "=INT(RiskStudent(" & txt4 & ", RiskTruncate(1, )))" TEP = Range("o1").Value Case 10 Range("o1").Formula = "=INT(RiskWeibull(" & txt4 & "," & txt5 & ", RiskTruncate(1, )))" TEP = Range("o1").Value Case 11 Range("o1").Formula = "=INT(RiskChisq(" & txt4 & ", RiskTruncate(1, )))" TEP = Range("o1").Value End Select End Sub Private Sub Revision() If INVF <= s And bandera = False Then GeneraTEP Eventos(2) = Reloj + TEP NumPed = NumPed + 1 Bandera5 = True bandera = True If Eventos(2) <= Final Then NumRev = NumRev + 1 End If End Sub Public Sub Recepcion() bandera = False Select Case Retraso Case True Aux = (Q - AGO) If Aux > 0 Then INVF = Aux + INVF AGO = 0 Else AGO = Aux End If Case False INVF = INVF + Q End Select End Sub Public Sub CostoTotal() COT = Co * NumPed CCT = Cc * AGOT CTA = COT + CCT + CAT End Sub Sub Optimiza() Application.ScreenUpdating = False Start = Timer Dim ContaTabu As Integer If BanIte = False Then Ite = 10 ReDim T(2, Ite) If BanNS = False Then AuxP = 50 If BanQs = False Then Qw = Sqr(2 * Captura.txtCo.Value * Captura.txtCa.Value * Captura.txtDA.Value / Captura.txtCa.Value) sw = Qw / 2 End If ContadorBarra = 0 SolActual = 0 QActual = Qw sActual = sw AuxTQ = QActual AuxTs = sActual QMejor = QActual sMejor = sActual If Captura.ListBox1.ListIndex <> 0 Or Captura.ListBox2.ListIndex <> 0 Then Q = Qw s = sw Simm = (Ite * AuxP * 8) + 2 * AuxP For uuu = 1 To AuxP Simula SolActual = SolActual + CTA Next uuu SolActual = SolActual / AuxP Else Simm = (Ite * 8) Q = Qw s = sw Simula SolActual = CTA End If SolMejor = SolActual Contad = 0 For k = 1 To Ite For ini = 1 To 8 PCTA(ini) = 0 Next ini Conta = 0 For u = -1 To 1 Q = Int(QActual + (u) * QActual * inc) For uu = -1 To 1 If (u = 0 And uu = 0) Then uu = uu + 1 Conta = Conta + 1 Contad = Contad + 1 s = Int(sActual + (uu) * sActual * inc) ''range("d" & Contad) = Q ''range("e" & Contad) = s VecQs(1, Conta) = Q VecQs(2, Conta) = s If Captura.ListBox1.ListIndex Captura.ListBox2.ListIndex <> 0 Then For uuu = 1 To AuxP Simula <> PCTA(Conta) = PCTA(Conta) + CTA Next uuu PCTA(Conta) = PCTA(Conta) / AuxP Else Simula PCTA(Conta) = CTA ''range("c" & Contad) = CTA End If 0 Or Next uu Next u Call BubbleSort(PCTA(), VecQs()) If k <> 1 Then ChecaTabu If SolActual < SolMejor Then SolMejor = SolActual QMejor = QActual sMejor = sActual End If Else QActual = VecQs(1, 1) sActual = VecQs(2, 1) SolActual = PCTA(1) If SolActual < SolMejor Then SolMejor = SolActual QMejor = QActual sMejor = sActual End If T(1, 1) = AuxTQ T(2, 1) = AuxTs End If Next k Finish = Timer TotalTime = Format((Finish - Start) / 60, "0.000") If Captura.ListBox1.ListIndex <> 0 Or Captura.ListBox2.ListIndex <> 0 Then Prom = 0 Varianz = 0 Q = QMejor s = sMejor Dim Mejorcito() As Double ReDim Mejorcito(AuxP) For uoo = 1 To AuxP Simula Mejorcito(uoo) = CTA Prom = CTA + Prom Next uoo Prom = Prom / AuxP For hola = 1 To AuxP Varianz = Varianz + ((Mejorcito(hola) - Prom) ^ 2) Next Varianz = Varianz / (AuxP - 1) End If Resultado1.Show 0 Application.StatusBar = False End Sub Sub ChecaTabu() Dim BanderaTabu As Boolean ReDim Preserve T(2, Ite) ContaTabu = 0 Do For Tabu = 1 To (k - 1) BanderaTabu = False If T(1, Tabu) = VecQs(1, ContaTabu + 1) And T(2, Tabu) = VecQs(2, ContaTabu + 1) Then BanderaTabu = True If PCTA(ContaTabu + 1) < SolMejor Then BanderaTabu = False Exit For Else If ContaTabu <= 7 Then ContaTabu = ContaTabu + 1 End If End If End If Next Tabu Loop While BanderaTabu = True If BanderaTabu <> True Then 'Antes de cambie el valor de Qactual T(1, k) = QActual T(2, k) = sActual QActual = VecQs(1, ContaTabu + 1) sActual = VecQs(2, ContaTabu + 1) SolActual = PCTA(ContaTabu + 1) End If End Sub Sub BubbleSort(List() As Double, ListQs() As Double) Dim First As Integer, Last As Integer Dim i As Integer, j As Integer Dim Temp As Double, Temps As Double, TempQ As Double First = LBound(List) Last = UBound(List) For i = First To Last - 1 For j = i + 1 To Last If List(i) > List(j) Then Temp = List(j) List(j) = List(i) List(i) = Temp TempQ = ListQs(1, j) ListQs(1, j) = ListQs(1, i) ListQs(1, i) = TempQ Temps = ListQs(2, j) ListQs(2, j) = ListQs(2, i) ListQs(2, i) = Temps End If Next j Next i End Sub E.1.3 MODELO (S,s) Las rutinas para el simulador, en este modelo, son las mismas a excepción de una RevisiónSs, es por ello que rutinas como GeneraD y Demanda no son repetidas. Optimiza2 es la macro principal del modelo ( S,s), es la macro equivalente a Optimiza para el modelo (s,Q), sólo que con las variables respectivas. Private Sub RevisionSs() If INVF <= s And bandera = False Then GeneraTEP Eventos(2) = Reloj + TEP NumPed = NumPed + 1 Bandera5 = True bandera = True Q = SS - INVF If Eventos(2) <= Final Then NumRev = NumRev + 1 End If End If End Sub Public Sub Optimiza2() Application.ScreenUpdating = False Start = Timer Dim ContaTabu As Integer If BanIte = False Then Ite = 10 ReDim T(2, Ite) If BanNS = False Then AuxP = 50 If BanQs = False Then SSw = Sqr(2 * Captura.txtCo.Value * Captura.txtCa.Value * Captura.txtDA.Value / Captura.txtCa.Value) sw = SSw / 2 End If ContadorBarra = 0 Simm = (Ite * AuxP * 8) + 2 * AuxP SolActual = 0 QActual = SSw sActual = sw AuxTQ = QActual AuxTs = sActual QMejor = QActual sMejor = sActual If Captura.ListBox1.ListIndex <> 0 Or Captura.ListBox2.ListIndex <> 0 Then SS = SSw s = sw For uuu = 1 To AuxP Simula2 SolActual = SolActual + CTA Next uuu SolActual = SolActual / AuxP Else SS = SSw s = sw Simula2 SolActual = CTA End If SolMejor = SolActual For k = 1 To Ite For ini = 1 To 8 PCTA(ini) = 0 Next ini Conta = 0 For u = -1 To 1 SS = Int(QActual + (u) * QActual * inc) For uu = -1 To 1 If (u = 0 And uu = 0) Then uu = uu + 1 Conta = Conta + 1 s = Int(sActual + (uu) * sActual * inc) VecQs(1, Conta) = SS VecQs(2, Conta) = s If Captura.ListBox1.ListIndex Captura.ListBox2.ListIndex <> 0 Then For uuu = 1 To AuxP Simula2 <> PCTA(Conta) = PCTA(Conta) + CTA Next uuu PCTA(Conta) = PCTA(Conta) / AuxP Else Simula2 PCTA(Conta) = CTA End If Next uu Next u Call BubbleSort(PCTA(), VecQs()) If k <> 1 Then ChecaTabu If SolActual < SolMejor Then SolMejor = SolActual QMejor = QActual sMejor = sActual End If Else QActual = VecQs(1, 1) sActual = VecQs(2, 1) SolActual = PCTA(1) If SolActual < SolMejor Then SolMejor = SolActual QMejor = QActual 0 Or sMejor = sActual End If T(1, 1) = AuxTQ T(2, 1) = AuxTs End If Next k Finish = Timer TotalTime = Format((Finish - Start) / 60, "0.000") If Captura.ListBox1.ListIndex <> 0 Or Captura.ListBox2.ListIndex <> 0 Then Prom = 0 Varianz = 0 SS = QMejor s = sMejor Dim Mejorcito() As Double ReDim Mejorcito(AuxP) For uoo = 1 To AuxP Simula Mejorcito(uoo) = CTA Prom = CTA + Prom Next uoo Prom = Prom / AuxP For hola = 1 To AuxP Varianz = Varianz + ((Mejorcito(hola) - Prom) ^ 2) Next Varianz = Varianz / (AuxP - 1) End If Resultado1.Show 0 Application.StatusBar = False End Sub E.1.4 OPCIÓN CONTINUAR Una vez que el proceso completo ha finalizado después de k iteraciones, si el usuario decide que esas k iteraciones no fueron suficientes y necesita hacer más continuando desde ese último resultado, solo necesita apretar el botón continuar en el Formulario Resultado1. A continuación se presenta las macros que permiten que esto suceda, primero se presenta para el modelo(s,Q) y luego para el modelo(S,s). Sub Continua() For k = Ite - Sigue.txtContinua.Value + 1 To Ite For g = 1 To 8 PCTA(g) = 0 Next Conta = 0 For u = -1 To 1 Q = Int(QActual + (u) * QActual * inc) For uu = -1 To 1 If (u = 0 And uu = 0) Then uu = uu + 1 Conta = Conta + 1 s = Int(sActual + (uu) * sActual * inc) VecQs(1, Conta) = Q VecQs(2, Conta) = s If Captura.ListBox1.ListIndex <> Captura.ListBox2.ListIndex <> 0 Then For uuu = 1 To AuxP Simula PCTA(Conta) = PCTA(Conta) + CTA Next uuu PCTA(Conta) = PCTA(Conta) / AuxP Else Simula PCTA(Conta) = CTA End If Next uu Next u 0 Or Call BubbleSort(PCTA(), VecQs()) ChecaTabu If SolActual < SolMejor Then SolMejor = SolActual QMejor = QActual sMejor = sActual End If Next k If Captura.ListBox1.ListIndex <> 0 Or Captura.ListBox2.ListIndex <> 0 Then Prom = 0 Varianz = 0 Q = QMejor s = sMejor Dim Mejorcito() As Double ReDim Mejorcito(AuxP) For uoo = 1 To AuxP Simula Mejorcito(uoo) = CTA Prom = CTA + Prom Next uoo Prom = Prom / AuxP For hola = 1 To AuxP Varianz = Varianz + ((Mejorcito(hola) - Prom) ^ 2) Next Varianz = Varianz / (AuxP - 1) End If Resultado1.Show 0 End Sub Sub Continua2() For k = Ite - Sigue.txtContinua.Value + 1 To Ite For g = 1 To 8 PCTA(g) = 0 Next Conta = 0 For u = -1 To 1 SS = Int(QActual + (u) * QActual * inc) For uu = -1 To 1 If (u = 0 And uu = 0) Then uu = uu + 1 Conta = Conta + 1 s = Int(sActual + (uu) * sActual * inc) VecQs(1, Conta) = SS VecQs(2, Conta) = s If Captura.ListBox1.ListIndex <> Captura.ListBox2.ListIndex <> 0 Then For uuu = 1 To AuxP Simula2 PCTA(Conta) = PCTA(Conta) + CTA Next uuu PCTA(Conta) = PCTA(Conta) / AuxP Else Simula2 PCTA(Conta) = CTA End If Next uu Next u Call BubbleSort(PCTA(), VecQs()) ChecaTabu 'Checando si es Tabú o no If SolActual < SolMejor Then SolMejor = SolActual QMejor = QActual sMejor = sActual End If Next k If Captura.ListBox1.ListIndex <> 0 Or Captura.ListBox2.ListIndex <> 0 Then Prom = 0 Varianz = 0 SS = QMejor s = sMejor Dim Mejorcito() As Double ReDim Mejorcito(AuxP) 0 Or For uoo = 1 To AuxP Simula Mejorcito(uoo) = CTA Prom = CTA + Prom Next uoo Prom = Prom / AuxP For hola = 1 To AuxP Varianz = Varianz + ((Mejorcito(hola) - Prom) ^ 2) Next Varianz = Varianz / (AuxP - 1) End If Resultado1.Show 0 End Sub