APÉNDICE A. CÓDIGO DEL PROGRAMA Dim numciu As Integer 'numero de ciudades dentro dela red Dim numind As Integer 'numero de "cromosomas" por generacion Dim celda As Integer ' posicionador Dim numal As Integer ' numero de almacenes a utilizar en la red Dim numcon As Integer ' numero de posibles conexiones Dim direc As String ' posicionador Dim red As Integer Dim celda2 As Integer Dim numite As Integer ' numero de iteraciones Dim probrec As Double ' probabilidad de recombinacion, la da el usuario Dim probmut As Double ' probabilidad de mutacion Dim lite As Integer Dim alfa As Double, beta As Double Dim sumob Dim funob Dim tablas(), tsp(), tsp1(), tsp2(), tsp3() Dim distancias(), distancias1(), ciudades(), ciudades1() Dim datos(), transporte(), transporte1() Dim generacion, redm, redd Type par p1 As Long p2 As Long End Type ‘Creaarreglos: en esta subrutina se trasforma y se vacía la información de las bases de datos que están en las hojas de Excel en arreglos para posteriormente ser utilizados. Sub creaarreglos() Worksheets("Ciudades").Activate Range("H1").Formula = "=COUNTA(A:A)" numciu = Range("H1").Value - 1 Range("H1").Clear ReDim ciudades(numciu, 2) ReDim ciudades1(numciu, 2) ReDim datos(numciu, 6) Range("A1").Activate For i = 1 To numciu ActiveCell.Cells(2, 1).Select ciudades(i, 1) = ActiveCell.Value datos(i, 1) = ActiveCell.Cells(1, 2).Value datos(i, 2) = ActiveCell.Cells(1, 3).Value datos(i, 3) = ActiveCell.Cells(1, 4).Value datos(i, 4) = ActiveCell.Cells(1, 5).Value datos(i, 5) = ActiveCell.Cells(1, 6).Value datos(i, 6) = ActiveCell.Cells(1, 7).Value Next Worksheets("Transporte1").Cells.Clear Worksheets("Transporte").Activate Range("G1").Formula = "=COUNTA(A:A)" numcon = Range("G1").Value - 1 Range("G1").Clear ReDim transporte(numcon, 3) ReDim transporte1(numcon, 3) Range("A1").Activate For i = 1 To numcon ActiveCell.Cells(2, 1).Select a = ActiveCell.Value b = ActiveCell.Cells(1, 2).Value Worksheets("Transporte1").Range("C" & i) = ActiveCell.Cells(1, 5).Value sal = 0 For j = 1 To numciu If a = ciudades(j, 1) Then Worksheets("Transporte1").Range("A" & i) = j sal = sal + 1 End If If b = ciudades(j, 1) Then Worksheets("Transporte1").Range("B" & i) = j sal = sal + 1 End If If sal = 2 Then Exit For End If Next Next Worksheets("Transporte1").Activate For i = 1 To numcon dem = Range("B" & i).Value Range("D" & i).Value = (alfa / datos(dem, 1)) + _ beta * Range("C" & i).Value Next Range("A1:D" & numcon).Select Selection.Sort Key1:=Range("D1"), Order1:=xlAscending, Header:=xlNo, _ OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _ DataOption1:=xlSortNormal Range("A1").Select For i = 1 To numcon transporte(i, 1) = ActiveCell.Value transporte(i, 2) = ActiveCell.Cells(1, 2) transporte(i, 3) = ActiveCell.Cells(1, 4) ActiveCell.Cells(2, 1).Select Next End Sub ‘Tabla: Vacía la tabla de distancias en una matriz para su uso posterior. Sub tabla() ReDim tablas(1 To numciu, 1 To numciu) Worksheets("Tablacostos").Activate Range("A1").Activate For i = 1 To numciu For j = 1 To numciu tablas(i, j) = ActiveCell.Cells(i + 1, j + 1).Value Next Next End Sub ‘Ingresadatos: Vacía la información de Userform1 en variables para ser manejadas por el programa, también crea las hojas de Excel necesarias para el proceso y sirve de punto de partida para el programa, manda a llamara a otras subrutinas. Sub ingresadatos() numite = UserForm1.TextBox2.Value numind = UserForm1.TextBox3.Value probrec = UserForm1.TextBox4.Value probmut = UserForm1.TextBox5.Value alfa = UserForm1.TextBox6.Value beta = UserForm1.TextBox7.Value numal1 = UserForm1.TextBox9.Value If UserForm1.TextBox10.Value = "" Then numal2 = numal1 Else numal2 = UserForm1.TextBox10.Value End If Unload UserForm1 Worksheets("Inicio").Activate Application.ScreenUpdating = False For i = 1 To numind Sheets.Add ActiveSheet.Name = "red" & i Next creaarreglos tabla For numal = numal1 To numal2 generacion = "Generación (" & numal & ")" Sheets.Add On Error Resume Next ActiveSheet.Name = generacion If Err <> 0 Then Application.DisplayAlerts = False ActiveSheet.Select ActiveWindow.SelectedSheets.Delete Application.DisplayAlerts = True End If Worksheets(generacion).Activate Cells.Clear redm = "red (" & numal & ")" Sheets.Add On Error Resume Next ActiveSheet.Name = redm If Err <> 0 Then Application.DisplayAlerts = False ActiveSheet.Select ActiveWindow.SelectedSheets.Delete Application.DisplayAlerts = True End If Worksheets(redm).Activate Cells.Clear redd = "redd (" & numal & ")" Sheets.Add On Error Resume Next ActiveSheet.Name = redd If Err <> 0 Then Application.DisplayAlerts = False ActiveSheet.Select ActiveWindow.SelectedSheets.Delete Application.DisplayAlerts = True End If Worksheets(redd).Activate Cells.Clear lite = 0 pobinicial muestrasolucion Next Application.DisplayAlerts = False For i = 1 To numind Worksheets("red" & i).Select ActiveWindow.SelectedSheets.Delete Next Application.DisplayAlerts = True Worksheets("Solución (3)").Activate End Sub ‘Pobinicial: Genera la población inicial de cromosomas, manda llamar el cálculo de la función objetivo, la subrutina mejores e iteraciones. Sub pobinicial() Dim gen As Integer Worksheets(generacion).Activate Cells.Select Selection.Clear Range("A1").Value = "Población inicial" Range("A3").Value = "Cromosoma" Range("A3").Select For i = 1 To numal ActiveCell.Cells(1, i + 1).Value = "Almacén " & i Next ActiveCell.Cells(1, numal + 3).Value = "Valor de la función objetivo" For i = 1 To numind ActiveCell.Cells(i + 1, 1).Value = i ActiveCell.Cells(i + 1, 1).Interior.ColorIndex = 6 ActiveCell.Cells(i + 1, 1).HorizontalAlignment = xlCenter Next Randomize For k = 1 To numind For i = 1 To numal gen = 0 Do Until gen <> 0 And gen <> numciu + 1 And datos(gen, 2) <> 0 gen = Rnd * numciu Loop ActiveCell.Cells(k + 1, i + 1) = gen For j = 1 To i - 1 If gen = ActiveCell.Cells(k + 1, j + 1) Then i=i-1 Exit For End If Next Next Next celda = 2 calcfo mejores celda = celda + numind + 4 iteraciones End Sub ‘calcfo: Manda a llamar la función objetivo para cada cromosoma de la generación correspondiente. Sub calcfo() celda2 = celda + 2 For red = 1 To numind Worksheets("red" & red).Cells.Clear fo Worksheets(generacion).Activate Range(direc).Value = sumob celda2 = celda2 + 1 Next End Sub ‘mejores: toma la generación correspondiente y la ordena a los individuos de menor a mayor según su función objetivo. Sub mejores() Range("A" & celda + 1).Select direcc = ActiveCell.Cells(2, 3 + numal).Address direcc1 = ActiveCell.Cells(numind + 1, 8 + numal).Address Range("A" & celda + 2 & ":" & direcc1).Select Selection.Sort Key1:=Range(direcc), Order1:=xlAscending, Header:=xlGuess, _ OrderCustom:=1, MatchCase:=True, Orientation:=xlTopToBottom, DataOption1 _ :=xlSortNormal val1 = Range("B" & celda + 2).Cells(1, numal + 2).Value Worksheets(redm).Activate Range("A1").Formula = "=sum(2:65536)" val2 = Range("A1").Value Worksheets(generacion).Activate If val1 <> "inválido" Then If val1 < val2 Or val2 = 0 Then dval1 = Range("A" & celda + 2).Value Worksheets("red" & dval1).Cells.Copy Worksheets(redm).Activate Range("A1").Select ActiveSheet.Paste End If End If Worksheets(generacion).Activate val1 = Range("B" & celda + 3).Cells(1, numal + 2).Value Worksheets(redd).Activate Range("A1").Formula = "=sum(2:65536)" val2 = Range("A1").Value Worksheets(generacion).Activate If val1 <> "inválido" Then If val1 < val2 Or val2 = 0 Then dval1 = Range("A" & celda + 3).Value Worksheets("red" & dval1).Cells.Copy Worksheets(redd).Activate Range("A1").Select ActiveSheet.Paste End If End If End Sub ‘iteraciones: Va generando las nuevas poblaciones o generaciones, genera tantas como iteraciones le haya pedido el usuario, acada nuevo individuo creado le escribe a un lado como fue creado (recombinación o mutación). Sub iteraciones() Worksheets("Transporte").Activate Range("N1").Value = 1 Range("O1").Value = 2 Range("N2").Value = probrec Range("O2").Value = probmut Range("M1").Formula = "=DISCRINV(RAND(),N1:O1,N2:O2)" For lite = 1 To numite Application.DisplayStatusBar = True Application.StatusBar = "Iteración" & lite Worksheets(generacion).Activate Range("A" & celda).Value = "Generación " & lite Range("A" & celda + 1).Select ActiveCell.Value = "Cromosoma" For i = 1 To numal ActiveCell.Cells(1, i + 1).Value = "Almacén " & i Next ActiveCell.Cells(1, numal + 3).Value = "Valor de la función objetivo" ActiveCell.Cells(1, numal + 5).Value = "Operación" ActiveCell.Cells(1, numal + 6).Value = "n1" ActiveCell.Cells(1, numal + 7).Value = "n2" For i = 1 To numind ActiveCell.Cells(i + 1, 1).Value = i ActiveCell.Cells(i + 1, 1).Interior.ColorIndex = 6 ActiveCell.Cells(i + 1, 1).HorizontalAlignment = xlCenter Next cop = ActiveCell.Cells(-numind - 1, numal + 1).Address Range("B" & celda - numind - 2 & ":" & cop).Copy Range("B" & celda + 2).Select ActiveSheet.Paste numcrom = 2 Range("B" & celda + 1).Select While numcrom < numind Calculate oper = Worksheets("Transporte").Range("M1").Value If oper = 1 Then ' recombinación: Toma dos números aleatorios y entre esas posiciones recombina los genes de los dos cromosomas padres. Randomize k1 = 0 Do Until k1 <> 0 And k1 <> numal + 1 k1 = Int(Rnd * numal) Loop k2 = 0 Do Until k2 <> 0 And k2 <> numal + 1 k2 = Int(Rnd * numal) Loop If k1 > k2 Then tempo = k1 k1 = k2 k2 = tempo End If Dim pad() As par ReDim pad(1 To numal) For i = 1 To numal pad(i).p1 = ActiveCell.Cells(2, i).Value pad(i).p2 = ActiveCell.Cells(3, i).Value Next ActiveCell.Cells(numcrom + 2, 4 + numal) = "recombinación" ActiveCell.Cells(numcrom + 2, 5 + numal) = k1 ActiveCell.Cells(numcrom + 2, 6 + numal) = k2 For i = 1 To k1 - 1 ActiveCell.Cells(numcrom + 2, i).Value = pad(i).p1 If numcrom + 1 < numind Then ActiveCell.Cells(numcrom + 3, i).Value = pad(i).p2 End If Next For i = k1 To k2 ActiveCell.Cells(numcrom + 2, i).Value = pad(i).p2 If numcrom + 1 < numind Then ActiveCell.Cells(numcrom + 3, i).Value = pad(i).p1 End If Next For i = (k2 + 1) To numal ActiveCell.Cells(numcrom + 2, i).Value = pad(i).p1 If numcrom + 1 < numind Then ActiveCell.Cells(numcrom + 3, i).Value = pad(i).p2 End If Next For g = 1 To numal - Int(numal / 2) For i = 1 To k1 - 1 C = ActiveCell.Cells(numcrom + 2, i).Value For j = k1 To k2 b = ActiveCell.Cells(numcrom + 2, j).Value If C = b Then ActiveCell.Cells(numcrom + 2, i).Value = pad(j).p1 End If Next Next For i = k2 + 1 To numal C = ActiveCell.Cells(numcrom + 2, i).Value For j = k1 To k2 b = ActiveCell.Cells(numcrom + 2, j).Value If C = b Then ActiveCell.Cells(numcrom + 2, i).Value = pad(j).p1 End If Next Next Next For i = 1 To numal num1 = ActiveCell.Cells(numcrom + 2, i).Value For j = 1 To i - 1 num2 = ActiveCell.Cells(numcrom + 2, j).Value If num1 = num2 Then gen = 0 Do Until gen <> 0 And gen <> numciu + 1 And datos(gen, 2) <> 0 gen = Int(Rnd * numciu) Loop ActiveCell.Cells(numcrom + 2, j).Value = gen i=0 Exit For End If Next If i <> 0 Then For j = i + 1 To numal num2 = ActiveCell.Cells(numcrom + 2, j).Value If num1 = num2 Then gen = 0 Do Until gen <> 0 And gen <> numciu + 1 And datos(gen, 2) <> 0 gen = Int(Rnd * numciu) Loop ActiveCell.Cells(numcrom + 2, j).Value = gen i=0 Exit For End If Next End If Next If numcrom + 1 < numind Then For g = 1 To numal - Int(numal / 2) For i = 1 To k1 - 1 C = ActiveCell.Cells(numcrom + 3, i).Value For j = k1 To k2 b = ActiveCell.Cells(numcrom + 3, j).Value If C = b Then ActiveCell.Cells(numcrom + 3, i).Value = pad(j).p2 End If Next Next For i = k2 + 1 To numal C = ActiveCell.Cells(numcrom + 3, i).Value For j = k1 To k2 b = ActiveCell.Cells(numcrom + 3, j).Value If C = b Then ActiveCell.Cells(numcrom + 3, i).Value = pad(j).p2 End If Next Next Next For i = 1 To numal num1 = ActiveCell.Cells(numcrom + 3, i).Value For j = 1 To i - 1 num2 = ActiveCell.Cells(numcrom + 3, j).Value If num1 = num2 Then gen = 0 Do Until gen <> 0 And gen <> numciu + 1 And datos(gen, 2) <> 0 gen = Int(Rnd * numciu) Loop ActiveCell.Cells(numcrom + 3, j).Value = gen i=0 Exit For End If Next If i <> 0 Then For j = i + 1 To numal num2 = ActiveCell.Cells(numcrom + 3, j).Value If num1 = num2 Then gen = 0 Do Until gen <> 0 And gen <> numciu + 1 And datos(gen, 2) <> 0 gen = Int(Rnd * numciu) Loop ActiveCell.Cells(numcrom + 3, j).Value = gen i=0 Exit For End If Next End If Next End If numcrom = numcrom + 2 Else 'mutación: entre dos números quita los genes y los cambia por otros generados aleatoriamente que no pueden ser iguales a los que se conservaron en el cromosoma. Randomize a=1 Range(ActiveCell.Cells(2, 1).Address numal).Address).Copy Range("B" & celda + numcrom + 2).Select ActiveSheet.Paste Range("B" & celda + 1).Select k1 = 0 Do Until k1 <> 0 And k1 <> numal + 1 k1 = Int(Rnd * numal) Loop k2 = 0 Do Until k2 <> 0 And k2 <> numal + 1 k2 = Int(Rnd * numal) & ":" & ActiveCell.Cells(2, Loop If k1 > k2 Then tempo = k1 k1 = k2 k2 = tempo End If For i = k1 To k2 a=0 Do Until a = 1 gen = 0 a=1 Do Until gen <> 0 And gen <> numciu + 1 And datos(gen, 2) <> 0 gen = Int(Rnd * numciu) Loop For j = 1 To i - 1 If ActiveCell.Cells(numcrom + 2, j).Value = gen Then a=0 End If Next For j = k2 + 1 To numal If ActiveCell.Cells(numcrom + 2, j).Value = gen Then a=0 End If Next Loop ActiveCell.Cells(numcrom + 2, i).Value = gen Next ActiveCell.Cells(numcrom + 2, 4 + numal).Value = "mutación" ActiveCell.Cells(numcrom + 2, 5 + numal).Value = k1 ActiveCell.Cells(numcrom + 2, 6 + numal).Value = k2 numcrom = numcrom + 1 End If Wend calcfo mejores celda = celda + numind + 4 Next End Sub ‘fo: Primero genera el árbol de expansión mínima y luego genera ciclos para las ciudades asignadas a cada almacen y se queda con el mejor. Sub fo() Dim Arbol() ReDim Arbol(numciu, 3) Worksheets("individuo").Activate Worksheets("individuo").Cells.Clear Range("B" & celda2).Select direc = ActiveCell.Cells(1, numal + 2).Address Worksheets(generacion).Range("B" & celda2 & ":" & direc).Copy Range("A1").Select Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _ False, Transpose:=True transporte1() = transporte() ciudades1() = ciudades() ‘árbol: A partir de aquí genera el árbol de expansión mínima para el cromosoma correspondiente, esto lo hace utilizando los costos alterados como se indica en la tesis. For i = 1 To numal le = Worksheets("individuo").Range("A" & i).Value Worksheets("red" & red).Range("A3").Cells(1, (i * 3) - 2).Value = ciudades(le, 1) ciudades1(le, 2) = 1 Arbol(i, 2) = le Arbol(i, 3) = le Next coe = numal Do Until coe = numciu indic = 0 Do Until indic = 1 For i = 1 To coe npt = Arbol(i, 2) nat = Arbol(i, 3) For j = 1 To numcon If transporte1(j, 1) = npt Then poste = j costo = transporte1(j, 3) nst = transporte1(j, 2) Exit For End If Next If i = 1 Or costo < cosm Then npm = npt nam = nat nsm = nst posm = poste cosm = costo End If Next transporte1(posm, 1) = 0 transporte1(posm, 2) = 0 transporte1(posm, 3) = 0 If ciudades1(nsm, 2) <> 1 Then Arbol(coe + 1, 1) = npm Arbol(coe + 1, 2) = nsm Arbol(coe + 1, 3) = nam indic = 1 ciudades1(nsm, 2) = 1 End If Loop coe = coe + 1 Loop ' hasta aqui es el arbol ‘ciclo: A partir de aquí se calcula el ciclo para cada almacén, la función objetivo se compone de la suma de los costos de ubicar el almacén más la suma de los ciclos. Worksheets("Transporte1").Activate Cells.Select Selection.Clear Range("E1").Select For i = 1 To numciu ActiveCell.Cells(2, 1).Select ActiveCell.Value = Arbol(i, 1) ActiveCell.Cells(1, 2).Value = Arbol(i, 2) ActiveCell.Cells(1, 3).Value = Arbol(i, 3) Next Worksheets("provisional").Range("B1").Formula = "=COUNTA(A:A)" Worksheets("provisional").Range("F1").Formula = "=SUM(E:E)" Worksheets("provisional").Range("J1").Formula = "=SUM(I:I)" sumob = 0 For i = 1 To numal Application.DisplayStatusBar = True Application.StatusBar = "Iteración " & lite & " cromosoma " & red & " almacen " & i & "(" & numal & ")" Worksheets("provisional").Range("A:A").Clear Worksheets("provisional").Range("C:E").Clear Worksheets("provisional").Range("H:I").Clear Worksheets("Transporte1").Activate almacen = Worksheets("individuo").Range("A" & i).Value Worksheets("provisional").Range("A:A").Clear Range("F:G").Select Selection.AutoFilter Field:=2, Criteria1:=almacen Range("F:F").Select Selection.Copy Worksheets("provisional").Activate Range("A1").Select ActiveSheet.Paste Range("D1").Value = almacen Range("A2").Clear nodosal = Range("B1").Value demanda = datos(almacen, 1) Range("A2").Activate For j = 1 To nodosal ActiveCell.Cells(2, 1).Select demanda = demanda + datos(ActiveCell.Value, 1) Next ‘ aqui checa si la demanda sobrepasa la capacidad del almacen, si la sobrepasa, se para el proceso y se declara el cromosoma inválido, si no continua el proceso. If demanda > datos(almacen, 2) Then sumob = "inválido" Exit For End If If nodosal < 1 Then If datos(almacen, 3) = 0 Then costoal = datos(almacen, 4) + datos(almacen, 5) * demanda Else If demanda * (1 + datos(almacen, 6)) < datos(almacen, 2) Then costoal = datos(almacen, 4) + demanda * (1 + datos(almacen, 6)) * datos(almacen, 5) Else costoal = datos(almacen, 4) + datos(almacen, 2) * datos(almacen, 5) End If End If sumob = sumob + costoal Worksheets("red" & red).Activate Range("3:3").Select Selection.Find(What:=ciudades(almacen, 1), After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _ xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True _ , SearchFormat:=False).Activate ActiveCell.Cells(0, 2) = costoal Else ReDim tsp(1 To nodosal, 2) ReDim tsp1(1 To nodosal, 2) ReDim tsp2(1 To nodosal + 2, 3) ReDim tsp3(1 To nodosal + 2, 3) Worksheets("ciudades").Activate For z = 1 To nodosal numnodo = Worksheets("provisional").Range("A" & z + 2).Value tsp(z, 1) = ciudades(numnodo, 1) tsp(z, 2) = numnodo Next tsp2(1, 1) = ciudades(almacen, 1) tsp2(1, 2) = almacen tsp2(nodosal + 2, 1) = ciudades(almacen, 1) tsp2(nodosal + 2, 2) = almacen sum2 = 0 ‘aqui se genera el ciclo para el almacen correspondiente y se va almacenando el de menor costo en una variable. For h = 1 To 1000 Randomize poscon = nodosal tsp1() = tsp() For x = 1 To nodosal If poscon = 1 Then conreg = 1 Else Do Until conreg <> 0 And conreg <> poscon + 1 conreg = Int(poscon * Rnd) Loop End If pos = 1 For y = 1 To conreg If tsp1(pos, 2) <> 0 Then pos = pos + 1 Else y=y-1 pos = pos + 1 End If Next tsp2(x + 1, 1) = tsp1(pos - 1, 1) tsp2(x + 1, 2) = tsp1(pos - 1, 2) tsp1(pos - 1, 2) = 0 poscon = poscon - 1 Next sum1 = 0 For x = 1 To nodosal + 1 coor1 = tsp2(x, 2) coor2 = tsp2(x + 1, 2) tsp2(x, 3) = tablas(coor1, coor2) sum1 = sum1 + tablas(coor1, coor2) Next If sum2 = 0 Or sum1 < sum2 Then tsp3() = tsp2() sum2 = sum1 End If Next sumob = sumob + sum2 If datos(almacen, 3) = 0 Then costoal = datos(almacen, 4) + datos(almacen, 5) * demanda Else If demanda * (1 + datos(almacen, 6)) < datos(almacen, 2) Then costoal = datos(almacen, 4) + demanda * (1 + datos(almacen, 6)) * datos(almacen, 5) Else costoal = datos(almacen, 4) + datos(almacen, 2) * datos(almacen, 5) End If End If sumob = sumob + costoal Worksheets("red" & red).Activate Range("3:3").Select Selection.Find(What:=ciudades(almacen, 1), After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _ xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True _ , SearchFormat:=False).Activate ActiveCell.Cells(0, 2) = costoal For x = 1 To nodosal + 1 ActiveCell.Value = tsp3(x, 1) ActiveCell.Cells(1, 2) = tsp3(x, 3) ActiveCell.Cells(2, 1).Activate Next End If Next Worksheets("red" & red).Activate Range("A1").Select For i = 0 To numal - 1 ActiveCell.Cells(2, i * 3 + 1).Value = "Sucesión" ActiveCell.Cells(2, i * 3 + 1).Font.Bold = True ActiveCell.Cells(1, i * 3 + 2).Value = "Costo de ubicación" ActiveCell.Cells(1, i * 3 + 2).Font.Bold = True ActiveCell.Cells(3, i * 3 + 3).Value = "Costo" ActiveCell.Cells(3, i * 3 + 3).Font.Bold = True Next End Sub ‘muestrasolucion: en la hoja Solución correspondiente vacía los costos obtenidos para el mejor cromosoma. Sub muestrasolucion() solucion = "Solución (" & numal & ")" Sheets.Add On Error Resume Next ActiveSheet.Name = solucion If Err <> 0 Then Application.DisplayAlerts = False ActiveSheet.Select ActiveWindow.SelectedSheets.Delete Application.DisplayAlerts = True End If Worksheets(solucion).Activate Cells.Clear Range("A5").Value = "Ubicación" Range("A5").Select Selection.Interior.ColorIndex = 3 ActiveCell.Cells(1, numal + 2).Interior.ColorIndex = 3 Range("A6").Value = "Costo de ubicación" Range("A6").Select Selection.Interior.ColorIndex = 46 ActiveCell.Cells(1, numal + 2).Interior.ColorIndex = 46 Range("A7").Value = "Costo de transporte" Range("A7").Select Selection.Interior.ColorIndex = 3 ActiveCell.Cells(1, numal + 2).Interior.ColorIndex = 3 For i = 1 To numal Worksheets(redm).Activate Range("A3").Select ActiveCell.Cells(1, i * 3 - 2).Select ubi = ActiveCell.Value costub = ActiveCell.Cells(0, 2) costran = 0 Do Until IsEmpty(ActiveCell) costran = costran + ActiveCell.Cells(1, 2).Value ActiveCell.Cells(2, 1).Select Loop Worksheets(solucion).Activate Range("A5").Select ActiveCell.Cells(1, i + 1).Select ActiveCell.Value = ubi ActiveCell.Cells(2, 1).Value = costub ActiveCell.Cells(3, 1).Value = costran modu = i Mod 2 If modu = 0 Then ActiveCell.Interior.ColorIndex = 43 ActiveCell.Cells(2, 1).Interior.ColorIndex = 4 ActiveCell.Cells(3, 1).Interior.ColorIndex = 43 Else ActiveCell.Interior.ColorIndex = 4 ActiveCell.Cells(2, 1).Interior.ColorIndex = 43 ActiveCell.Cells(3, 1).Interior.ColorIndex = 4 End If Next Range("A5").Select ActiveCell.Cells(1, numal + 2).Value = "Totales" ActiveCell.Cells(4, numal + 1).Value = "Total" ActiveCell.Cells(4, numal + 1).Interior.ColorIndex = 3 total = ActiveCell.Cells(2, numal + 1).Address ActiveCell.Cells(2, numal + 2).Formula = "=sum(B6:" & total & ")" total = ActiveCell.Cells(3, numal + 1).Address ActiveCell.Cells(3, numal + 2).Formula = "=sum(B7:" & total & ")" total = ActiveCell.Cells(2, numal + 2).Address total1 = ActiveCell.Cells(3, numal + 2).Address ActiveCell.Cells(4, numal + 2).Formula = "=sum(" & total & ":" & total1 & ")" ActiveCell.Cells(4, numal + 2).Interior.ColorIndex = 5 Cells.Select With Selection.Font .Name = "Arial" .Size = 18 .Strikethrough = False .Superscript = False .Subscript = False .OutlineFont = False .Shadow = False .Underline = xlUnderlineStyleNone .ColorIndex = xlAutomatic .Bold = True End With Cells.Select Selection.EntireColumn.AutoFit Selection.Style = "Currency" End Sub