954,517 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Variable names to subroutines. Vbnet

Hello, I'm new to this forum.
Right now I'm developing a software based on Genetic Algorithms. I really have almost none experience, and I have a question.

First of, this software is a prototype, a template. So the user can choose between a lot of choices (types of crossing and mutations). And I have many radio buttons for that.
The question, like in the thread title is, can I give the name of a suroutine to a variable, so that sub executes instead of making a comparisson about which radio button is selecten, THEN execute the sub of that option. This is sort of the problem:


for i=0 to 1000 ' A long for statement
if radiobutton1.checked = true then
method1(var1, var2)
elseif radiobutton2.checked = true then
method2(var1, var2)
...
else
methodn(var1, var2)
endif

some other code..
next


And I want something like:


if radiobutton1.checked = true then
method = method1(var1, var2)
elseif radiobutton2.checked = true then
method = method2(var1, var2)
...
else
method = methodn(var1, var2)
endif

for i = 0 to 1000
method(var1, var2)
some other code...
next

I'm studying Software Engineering but I'm just starting really.
And sorry for my bad english (not my language).

Pundia
Newbie Poster
21 posts since Jul 2010
Reputation Points: 10
Solved Threads: 0
 

It is not possible to assign a method to a variable like that.
But you can create a class that holds all those methods, where you tell the constructor which method to execute.
Like this:

Public Class Methods
   Private strMethodName As String
   Private objVar1 As Object
   Private objVar2 As Object

   Public Sub New(NameOfMethod As String)
      Me.strMethodName = NameOfMethod
   End Sub

   Public Function Method(Var1 As Object, Var2 As Object) As Object
      objVar1 = Var1
      objVar2 = Var2

      Select Case strMethodName
         Case "method1":
            Return method_1()
         Case "method2":
            Return method_2()
         'And so on
         Else
            Return method_n()
      End Select
   End Function

   Private Function method_1() As Object
      'Do something with var1 and var2
      Return result
   End Function

   Private Function method_2() As Object
      'Do something else with var1 and var2
      Return result
   End Function

   Private Function method_n() As Object
      'Do something else with var1 and var2
      Return result
   End Function
End Class

Then do this in your code:

'This is your code
Dim clsMethods As Methods
If radiobutton1.checked = true then
   clsMethods = New Methods("method1")
ElseIf radiobutton2.checked = true then
   clsMethods = New Methods("method2")
Else
   clsMethods = New Methods("method3")
End If

For i = 0 To 1000
   Dim value As Object = clsMethods.Method(var1, var2)
   'Do something with the value
Next
Oxiegen
Master Poster
715 posts since Jun 2006
Reputation Points: 87
Solved Threads: 141
 

I don't have return values. So they are subroutines, not functions, and they can't be "as object".
Also, I don't know how to use your line 12 in "do this in your code" part.

This is the class I made with your help:

Public Class Cruce
    Structure individuo
        Dim x() As Double
        Dim fx As Double
    End Structure
    Structure poblacion
        Dim ind() As individuo
    End Structure

    Private strMethodName As String
    Private objVar1 As Object
    Private objVar2 As Object
    Dim tpob, nvars, ngen, pto, p1, p2, ini As Integer

    Public Sub New(ByVal NameOfMethod As String)
        Me.strMethodName = NameOfMethod
    End Sub

    Public Sub Method(ByRef ind1 As individuo, ByRef ind2 As individuo)
        objVar1 = ind1
        objVar2 = ind2

        Select Case strMethodName
            Case "cruce_unpunto"
                cruce_unpunto(ind1, ind2)
            Case "cruce_dospuntos"
                cruce_dospuntos(ind1, ind2)
            Case "cruce_uniforme"
                cruce_uniforme(ind1, ind2)
            Case "cruce_intermedio"
                cruce_intermedio(ind1, ind2)
            Case "cruce_sbx"
                cruce_sbx(ind1, ind2)
            Case "cruce_arit"
                cruce_arit(ind1, ind2)
            Case Else
                cruce_arit_total(ind1, ind2)
        End Select
    End Sub


    Sub cruce_unpunto(ByRef ind1 As individuo, ByRef ind2 As individuo)
        'Cruce de un punto
        'Se elije un punto de cruza 
        'swap de valores de X entre individuos
        For i = 0 To pto
            swap_ind(ind1, ind2, i)
        Next

        For i = pto + 1 To UBound(ind1.x)
            swap_ind(ind1, ind2, i)
        Next
    End Sub
    Sub cruce_dospuntos(ByRef ind1 As individuo, ByRef ind2 As individuo)
        'Cruce de dos puntos
        'Se elijen dos puntos de cruza
        'y se intercambia lo que haya en el intermedio
        For i = p1 To p2
            swap_ind(ind1, ind2, i)
        Next
    End Sub
    Sub cruce_uniforme(ByRef ind1 As individuo, ByRef ind2 As individuo)
        'Se elije un numero n de puntos de cruce

    End Sub
    Public Sub swap_ind(ByRef ind1 As individuo, ByRef ind2 As individuo, ByVal i As Integer)
        Dim temp As Double
        temp = ind1.x(i)
        ind1.x(i) = ind2.x(i)
        ind2.x(i) = temp
    End Sub

    Sub cruce_intermedio(ByRef ind1 As individuo, ByRef ind2 As individuo)
        Dim a As Double = valor_random()
        For i = ini + 1 To UBound(ind1.x)
            ind1.x(i) = fun_cruce_int(i, ind1, ind2, a)
            ind2.x(i) = fun_cruce_int(i, ind2, ind1, a)
        Next
    End Sub
    Sub cruce_sbx(ByRef ind1 As individuo, ByRef ind2 As individuo)
        Dim u As Double = valor_random(), b, nc, p1, p2 As Double
        nc = 2
        'Obtener b
        If u > 0.5 Then
            b = (1 / (2 * (1 - u))) ^ (1 / (nc + 1))
        Else
            b = (2 * u) * (1 / (nc + 1))
        End If
        'Obtener valores de x
        For i = 0 To UBound(ind1.x)
            p1 = ind1.x(i)
            p2 = ind2.x(i)
            ind1.x(i) = 0.5 * ((p1 + p2) - b * Math.Abs(p1 - p2))
            ind2.x(i) = 0.5 * ((p1 + p2) - b * Math.Abs(p1 + p2))
        Next

    End Sub
    Function fun_cruce_int(ByVal i As Integer, ByRef ind As individuo, ByRef ind2 As individuo, ByVal a As Integer)
        Dim cruce As Double
        cruce = ind2.x(i) * a + ind.x(i) * (1 - a)
        Return cruce
    End Function

    Sub cruce_arit(ByRef ind1 As individuo, ByRef ind2 As individuo)
        Dim a As Double
        For i = ini + 1 To UBound(ind1.x)
            a = obtener_a(i, ind1, ind2)
            ind1.x(i) = fun_cruce_int(i, ind1, ind2, a)
            ind2.x(i) = fun_cruce_int(i, ind1, ind2, a)
        Next
    End Sub
    Function obtener_a(ByVal ini As Integer, ByRef ind1 As individuo, ByRef ind2 As individuo)
        Dim a, b, c, d, l, u, x As Double
        l = ind1.x(ini)
        u = ind1.x(ini)
        'Se buscan los limites superiores e inferiores
        For i = ini To UBound(ind1.x)
            If l > ind1.x(ini) Then
                l = ind1.x(ini)
            End If
            If l > ind2.x(ini) Then
                l = ind2.x(ini)
            End If
            If u < ind1.x(ini) Then
                u = ind1.x(ini)
            End If
            If u < ind2.x(ini) Then
                u = ind2.x(ini)
            End If
        Next

        a = (l - ind2.x(ini)) / (ind1.x(ini) - ind2.x(ini))
        b = (u - ind1.x(ini)) / (ind2.x(ini) - ind1.x(ini))
        c = (l - ind1.x(ini)) / (ind2.x(ini) - ind1.x(ini))
        d = (u - ind2.x(ini)) / (ind1.x(ini) - ind2.x(ini))

        If ind1.x(ini) > ind2.x(ini) Then
            x = Random(Random(a, b), Random(c, d))
        ElseIf ind1.x(ini) = ind2.x(ini) Then
            x = 0
        Else
            x = Random(Random(c, d), Random(a, b))
        End If
        Return x
    End Function
    Sub cruce_arit_total(ByRef ind1 As individuo, ByRef ind2 As individuo)
        Dim a As Double = valor_random()
        For i = 0 To UBound(ind1.x)
            ind1.x(i) = fun_cruce_int(i, ind1, ind2, a)
            ind2.x(i) = fun_cruce_int(i, ind2, ind1, a)
        Next
    End Sub

    Public Function posicion_random(ByRef ind As individuo)
        Microsoft.VisualBasic.VBMath.Randomize()
        Dim r As Integer
        r = Int((UBound(ind.x) + 1) * Rnd())
        Return r
    End Function
    Function valor_random()
        'valor random de 0 a 1
        Microsoft.VisualBasic.VBMath.Randomize()
        Dim m As Double
        m = Rnd()
        Return m
    End Function
    Public Function random(ByVal low, ByVal high)
        Microsoft.VisualBasic.VBMath.Randomize()
        Dim r As Integer
        r = (high - low + 1) * Rnd() + low
        Return r
    End Function

End Class
Pundia
Newbie Poster
21 posts since Jul 2010
Reputation Points: 10
Solved Threads: 0
 

Well.
Since you're using ByRef for the arguments, then line 12 can be changed into simply this: "cslsMethods.Method(var1, var2)".
Ie, remove the "Dim value As Object = " part.

Does this solution work for you?

Oxiegen
Master Poster
715 posts since Jun 2006
Reputation Points: 87
Solved Threads: 141
 

here a short example...

Sub Main()
	Dim msc As New MySubClass
		For i = 0 To 1000 ' A long for statement
			If radiobutton1.checked = True Then
				CallByName(msc, "Methode1", CallType.Method, New Object() {var1, var2})
			ElseIf radiobutton2.checked = True Then
				CallByName(msc, "Methode2", CallType.Method, New Object() {var1, var2})
			Else
				CallByName(msc, "Methode3", CallType.Method, New Object() {var1, var2})
			End If
		Next
	End Sub

Class MySubClass 'holds all methods that needs to be called

	Public Sub Methode1(ByVal s As String, ByVal i As Integer)
		Console.WriteLine(String.Format("string: {0}, Integer: {1}", s, i))
	End Sub

	Public Sub Methode2(ByVal s As String, ByVal i As String)
		Console.WriteLine(String.Format("String: {0}, Second string: {1}", s, i))
	End Sub

End Class
GeekByChoiCe
Master Poster
721 posts since Jun 2009
Reputation Points: 208
Solved Threads: 168
 

I see.
But your original question was "Is it possible to assign a method to a variable?".
And the answer is No, which is why I gave you a solution, that you built your own solution on.

Now I'm asking you, does it work?
Is your problem solved?

Oxiegen
Master Poster
715 posts since Jun 2006
Reputation Points: 87
Solved Threads: 141
 

I see. But your original question was "Is it possible to assign a method to a variable?". And the answer is No, which is why I gave you a solution, that you built your own solution on.

Now I'm asking you, does it work? Is your problem solved?

It wasn't me who wrote that last post.
Now I have another question. When I do this:

clsMethods.Method(pob.ind(i), pob.ind(i + 1))


I have this error:Error 1 Value of type 'templateag3.Form1.individuo' cannot be converted to 'templateag3.Cruce.individuo'.

I copied the struct "individuo" to the class, but I need that same struct in the Form1 as well. How can I use just one struct that is valid for both class and form?

Pundia
Newbie Poster
21 posts since Jul 2010
Reputation Points: 10
Solved Threads: 0
 

Oops. Didn't look at the name of the poster. My bad. :)

You can create a structure outside the class and make it public.
Now it will be accessible from anywhere.

Public Structure individuo
   Dim x() As Double
   Dim fx As Double
End Structure
Public Structure poblacion
   Dim ind() As individuo
End Structure

Public Class Cruce
...
End Class
Oxiegen
Master Poster
715 posts since Jun 2006
Reputation Points: 87
Solved Threads: 141
 

Thank you! It works now!

Pundia
Newbie Poster
21 posts since Jul 2010
Reputation Points: 10
Solved Threads: 0
 

Solved, sorry. Moved the "Dim clsMethods As New Cruce" at the top. Didn't work before because the "if statement" was in a separate Sub from the "for statement".


I just runned the program with the debug mode, and it does not work. At first it gave me an error and generated this for me:
The error:
Error 1 Argument not specified for parameter 'NameOfMethod' of 'Public Sub New(NameOfMethod As String)'.

Sub New()
        ' TODO: Complete member initialization 
    End Sub


This is the code you gave me, and the program ignores it:

Sub New(ByVal NameOfMethod As String)
        Me.strMethodName = NameOfMethod
    End Sub


It just goes to the "else" when it compares the name of the method. That's why it seemed to work. What can I do?

The error is here:

Dim clsMethods As New Cruce
Pundia
Newbie Poster
21 posts since Jul 2010
Reputation Points: 10
Solved Threads: 0
 

I suggest that you follow the coding in the second snippet I gave in my first respons to you.
It states, with the name of your class:

Dim clsMethods As Cruce
If radiobutton1.checked = true then
   clsMethods = New Cruce("method1")
ElseIf radiobutton2.checked = true then
   clsMethods = New Cruce("method2")
Else
   clsMethods = New Cruce("method3")
End If

clsMethods.Method(pob.ind(i), pob.ind(i + 1))
Oxiegen
Master Poster
715 posts since Jun 2006
Reputation Points: 87
Solved Threads: 141
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: