mirror of
https://github.com/KeymonSoft/Ruteador-NonUI.git
synced 2026-04-17 12:56:10 +00:00
- Se agregó el HASH al JSON que regresa cuando se genera el ruteo.
408 lines
22 KiB
QBasic
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 |