B4J=true Group=Default Group ModulesStructureVersion=1 Type=Class Version=10 @EndOfDesignText@ Sub Class_Globals Dim popSize As Int = 128 Dim numIterations As Int = 100 Dim mutChance As Double = 0.4 Dim population As List Dim bestFitness As List Dim probabilities As List Dim laSolucion, laSolucion2 As individuoT Dim waypoints As List Type individuoT (indice As Int, individuo As List, fitness As Double) ', probabilities As Double Dim listaIndFit As List Dim inicioCont As Double = 0 Dim final As String = "" End Sub 'Initializes the object. You can add parameters to this method if needed. Public Sub Initialize ' waypoints = jsonP. End Sub 'Resumable Subs (wait for / sleep) in server handlers 'Resumable subs can only work when there is a message queue. 'By default, server handlers end when the Handle sub is completed. They do not create a message loop. 'If you want to wait for an event then you need to call StartMessageLoop and later StopMessageLoop. 'https://www.b4x.com/android/forum/threads/resumable-subs-wait-for-sleep-in-server-handlers.81833/ Sub Handle(req As ServletRequest, resp As ServletResponse) Log("##############################################################") Log("############# GA/Handle ########################") Log("##############################################################") Private coords As String = req.GetParameter("c") final = req.GetParameter("f") If coords <> "" Then Private latF As String = "0" Private lonF As String = "0" If final <> "" Then ' Coordenadas del punto final. Private tmpF() As String = Regex.Split(",", final) latF = tmpF(2) lonF = tmpF(1) End If waypoints.Initialize Private coords2() As String = Regex.Split(";", coords) For i = 0 To coords2.Length - 1 Private tmpS() As String = Regex.Split(",", coords2(i)) If (latF <> tmpS(2) And lonF <> tmpS(1)) Or i = 0 Then ' Quitamos las coordenadas del punto final de los waypoints para agregarlas despues waypoints.Add(CreateMap("id":tmpS(0), "lon":tmpS(1), "lat":tmpS(2))) End If Next If final <> "" Then waypoints.Add(CreateMap("id":tmpF(0), "lon":lonF, "lat":latF)) End If End If Log(waypoints) resp.ContentType = "text/html" ' Dim l0 As List ' l0.Initialize2(Array As Int(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)) ' resp.Write($"${l0}
"$) ' Log(l0) ' For i = 0 To 10 ' resp.Write($"${ShuffleList(l0)}
"$) '' Log(ShuffleList(l0)) ' Next ' Log($"${l0}${CRLF}${l1}"$) population.Initialize bestFitness.Initialize laSolucion.Initialize laSolucion2.Initialize population = GenInitialPopulation(population) inicioCont = DateTime.now For h = 0 To numIterations ' Log("#########################################################################################") ' Log("############################## NUEVA POBLACION ###################################") ' Log("#########################################################################################") ' Log(population) Private fitness As List listaIndFit.Initialize fitness.Initialize probabilities.Initialize For j = 0 To population.Size - 1 ' Log(j) Private thisFitness As Double = calculateTotalDistance(waypoints, population.get(j)) fitness.Add(thisFitness) Private indFit As individuoT indFit.indice = j indFit.individuo = population.get(j) indFit.fitness = thisFitness probabilities.Add(1.0 / popSize) 'indFit. listaIndFit.Add(indFit) 'Ponemos en listaIndFit, el Indice de la poblacion, el individuo y el fitness Next fitness.Sort(True) ' Log(fitness) listaIndFit.SortType("fitness", True) ' Ordenamos la lista por fitness. ' Log("BEST FITNESS" & listaIndFit.Get(0)) bestFitness.Add(listaIndFit.Get(0)) ' Agregamos la mejor a bestFitness. ' Log("***** listaIndFit: " & listaIndFit) ' Log(listaIndFit.Size) ' Modificamos las probabilidades de selección de individuos en la población. Private tmpIndFit As individuoT tmpIndFit = listaIndFit.Get(0) probabilities.Set(0, probabilities.Get(0) * 6) listaIndFit.Set(0, tmpIndFit) tmpIndFit = listaIndFit.Get(1) probabilities.set(1, probabilities.Get(1) * 6) listaIndFit.Set(1, tmpIndFit) For i = 0 To (popSize / 2) - 1 tmpIndFit = listaIndFit.Get(i) probabilities.set(i, probabilities.Get(i) * 3) listaIndFit.Set(i, tmpIndFit) Next ' Normalizamos las probabilidades de selección de individuos Private sum As Double = 0 For i = 0 To popSize - 1 sum = sum + probabilities.Get(i) Next For i = 0 To popSize - 1 tmpIndFit = listaIndFit.Get(i) probabilities.set(i, probabilities.Get(i) / sum) listaIndFit.Set(i, tmpIndFit) Next If h = numIterations Then bestFitness.SortType("fitness", True) laSolucion = bestFitness.Get(0) Log("#################################################################################") Log($"################ LA SOLUCION ES: ${CRLF}${laSolucion}"$) Log("#################################################################################") resp.Write($"# LA SOLUCION ES:
${CRLF}${laSolucion}
"$) resp.Write($"# PUNTOS: ${laSolucion.individuo.Size}
"$) DateTime.DateFormat="yyMMddHHmmss" Log("TIEMPO : " & ((DateTime.Now-inicioCont)/1000)) Private coords4 As String = "" Private laDist As Double = 0 Private lonAnt, latAnt As Double For v = 0 To laSolucion.individuo.Size - 1 ' Log( $"${laSolucion.individuo.Get(v)} - ${waypoints.Get(laSolucion.individuo.Get(v))}"$ ) Private lasCoords As Map = waypoints.Get(v) If coords4 = "" Then ' Generamos coordenadas para ver el mapa en osm.quelltextlich.at/ coords4 = $"${lasCoords.get("lon")},${lasCoords.get("lat")}"$ Else coords4 = $"${coords4}:${lasCoords.get("lon")},${lasCoords.get("lat")}"$ End If If v > 0 Then Private lasCoordsAnt As Map = waypoints.Get((v - 1)) laDist = laDist + Main.calculateDistance1(lasCoordsAnt.Get("lat"), lasCoordsAnt.Get("lon"),lasCoords.Get("lat"), lasCoords.Get("lon")) End If lonAnt = lasCoords.get("lon") latAnt = lasCoords.get("lat") Next If final <> "" Then ' Log($"${waypoints.Get(waypoints.Size-2).As(Map).Get("id")},${waypoints.Get(waypoints.Size-2).As(Map).Get("lat")}, ${waypoints.Get(waypoints.Size-2).As(Map).Get("lon")}, ${latF}, ${lonF}"$) ' Log(laDist) laDist = laDist + calculateDistance1(waypoints.Get(waypoints.Size-2).As(Map).Get("lat"), waypoints.Get(waypoints.Size-2).As(Map).Get("lon"), latF, lonF) ' Log(laDist) End If Log("DISTANCIA ORIGINAL: " & laDist) resp.Write($"# DISTANCIA ORIGINAL: ${NumberFormat2(laDist, 1, 2, 2, True)}
"$) Private coords4 As String = "" Private laDist As Double = 0 Private lonAnt, latAnt As Double For v = 0 To laSolucion.individuo.Size - 1 ' Log( $"${laSolucion.individuo.Get(v)} - ${waypoints.Get(laSolucion.individuo.Get(v))}"$ ) Private lasCoords As Map = waypoints.Get(laSolucion.individuo.Get(v)) If coords4 = "" Then ' Generamos coordenadas para ver el mapa en osm.quelltextlich.at/ coords4 = $"${lasCoords.get("lon")},${lasCoords.get("lat")}"$ Else coords4 = $"${coords4}:${lasCoords.get("lon")},${lasCoords.get("lat")}"$ End If If v > 0 Then Private lasCoordsAnt As Map = waypoints.Get(laSolucion.individuo.Get(v - 1)) ' Log($"${laSolucion.individuo.Get(v - 1)} -> ${laSolucion.individuo.Get(v)} = ${numberformat2(laDist, 1, 2, 2, True)} + ${Main.calculateDistance1(lasCoordsAnt.Get("lat"), lasCoordsAnt.Get("lon"),lasCoords.Get("lat"), lasCoords.Get("lon"))} = ${numberformat2(ladist + Main.calculateDistance1(lasCoordsAnt.Get("lat"), lasCoordsAnt.Get("lon"),lasCoords.Get("lat"), lasCoords.Get("lon")),1,2,2,True)}"$) laDist = laDist + Main.calculateDistance1(lasCoordsAnt.Get("lat"), lasCoordsAnt.Get("lon"),lasCoords.Get("lat"), lasCoords.Get("lon")) End If lonAnt = lasCoords.get("lon") latAnt = lasCoords.get("lat") Next Log("DISTANCIA MEJORADA: " & laDist) resp.Write($"# DISTANCIA MEJORADA: ${NumberFormat2(laDist, 1, 2, 2, True)}"$) ' Private laDistOrig As Double = 0 ' Private origCoords As String = "-98.367397,20.2885251:-98.3673986,20.2842333:-98.4171617,20.2875307:-98.4171617,20.2870722:-98.2018217,20.157312:-98.2037883,20.1579131:-98.2033956,20.1597869:-98.2037471,20.1600194:-98.3304542,20.2411999:-98.3675814,20.157501:-98.3981804,20.1613062:-98.3981877,20.1611756:-98.3981638,20.1611726:-98.3981838,20.1528387:-98.4105988,20.1604658:-98.4105797,20.1604658:-98.4106149,20.1601633:-98.4105995,20.1582812:-98.4171635,20.0934635:-98.3746171,20.0937065:-98.3113997,20.0373747:-98.3097373,20.0378:-98.3097854,20.0378621:-98.3097373,20.03822:-98.3091305,20.0382337:-98.3092364,20.0295646:-98.3020753,20.0281433:-98.2993573,19.9890079:-98.2994654,20.0191821:-98.2997214,20.0191883:-98.2998736,20.0373747:-98.2965265,20.0374267:-98.2974103,20.0382089:-98.2974578,20.0382999:-98.2998506,20.0373507:-98.3001282,20.0374151:-98.3011024,20.0382249:-98.3019379,20.0373344:-98.3024263,20.0382022:-98.3024866,20.0381959:-98.3047418,20.0372789:-98.3048551,20.0373969:-98.3087633,20.0373588:-98.3091585,20.038213:-98.3096702,20.0382294:-98.3098262,20.0382301:-98.3098019,20.0382226:-98.3098507,20.0382032:-98.309962,20.0382169:-98.310657,20.0382241:-98.3545391,20.0765822:-98.3674448,20.0883075:-98.3674109,20.0883744:-98.3717499,20.0904887:-98.3733305,20.0934303:-98.3729919,20.1005734:-98.3674397,20.1069279:-98.3597017,20.1002531:-98.3603581,20.0989735:-98.3578046,20.0983058:-98.3575839,20.0997116:-98.3571027,20.102067:-98.3575733,20.102067:-98.35414,20.106525:-98.3547467,20.1085665:-98.3569592,20.1102607:-98.3543659,20.097339:-98.354654,20.0976982:-98.355117,20.1066587:-98.3568694,20.1071554:-98.3571229,20.106387:-98.3602375,20.1011948:-98.359305,20.1076649:-98.3595572,20.1072504:-98.3600443,20.1044867:-98.360066,20.1044785:-98.367437,20.0989306:-98.3683624,20.097075:-98.3717737,20.0960621:-98.3732723,20.0958825:-98.3739688,20.0950052:-98.3744864,20.0959816:-98.3748629,20.0952055:-98.4171079,20.0942:-98.4171454,20.0950241:-98.4171373,20.0951271:-98.4171682,20.0969286:-98.4782102,20.0689478:-98.4821405,20.0794694:-98.5321791,20.0950872:-98.5316393,20.0950869:-98.5316151,20.0950928:-98.5313826,20.0950772:-98.5311545,20.0950977:-98.5311341,20.0950882:-98.5307409,20.0950772:-98.5310337,20.0880191:-98.5117017,20.0950945:-98.4964301,20.095097:-98.4954019,20.0950948:-98.4797164,20.0950921:-98.4793191,20.0950853:-98.4773212,20.0950898:-98.4731448,20.0950862:-98.4171953,20.0969398:-98.4171583,20.1079494:-98.4158139,20.1541421:-98.4185455,20.1598054:-98.4175739,20.1604813:-98.4171777,20.1600988:-98.4171707,20.1586434:-98.410603,20.1551811:-98.4018328,20.1582555:-98.4017017,20.1586705:-98.4015936,20.1598066:-98.3986541,20.1600943:-98.3981603,20.1599041:-98.3675814,20.1600466:-98.3674102,20.160304:-98.3674328,20.2380154:-98.3674147,20.2631807:-98.3580592,20.2664201:-98.348528,20.2820715:-98.3472617,20.2878516:-98.3470749,20.2869986:-98.3473113,20.285622:-98.3485247,20.2856734:-98.3485252,20.2840998:-98.3673448,20.2845417:-98.3674329,20.2875573:-98.3674382,20.287592:-98.3674382,20.2879142" '' Private origCoords As String = "ESE05002,-98.367397,20.2885251;ESE05003,-98.3674382,20.287592;ESE05004,-98.3674382,20.2879142;ESE05005,-98.3304542,20.2411999;ESE05006,-98.3674147,20.2631807;ESE05007,-98.348528,20.2820715;ESE05008,-98.3981838,20.1528387;ESE05009,-98.4158139,20.1541421;ESE05010,-98.410603,20.1551811;ESE05011,-98.4105995,20.1582812;ESE05012,-98.3674102,20.160304;ESE05013,-98.2018217,20.157312;ESE05014,-98.3986541,20.1600943;ESE05015,-98.3717737,20.0960621;ESE05016,-98.3733305,20.0934303;ESE05017,-98.354654,20.0976982;ESE05018,-98.3543659,20.097339;ESE05019,-98.3578046,20.0983058;ESE05020,-98.3597017,20.1002531;ESE05021,-98.359305,20.1076649;ESE05022,-98.367437,20.0989306;TSE0555000,-98.3683624,20.097075;115683,-98.3744864,20.0959816;115685,-98.3746171,20.0937065;115686,-98.3717499,20.0904887;115687,-98.4171454,20.0950241;115688,-98.4171373,20.0951271;115690,-98.4171953,20.0969398;115693,-98.3729919,20.1005734;115694,-98.3732723,20.0958825;115695,-98.4171635,20.0934635;115696,-98.4171583,20.1079494;115697,-98.35414,20.106525;115699,-98.355117,20.1066587;115701,-98.3575839,20.0997116;115702,-98.3575733,20.102067;115703,-98.3603581,20.0989735;115707,-98.3600443,20.1044867;115712,-98.3571027,20.102067;115713,-98.3602375,20.1011948;115714,-98.360066,20.1044785;115715,-98.3674397,20.1069279;115717,-98.3595572,20.1072504;115718,-98.3568694,20.1071554;115720,-98.3470749,20.2869986;115721,-98.3580592,20.2664201;115722,-98.3674329,20.2875573;115723,-98.4171617,20.2870722;115725,-98.3473113,20.285622;115726,-98.3485247,20.2856734;115728,-98.4171617,20.2875307;115734,-98.3673448,20.2845417;115740,-98.5307409,20.0950772;115741,-98.5313826,20.0950772;115742,-98.5311545,20.0950977;115743,-98.3092364,20.0295646;115744,-98.2993573,19.9890079;115745,-98.3001282,20.0374151;115746,-98.2998736,20.0373747;115747,-98.3113997,20.0373747;115748,-98.3048551,20.0373969;115749,-98.3981877,20.1611756;115750,-98.3981638,20.1611726;115751,-98.2033956,20.1597869;115752,-98.3981603,20.1599041;115753,-98.3675814,20.1600466;115754,-98.3981804,20.1613062;115755,-98.3675814,20.157501;115756,-98.2037883,20.1579131;115757,-98.4018328,20.1582555;115760,-98.4017017,20.1586705;115761,-98.2037471,20.1600194;115764,-98.5316151,20.0950928;115765,-98.4731448,20.0950862;115767,-98.4793191,20.0950853;115768,-98.4185455,20.1598054;115769,-98.4773212,20.0950898;115770,-98.4782102,20.0689478;115771,-98.5117017,20.0950945;115772,-98.5321791,20.0950872;115773,-98.5310337,20.0880191;115774,-98.4797164,20.0950921;115775,-98.4954019,20.0950948;115776,-98.4964301,20.095097;115778,-98.2974103,20.0382089;115779,-98.2974578,20.0382999;115780,-98.2997214,20.0191883;115781,-98.2965265,20.0374267;115782,-98.3096702,20.0382294;115783,-98.3020753,20.0281433;115784,-98.3097373,20.0378;115786,-98.3097373,20.03822;115787,-98.3024263,20.0382022;115788,-98.3024866,20.0381959;115789,-98.2998506,20.0373507;115792,-98.3098507,20.0382032;115793,-98.3019379,20.0373344;115794,-98.3098262,20.0382301;115795,-98.2994654,20.0191821;115797,-98.4171682,20.0969286;115799,-98.3748629,20.0952055;115803,-98.3739688,20.0950052;115843,-98.3087633,20.0373588;115844,-98.3098019,20.0382226;115845,-98.309962,20.0382169;115847,-98.3097854,20.0378621;115849,-98.3547467,20.1085665;115850,-98.3571229,20.106387;115851,-98.3569592,20.1102607;115852,-98.3011024,20.0382249;115853,-98.3545391,20.0765822;115854,-98.310657,20.0382241;115860,-98.4175739,20.1604813;115864,-98.5311341,20.0950882;357004,-98.3472617,20.2878516;357005,-98.3485252,20.2840998;357006,-98.3674328,20.2380154;357007,-98.3673986,20.2842333;357089,-98.4105797,20.1604658;357090,-98.4106149,20.1601633;357091,-98.4105988,20.1604658;357092,-98.4015936,20.1598066;357093,-98.4171777,20.1600988;357094,-98.4171707,20.1586434;357195,-98.5316393,20.0950869;357196,-98.4821405,20.0794694;357305,-98.3091585,20.038213;357306,-98.3091305,20.0382337;357307,-98.3674109,20.0883744;357308,-98.3674448,20.0883075;357309,-98.3047418,20.0372789;357651,-98.4171079,20.0942" ' ' Private oc() As String = Regex.Split(":", origCoords) ' For w = 0 To oc.Length - 1 ' Private lascoords2() As String = Regex.Split(",", oc(w)) ' Private lat2 As Double = lascoords2(1) ' Private lon2 As Double = lascoords2(0) ' If w > 0 Then ' Private lascoordsAnt2() As String = Regex.Split(",", oc(w - 1)) ' Private latAnt2 As Double = lascoordsAnt2(1) ' Private lonAnt2 As Double = lascoordsAnt2(0) ' laDistOrig = laDistOrig + Main.calculateDistance1(latAnt2, lonAnt2, lat2, lon2) ' End If ' Next ' Log("laDistOrig: " & laDistOrig) Log("Liga para ver la ruta en mapa:" & CRLF) Log($"https://osm.quelltextlich.at/viewer-js.html?kml_url=http://keymon.lat:9001/kmz.php?c=${coords4}"$) resp.Write($"
# FITNESS : ${CRLF}${NumberFormat2(laSolucion.fitness, 1, 2, 2, True)}"$) resp.Write($"
# TIEMPO : ${CRLF}${(DateTime.Now-inicioCont)/1000}"$) End If Private index1 As Int = 0 Private index2 As Int = 0 Private random As Double = 0 Private currSum As Double = 0 Private crossoverIndex As Int = 0 Private aGoesFirst As Int = 0 Private newPopulation As List newPopulation.Initialize ' newPopulation.Add(listaIndFit.Get(0)) ' Log(listaIndFit.Size) For k = 0 To popSize - 1 currSum = 0 random = getRandomInclusive For m = 0 To popSize - 1 currSum = currSum + probabilities.Get(m) ' Log(listaIndFit.Get(m).As(individuoT).probabilities) ' Log($">>>>>> currSum: ${currSum}, random: ${random}"$) If currSum >= random Then index1 = m Exit End If Next currSum = 0 random = getRandomInclusive For m = 0 To popSize - 1 currSum = currSum + probabilities.Get(m) currSum = currSum + probabilities.Get(listaIndFit.Get(m).As(individuoT).indice) ' Log(listaIndFit.Get(m).As(individuoT).probabilities) ' Log($">>>>>> currSum: ${currSum}, random: ${random}"$) If currSum >= random Then index2 = m Exit End If Next crossoverIndex = getRandomIntInclusive(1, waypoints.Size - 2) aGoesFirst = getRandomIntInclusive(0, 1) ' Log($"Index1: ${index1}, Index2: ${index2}, CrossoverIndex: ${crossoverIndex}, aGoesFirst: ${aGoesFirst}, WPS: ${waypoints.Size - 2}"$) If aGoesFirst = 0 Then newPopulation = genNewPopulation(newPopulation, crossoverIndex, population.Get(index1), population.Get(index2)) Else newPopulation = genNewPopulation(newPopulation, crossoverIndex, population.Get(index2), population.Get(index1)) End If If k = 0 Then newPopulation.Add(listaIndFit.Get(0).As(individuoT).individuo) ' Log("+++++ " & listaIndFit.Get(0)) End If Next population = newPopulation ' Log("POPULATION: " & CRLF & population.Get(0)) ' Log(listaIndFit) ' Log(listaIndFit.Size) Next End Sub Sub GenInitialPopulation(population0 As List) As List Dim individual As List Dim primero, tempInd As List Private pFinal As Int Dim shuffled As List Private nuevoIndividuo As List individual.Initialize primero.Initialize tempInd.Initialize shuffled.Initialize For i = 0 To waypoints.size - 1 ' Generamos un individuo con el orden original de la ruta (0,1,2,3,4,5... etc) individual.Add(i) Next primero.AddAll(individual) tempInd.AddAll(individual) population0.Add(primero) 'Agregamos el individuo con el orden original al principio de la poblacion. If final <> "" Then pFinal = tempInd.get(tempInd.Size - 1) Log("## " & tempInd) For i = 0 To popSize - 1 If final <> "" Then tempInd.RemoveAt(tempInd.Size - 1) ' Quitamos el punto final, porque es el punto final de la ruta. tempInd.RemoveAt(0) ' Quitamos el punto inicial, porque es el punto de inicio ' Log(tempInd) ' nuevoIndividuo = individual shuffled = ShuffleList(tempInd) ' Log(shuffled) shuffled.InsertAt(0, 0) If final <> "" Then shuffled.Add(pFinal) ' Agregamos el punto final al final del individuo. ' Log(shuffled) nuevoIndividuo.Initialize nuevoIndividuo.AddAll(shuffled) ' Log(nuevoIndividuo) ' Log("#") population0.Add(nuevoIndividuo) Next ' Log("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%") ' Log($"POPULATION0: ${population0}"$) Return population0 End Sub Sub ShuffleList(pl As List) As List ' Private l As List ' l = pl For i = pl.Size - 1 To 0 Step -1 Dim j As Int Dim k As Object j = Rnd(0, i + 1) k = pl.Get(j) pl.Set(j,pl.Get(i)) pl.Set(i,k) Next Return pl End Sub 'Calculate distance - Haversine 'Using average radius of earth 6378.137 km. Sub calculateDistance1(Latitude1 As Double, Longitude1 As Double, Latitude2 As Double, Longitude2 As Double) As Double 'ignore Return NumberFormat2(2 * 6378137 * ASin (Sqrt (SinD ((Latitude2 - Latitude1) * 0.5) * SinD ((Latitude2 - Latitude1) * 0.5) + CosD (Latitude1) * CosD (Latitude2) * SinD ((Longitude2 - Longitude1) * 0.5) * SinD ((Longitude2 - Longitude1) * 0.5))), 1, 2, 2, False) End Sub Sub calculateTotalDistance(waypoints0 As List, individual As List) As String Dim totalDistance As Double = 0 ' Log("*******************************************************************************") ' Log(individual) For i = 0 To individual.Size - 2 Private nuevaDist As Double = calculateDistance1(waypoints0.Get(individual.get(i)).As(Map).get("lat"), waypoints0.Get(individual.get(i)).As(Map).get("lon"), waypoints0.Get(individual.get(i+1)).As(Map).get("lat"), waypoints0.Get(individual.get(i+1)).As(Map).get("lon")) ' Log(">>>>>>> " & i & "|" & totalDistance & " + " & nuevaDist) totalDistance = totalDistance + nuevaDist ' Log($"${waypoints0.Get(individual.get(i))}, ${waypoints0.Get(individual.get(i)).As(Map).get("lon")}, ${waypoints0.Get(individual.get(i)).As(Map).get("lat")}"$) ' Log($"${waypoints0.Get(individual.get(i+1))}, ${waypoints0.Get(individual.get(i+1)).As(Map).get("lon")}, ${waypoints0.Get(individual.get(i+1)).As(Map).get("lat")}"$) ' Log( totalDistance) Next ' Log(totalDistance) Return totalDistance End Sub Sub getRandomInclusive As Double Private j As Double j = Rnd(0, 10000000000) j = j / 10000000000 ' Log(j) If j = 0 Then j = 1 ' Log(j) Return j End Sub Sub getRandomIntInclusive(Min0 As Int, Max0 As Int) As Int Min0 = Ceil(Min0) ' Redondeamos hacia arriba. Max0 = Floor(Max0) ' Redondeamos hacia abajo. Private j As Double j = Rnd(Min0, Max0 + 1) Return j End Sub Sub genNewPopulation(newPopulation As List, crossoverIndex As Int, individual1 As List, individual2 As List) As List Private newIndividual As List Private index1, index2 As Int Private random As Double Private lTemp1, lTemp2 As Int newIndividual.Initialize crossoverIndex = crossoverIndex + 1 ' Log(crossoverIndex + 1) For i = 0 To crossoverIndex - 1 newIndividual.Add(individual1.get(i)) Next For i = 0 To individual2.Size - 1 If newIndividual.IndexOf(individual2.get(i)) = -1 Then newIndividual.Add(individual2.get(i)) End If Next ' Log(newIndividual) random = getRandomInclusive ' Log(random & "|" & mutChance) ' Log(newIndividual.size) If random <= mutChance Then index1 = getRandomIntInclusive(1, newIndividual.Size - 1) index2 = getRandomIntInclusive(1, newIndividual.Size - 1) ' Log($"${index1}, ${index2}, ${newIndividual.Size}"$) ' Log(newIndividual) lTemp1 = newIndividual.Get(index1) lTemp2 = newIndividual.Get(index2) newIndividual.Set(index1, lTemp2) newIndividual.Set(index2, lTemp1) End If newIndividual.RemoveAt(newIndividual.IndexOf(newIndividual.Size - 1)) newIndividual.Add(newIndividual.Size) newPopulation.Add(newIndividual) ' Log(newIndividual) Return newPopulation End Sub Sub traeDistanciaDesdeMatriz(punto1 As Int, punto2 As Int) Private id1 As String = waypoints.Get(punto1).As(Map).Get("id") Private id2 As String = waypoints.Get(punto2).As(Map).Get("id") Private c As ResultSet = Main.db.ExecQuery($"select ${id1} from R113A68_7A7FC9F7_matriz where idT = '${id2}'"$) End Sub