Files
Ruteador-NonUI/Genetic_Algorithm.bas
Jose Alberto Guerra Ugalde b44f28abc9 - Cambios en el Algoritmo Genetico.
- Se agregó el HASH al JSON que regresa cuando se genera el ruteo.
2024-05-07 05:47:08 -06:00

408 lines
22 KiB
QBasic

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}<br>"$)
' Log(l0)
' For i = 0 To 10
' resp.Write($"${ShuffleList(l0)}<br>"$)
'' 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($"<b># LA SOLUCION ES:</b><br>${CRLF}${laSolucion}<br>"$)
resp.Write($"<b># PUNTOS:</b> ${laSolucion.individuo.Size}<br>"$)
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($"<b># DISTANCIA ORIGINAL: </b>${NumberFormat2(laDist, 1, 2, 2, True)}<br>"$)
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($"<b># DISTANCIA MEJORADA: </b>${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($"<br><b># FITNESS :</b> ${CRLF}${NumberFormat2(laSolucion.fitness, 1, 2, 2, True)}"$)
resp.Write($"<br><b># TIEMPO :</b> ${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