Hola a todos y buenas noches o dias:
Estuve leyendo acerca del Programa para hacer combinaciones de numeros, y vi que el usuario pkj, hizo y modifico un programa en vb 6.0, y lo puse en vb.net 2010, en donde podias poner el tamaño del grupo y la lista de numeros que querias formar, yo quiero calcular y grabar en un archivo todas las combinaciones de 8 grupos de 2, ya sea numero, letras o la combinacion, por ejemplo el grupo de 8 seria: "AA,BB,CC,15,EE,20,GG,01" y calcular todas las varibles que pueden salir, segun en el propio programa, el total de variables son 40320, y yo deseo grabar todas esas variables, claro, sin repetir.
Al momento de ejecutar el programa con las variables ya descritas, solo hace el primer calculo o mejor dicho, coge las primeras variables, hasta ahi, todo bien, pero, ya no hace los otros calculo, solo saca la primera linea y termina, estuve observando y si muevo el total de la matriz donde guarda los datos obtenidos, me manda error en la matriz de los numeros.
Les paso el link en donde el usuario PKJ (agradezco su valiosa aportacion, ya que es lo que deseo) pone su programa, esta en vb 6.0:
https://foro.elhacker.net/programacion_visual_basic/programa_para_hacer_combinaciones_de_numeros-t414603.10.html
Yo le hice pequeñas modificaciones, les paso el programa para que me puedan orientar o en su defecto ayudar, esta en vb.net 2010
Public Class Form1
Public TamGrupos As Integer = 8 ' Tamaño de los grupos
Public ListaDeNumeros As String = "AA,BB,CC,DD,EE,FF,GG,HH" ' lista de numeros separados por comas
Public Parar As Integer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Parar = 1
End Sub
Private Function CalculaTotal(ByVal TamGrupos As Integer, ByVal MaximoValor As Integer) As Long
Dim C1 As Double
Dim C2 As Double
Dim F As Double
C1 = 1
C2 = 1
For F = 1 To TamGrupos
C1 = C1 * F
Next F
For F = MaximoValor To (MaximoValor - (TamGrupos - 1)) Step -1
C2 = C2 * F
Next F
CalculaTotal = C2 / C1
End Function
Private Sub CreaGrupos(ByVal TamGrupos As Integer, ByVal TopeOListaDeNumerosSeparadosPorComas As String, ByRef ListaDevuelta() As String)
' Busqueda de combinaciones.
' Dados los numeros de TopeOListaDeNumerosSeparadosPorComas,
' saca todos los grupos no repetidos de "TamGrupos" numeros
' y los devuelve en la matriz Lista()
' Por repetido se entiende que "1,2,3" es igual que "1,3,2", igual que "2,1,3", etc...
' Ejm: 1,2,3,4 de 2 en 2 = 6 combinaciones
' 1,2 - 1,3 - 1,4 - 2,3 - 2,4 - 3,4
' Opcionalmente, en lugar de una lista de números puedes poner un solo número.
' En ese caso la listadenumeros seran los números desde el 1 hasta el que pongas.
Dim F As Double
Dim Linea As String
Dim Num As Double
Dim Total As Double
Dim Ap() As Double
Dim MaximoValor As Long
Dim MatrizDeNumeros() As String
MatrizDeNumeros = Split(TopeOListaDeNumerosSeparadosPorComas, ",")
MaximoValor = UBound(MatrizDeNumeros) + 1
If MaximoValor = 1 And Val(MatrizDeNumeros(0)) > 0 Then
MaximoValor = Val(MatrizDeNumeros(0))
ReDim MatrizDeNumeros(MaximoValor - 1)
For F = 1 To MaximoValor
MatrizDeNumeros(F - 1) = F
Next F
End If
Total = CalculaTotal(TamGrupos, MaximoValor)
ReDim Ap(TamGrupos)
ReDim ListaDevuelta(Total - 1)
Dim Contador As Long
Contador = -1
Parar = 0
' Cogemos las primeras
For F = 1 To TamGrupos
Ap(F) = F
Next F
OtraVez:
'Preparo la linea con la combinacion
Linea = ""
For F = 1 To TamGrupos - 1
Linea = Linea & MatrizDeNumeros(Ap(F) - 1) & " , "
Next F
Linea = Linea & MatrizDeNumeros(Ap(TamGrupos) - 1)
' Guardo la combiancion
Contador = Contador + 1
ListaDevuelta(Contador) = Linea
'Label4.Caption = Contador + 1 ' Muestro el progreso
Application.DoEvents()
If Parar = 1 Then GoTo Fin
Num = TamGrupos + 1
Repetir1:
Num = Num - 1 ' Cogemos la apuesta(num) (en principio la ultima)
'La aumentamos...
Ap(Num) = Ap(Num) + 1
' si es mayor de la cuenta...
If Ap(Num) > (MaximoValor - (TamGrupos - Num)) Then
' si es la ap(1) se acaba
If Num = 1 Then GoTo Fin
' ...aumentamos la anterior
GoTo Repetir1
End If
' Si no llega a su limite se mira si alguna ha llegado
' a su maximo
' Si NUM no apunta a la ultima AP() es que
' alguna ap() ha llegado a su maximo
' entonces reiniciamos todas las siguientes...
If Num <> TamGrupos Then
For F = Num + 1 To TamGrupos
'....dandoles el valor de la anterior + 1...
Ap(F) = Ap(F - 1) + 1
Next F
End If
' ... Y se da por valida
GoTo OtraVez
Fin:
Parar = 1
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If Parar = 0 Then Parar = 1 : Exit Sub
Dim Matriz() As String = Nothing ' matriz donde recibiremos la lista
CreaGrupos(TamGrupos, ListaDeNumeros, Matriz)
'Aqui manipulas la matriz como quieras
' por ejemplo pasandola a un listbox
ListBox1.Visible = False
Dim F As Long
For F = 0 To UBound(Matriz)
ListBox1.Items.Add(Matriz(F))
Next F
ListBox1.Visible = True
End Sub
End Class
De antemano Muchas GRACIAS!!! ;-)
Hola Arturoro.
No tengo muy claro lo que explicas ni como te ha salido el numero 40320.
Las combinaciones sin repetición de 8 elementos en grupos de 2 creo que serian algo como 7+6+5+4+3+2+1
En tu ejemplo:
7
AA,BB
AA,CC
AA,15
AA,EE
AA,20
AA,GG
AA,01
6
BB,CC
BB,15
BB,EE
BB,20
BB,GG
BB,01
5
CC,15
CC,EE
CC,20
CC,GG
CC,01
4
15,EE
15,20
15,GG
15,01
3
EE,20
EE,GG
EE,01
2
20,GG
20,01
1
GG,01
El problema que veo es que pones grupos de 8 donde deberias poner un 2
Public TamGrupos As Integer = 8 ' Tamaño de los grupos
De modo que solo te muestra 1 grupo con los 8 elementos
Saludos
Hola PKJ y gracias por responder ;-) :
Si, creo que no me explique bien, tu programa esta excelente, solo deseo que los 8 grupos con elementos de 2, haga las combinaciones, y debe de salir mas o menos asi:
GRUPO DE 8 CON 2 ELEMENTOS CADA UNO: AA,BB,CC,8E,Z1,X1,Y0,01 :rolleyes:
Las combinaciones serian mas o menos as1:
AA,BB,CC,8E,Z1,X1,Y0,01
BB,AA,CC,8E,Z1,X1,Y0,01
01,BB,AA,CC,8E,Z1,X1,Y0
CC,8E,Z1,X1,Y0,01,BB,AA
... Y asi sucesivamente hasta que ya no existan mas combinaciones, ya sea poner un listbox, o un archivo.
Gracias por todo y perdona mi ignorancia
SALUDOS!!! :laugh:
Entonces no es mi funcion lo que necesitas.
No se me ocurría por donde pillarlo, asi que he usado una sub recursiva muy chula que nos dejó seba123neo, con algunas modificaciones.
Aquí está la sub original:
http://foro.elhacker.net/programacion_vb/combinaciones_vb-t240009.0.html
Y esto es lo que he sacado:
Hace falta un command button y un listbox.
Option Explicit
Private Sub Command1_Click()
Dim F As Long
Dim F2 As Long
Dim Matriz1() As String
Dim Matriz2() As String
Dim MatrizFinal() As String
Dim Linea As String
Dim Contador As Long
Dim ListaElementos As String
List1.Clear
ListaElementos = "AA,BB,CC,15,EE,20,GG,01" ' max. 10 elementos
Matriz1 = Split(ListaElementos, ",") 'separamos los elementos
For F = 0 To UBound(Matriz1) ' creamos una linea con X numeros
Linea = Linea & CStr(F)
Next F
ReDim Matriz2(0)
Call Combinaciones(Linea, Matriz2) ' creamos la matriz con las combinaciones de los X numeros
ReDim MatrizFinal(0)
For F = 0 To UBound(Matriz2) - 1
Linea = ""
For F2 = 1 To UBound(Matriz1) + 1 ' reemplazamos los numeros por los elementos de la lista
Linea = Linea & Matriz1(Val(Mid$(Matriz2(F), F2, 1))) & ","
Next F2
ReDim Preserve MatrizFinal(Contador)
MatrizFinal(Contador) = Left(Linea, Len(Linea) - 1) 'guardamos quitando la ultima coma
Contador = Contador + 1
Next F
' mostramos el resultado
MsgBox "Total " & Contador & " grupos" ' mostramos la cantidad de grupos extraidos
For F = 0 To UBound(MatrizFinal)
List1.AddItem MatrizFinal(F) ' y los cargamos en el listbox
Next F
End Sub
Private Sub Combinaciones(Palabra As String, ByRef Matriz() As String, Optional strFixed As String)
Dim i As Integer
If Len(Palabra) > 1 Then
For i = 1 To Len(Palabra)
Combinaciones Left$(Palabra, i - 1) & Mid$(Palabra, i + 1), Matriz, strFixed & Mid$(Palabra, i, 1)
Next i
Else
Matriz(UBound(Matriz)) = strFixed & Palabra
ReDim Preserve Matriz(UBound(Matriz) + 1)
End If
End Sub
A la sub de seba123neo solo le he añadido una matriz donde ir dejando los grupos que luego convertiremos segun nuestra necesidad.
Es mejor usar matrices porque un listbox tiene más limitaciones de capacidad.
Espero que te sirva.
Saludos
Gracias PKJ, es exactamente lo que necesito ;-) , esta en vb 6.0, lo voy a convertir (jejeje!! si eso aplica) a vb.net 2010, y lo voy a subir, y tambien y como una pequeña aportacion y un gran gracias a PKJ, les pongo otro calculo de combinaciones en vb.net 2010, por si alguien le interesa y le saca provecho.
Solo necesitan 2 textbox, 1 listbox y 1 boton.
Public Class Form1
Sub Permutaciones(ByVal a() As String, ByVal j As Integer, ByVal k As Integer, ByVal lista As ListBox)
Dim i As Integer
Dim s As String = ""
Dim sTemp As String
If j = 1 Then
For i = 1 To k
s = s & a(i)
Next i
lista.Items.Add(s)
Else
For i = 1 To j
sTemp = a(i)
a(i) = a(j)
a(j) = sTemp
Permutaciones(a, j - 1, k, lista)
sTemp = a(j)
a(j) = a(i)
a(i) = sTemp
Next i
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
lbResultados.Items.Clear()
If txtVariables.Text.Trim.Length >= 2 Then
Dim x As Integer
Dim i As Integer
Dim a() As String
x = Len(txtVariables.Text)
ReDim a(x)
For i = 1 To Len(txtVariables.Text)
a(i) = Mid(txtVariables.Text, i, 1)
Next i
Permutaciones(a, x, x, lbResultados)
txtTotal.Text = lbResultados.Items.Count.ToString
Else
MsgBox("Introduzca un cadena valida")
End If
End Sub
End Class
GRACIAS POR TODO!!! ;-) :rolleyes: ;-) :rolleyes:
Lo siento, llego tarde al tema (es lo que sucede si publicas en la sección incorrecta).
Ya lo has solucionado de una manera, pero si por casualidad lees esto quiero preguntarte si el rendimiento es un factor importante para tu algoritmo, ya que en caso afirmativo entonces estás desaprovechando todo el potencial que .Net nos ofrece.
Para cálculos de complejidad computacional cómo son las permutaciones y combinaciones, puedes utilizar el paralelismo para ganar una elevada velocidad de procesamiento al utilizar todos los nucleos disponibles, y evitar todos esos wrappers de Vb6 que utilizaste reemplazándolos por el uso de LINQ (o al menos utilizar un For pero con los métodos de manipulación de string equivalentes y el método Array.Copy en lugar de ReDim), ganando así velocidad, mucho más estabilidad del algoritmo y reducción/legibilidad del código, a costa de perder una cantidad ínfima de rendimiento que ya habrías ganado al reemplazar el código vb6-estilizado.
Si lo necesitas dímelo y desarrollo una solución, pero trata de explicame mostrando un ejemplo con las expectativas del resultado de ejecución, ya que no me ha quedado del todo claro que quieres hacer con esos ocho grupos, como quieres calcular las permutaciones;
¿quieres intercambiar las posiciones de cada grupo preservando los 2 caracteres de cada grupo?, ¿o quieres sustituir de forma incrementativa cada caracter de cada grupo?.
Saludos!