TSP(Travelling Salesman) in VBNET - vb.net

I'm trying to implement the Traveling salesman problem algorithm in vbnet to find the fastest path that visits all points of a bidirectional and weighted matrix and how much is the cost. Can anyone help me?
I've tried several implementations, but none worked
Tried this but not working. Can someone help me?
Public Function FillGraph(lista As List(Of Cliente)) As Integer(,)
Dim graph As Integer(,) = New Integer(lista.Count, lista.Count) {}
Dim n As Integer = lista.Count
For i = 0 To lista.Count - 1
For j = 0 To lista.Count - 1
If lista.Item(i).Id = lista.Item(j).Id Then
graph(i, j) = 0
Else
graph(i, j) = GetDistanceBetweenTwoPoints(lista.Item(i).latitude, lista.Item(i).longitude, lista.Item(j).latitude, lista.Item(j).longitude)
End If
Next
Next
Return graph
End Function
Public Function findNextPermutation(ByVal data As List(Of Integer)) As Boolean
If data.Count <= 1 Then Return False
Dim last As Integer = data.Count - 2
While last >= 0
If data(last) < data(last + 1) Then Exit While
last -= 1
End While
If last < 0 Then Return False
Dim nextGreater As Integer = data.Count - 1
For i As Integer = data.Count - 1 To last + 1
If data(i) > data(last) Then
nextGreater = i
Exit For
End If
Next
data = swap(data, nextGreater, last)
data = reverse(data, last + 1, data.Count - 1)
Return True
End Function
Public Shared Function reverse(ByVal data As List(Of Integer), ByVal left As Integer, ByVal right As Integer) As List(Of Integer)
While left < right
Dim temp As Integer = data(left)
data(Math.Min(System.Threading.Interlocked.Increment(left), left - 1)) = data(right)
data(Math.Max(System.Threading.Interlocked.Decrement(right), right + 1)) = temp
End While
Return data
End Function
Public Function swap(ByVal data As List(Of Integer), ByVal left As Integer, ByVal right As Integer) As List(Of Integer)
Dim temp As Integer = data(left)
data(left) = data(right)
data(right) = temp
Return data
End Function
Private Function travllingSalesmanProblem(ByVal graph As Integer(,), ByVal s As Integer) As Integer
Dim vertex As List(Of Integer) = New List(Of Integer)()
For i As Integer = 0 To V - 1
If i <> s Then vertex.Add(i)
Next
Dim min_path As Integer = Int32.MaxValue
Do
Dim current_pathweight As Integer = 0
Dim k As Integer = s
For i As Integer = 0 To vertex.Count - 1
current_pathweight += graph(k, vertex(i))
k = vertex(i)
Next
current_pathweight += graph(k, s)
min_path = Math.Min(min_path, current_pathweight)
Loop While findNextPermutation(vertex)
routeTxt.Text = path
Return min_path
End Function

Related

Find folder with approximate name

I currently have a routine that searches up through the directory where a file is saved and finds a folder called "$Fabrication Data".
I am working on a new addition that will be subbed into my existing code to allow for some human error, aka slight misspelling/misformating if that folder name.
I would like to examine each folder in the 'Path' directory (but not its sub folders). Currently it returns a match:
Path\SubFolder$Fabrication Data$
instead if the path I want:
Path$ Fabrication Data
Bonus question... I am currently returning any folder that is above a .8 match, how can I return the closest match if there are multiple folders above .8 match?
Dim Path As String = "N:\Stuff\More Stuff\More More Stuff\Project Folder"
For Each d In System.IO.Directory.GetDirectories(Path)
For Each sDir In System.IO.Directory.GetDirectories(d)
Dim sdirInfo As New System.IO.DirectoryInfo(sDir)
Dim similarity As Single = GetSimilarity(sdirInfo.Name, "$Fabrication Data")
If similarity > .8 Then
sFDPath = Path & "\" & sdirInfo.Name
MsgBox(sFDPath)
Else
End If
Next
Next
End Sub
Public Function GetSimilarity(string1 As String, string2 As String) As Single
Dim dis As Single = ComputeDistance(string1, string2)
Dim maxLen As Single = string1.Length
If maxLen < string2.Length Then
maxLen = string2.Length
End If
If maxLen = 0.0F Then
Return 1.0F
Else
Return 1.0F - dis / maxLen
End If
End Function
Private Function ComputeDistance(s As String, t As String) As Integer
Dim n As Integer = s.Length
Dim m As Integer = t.Length
Dim distance As Integer(,) = New Integer(n, m) {}
' matrix
Dim cost As Integer = 0
If n = 0 Then
Return m
End If
If m = 0 Then
Return n
End If
'init1
Dim i As Integer = 0
While i <= n
distance(i, 0) = System.Math.Min(System.Threading.Interlocked.Increment(i), i - 1)
End While
Dim j As Integer = 0
While j <= m
distance(0, j) = System.Math.Min(System.Threading.Interlocked.Increment(j), j - 1)
End While
'find min distance
For i = 1 To n
For j = 1 To m
cost = (If(t.Substring(j - 1, 1) = s.Substring(i - 1, 1), 0, 1))
distance(i, j) = Math.Min(distance(i - 1, j) + 1, Math.Min(distance(i, j - 1) + 1, distance(i - 1, j - 1) + cost))
Next
Next
Return distance(n, m)
End Function ```
You can track the ratings for each folder using a simple class like this:
Public Class FolderRating
Public Rating As Single
Public Folder As String
Public Sub New(folder As String, rating As Single)
Me.Folder = folder
Me.Rating = rating
End Sub
End Class
Then, create a List:
Dim ratings As New List(Of FolderRating)
In your loop, when you find a rating that is above 0.8, add it to the list:
If similarity > 0.8 Then
Dim sFDPath As String = Path & "\" & sdirInfo.Name
ratings.Add(New FolderRating(sFDPath, similarity))
End If
Finally, sort the list:
ratings.Sort(Function(x, y) x.Rating.CompareTo(y.Rating))
You can then take the last value in the list and it will be your most similar folder, if any:
Dim bestMatch As FolderRating = ratings.LastOrDefault

How can i make equal two references by using RETURN VB.Net

I have this codes
Public ReceteSN As String()
Public EldenSN As String()
and
Private Function degerata(ByVal i As Integer) As String()
If i = 0 Then Return EldenSN
If i = 1 Then Return UrunCikisSN
End Function
and
Public Sub Set2()
Dim x As Short
Dim y As Short
For x = 0 To obj.Length - 1
For y = 0 To obj(x).Length - 1
degerata(x)= "identify" & x
Next
Next
End Sub
But i can not return my references by using SUB FUNCTION. how can i make EldenSN(0) = "indetify0" ?

Using individual value from multiple values returned by a function VB.net

I have a function which returns average RGB value of a region drawn on a picturebox in VB.net.
The code is as below:
Function GetAvgRGB(ByVal CrdY As Integer, ByVal CrdX As Integer, ByVal Region As System.Drawing.Rectangle) As Tuple(Of Integer, Integer, Integer)
Dim totalR As UInteger
Dim totalG As UInteger
Dim totalB As UInteger
For y As Integer = CrdY - (Region.Height / 2) To CrdY + ((Region.Height / 2) - 1)
For x As Integer = CrdX - (Region.Width / 2) To CrdX + ((Region.Width / 2) - 1)
totalR += myBitmap.GetPixel(x, y).R
totalG += myBitmap.GetPixel(x, y).G
totalB += myBitmap.GetPixel(x, y).B
Next
Next
Dim pixelCount As Integer = Region.Width * Region.Height
Dim averageR As Integer = CType(totalR \ pixelCount, Integer)
Dim averageG As Integer = CType(totalG \ pixelCount, Integer)
Dim averageB As Integer = CType(totalB \ pixelCount, Integer)
Return Tuple.Create(averageR, averageG, averageB)
End Function
My query is how do I separate the values of R, G & B returned by this function..
Use the Item property.
Dim myTuple = GetAvgRGB(?,?,?)
Dim r = myTuple.Item1 ' g = .Item2, b = .Item3

Convert 1DPointArray into 2DPointArray

I started a new project which loads and saves tilesets in style of ini-datas.
The problem is now, that it loads the tiles into a 1d- list, which got copied sorted into a 1d-array.
Now I am trying to convert this sorted 1d-array into a 2d-array.
My try:
LoadedTiles.Sort(Function(p1, p2) (p1.Position.X.CompareTo(p2.Position.X)))
LoadedTiles.Sort(Function(p1, p2) (p1.Position.Y.CompareTo(p2.Position.Y)))
Dim currentArray(AmountTiles) As Tile
currentArray = LoadedTiles.ToArray
Dim lengthX, lengthY As Integer
Dim yAxis As Integer = currentArray(0).Position.Y
For Each p In currentArray
If Not p.Position.Y = yAxis Then
lengthX = (p.Position.X / p.Size.Width)
lengthY = (currentArray(currentArray.Length - 1).Position.Y / p.Size.Width)
Else
lengthX = (currentArray(currentArray.Length - 1).Position.X / p.Size.Width)
lengthY = 0
End If
Next
MapTiles = New Tile(lengthX, lengthY) {}
Dim ii As Integer
For x = 0 To lengthX
For y = 0 To lengthY
MapTiles(x, y) = currentArray(ii)
If Not ii >= currentArray.Length - 1 Then
ii += 1
End If
Next
Next
This gives a wrong output.
See picture below:
http://www.directupload.net/file/d/3690/pz8x98jr_png.htm
Is it possible to do it right?
Thanks alot!
The k-th element in a 1D array can correspond to row i=k/N and column j=k%N where N is the number of columns. The reverse is k=i*N+j
Ok guys, I got it ( =
Public Class Form1
Dim List As New List(Of Point)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
List.Add(New Point(180, 360))
List.Add(New Point(180, 180))
List.Add(New Point(180, 540))
'Convert 1d to 2d
Dim count As Point = countXYAxis(List, 180)
MsgBox(count.ToString)
Dim p(count.X - 1, List.Count - 1) As Point
MsgBox(p.Length)
Dim rofl As Integer
For i = 0 To p.GetUpperBound(0)
For j = 0 To p.GetUpperBound(1)
p(i, j) = List(rofl)
If Not rofl >= List.Count - 1 Then
rofl += 1
End If
Next
Next
For Each t In p
MsgBox(t.ToString)
Next
End Sub
Private Function countXYAxis(ByVal pt As List(Of Point), ByVal size As Integer) As Point
Dim bufferY As New List(Of Integer)
Dim cP As New Point
For Each pts In pt
If Not bufferY.Contains(pts.Y) Then
bufferY.Add(pts.Y)
End If
Next
For i = 0 To pt.Count - 1
If pt(i).Y = bufferY(0) Then
Else
cP = New Point(pt(i).X / size, bufferY.Count)
End If
Next
Return cP
End Function
End Class

VB .net - shortest and fastest way to find Nth occurrence of char in string?

What is the professional way to achieve this?
Thanks.
I've shamelessly ripped off the example from this question and converted it from C# to VB.net.
Public Function GetNthIndex(s As String, t As Char, n As Integer) As Integer
Dim count As Integer = 0
For i As Integer = 0 To s.Length - 1
If s(i) = t Then
count += 1
If count = n Then
Return i
End If
End If
Next
Return -1
End Function
Here's a way to do it with Linq.
Public Function GetNthIndex(searchString As String, charToFind As Char, n As Integer) As Integer
Dim charIndexPair = searchString.Select(Function(c,i) new with {.Character = c, .Index = i}) _
.Where(Function(x) x.Character = charToFind) _
.ElementAtOrDefault(n-1)
Return If(charIndexPair IsNot Nothing, charIndexPair.Index, -1)
End Function
Usage:
Dim searchString As String = "Assessment"
Dim index As Integer = GetNthIndex(searchString, "s", 4) 'Returns 5
My Version of Andew's but I believe this takes into account if the first character is the character you are looking for
Public Function GetNthIndexStringFunc(s As String, t As String, n As Integer) As Integer
Dim newFound As Integer = -1
For i As Integer = 1 To n
newFound = s.IndexOf(t, newFound + 1)
If newFound = -1 Then
Return newFound
End If
Next
Return newFound
End Function
If you're going for faster:
Public Function NthIndexOf(s As String, c As Char, n As Integer) As Integer
Dim i As Integer = -1
Dim count As Integer = 0
While count < n AndAlso i >= 0
i = s.IndexOf(c, i + 1)
count += 1
End While
Return i
End Function
Although it is slightly slower than Mike C's answer if you're looking for the nth "a" in a long string of "a"s (for example).
Edit: adjusted following spacemonkeys' comment.