Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 18
  1. #1

    [VB6] combinazioni coefficiente binomiale

    Salve a tutti, ho trovato un algoritmo che mi visualizza tutte le combinazioni semplici (la cui somma è data dal coefficiente binomiale) dati N numeri, in classi di K (con K< N) che posto perchè spero potrà essere utile anche a qualcun'altro. Il mio problema è che vorrei che visualizzasse le combinazioni in classe K di qualsiasi vettore di N numeri, mentre se inserisco 4 numeri a caso (diciamo 9-12-19-24) in classe 2 per esempio mi rende:

    1 2
    1 3
    1 4
    2 3
    2 4
    3 4

    invece di

    9 12
    9 19
    9 24
    ...
    non riesco a dargli in input il vettore che vorrei, e non so se agire all'interno dell'algoritmo oppure nel momento in cui riscrive i riultati sulla textbox. Spero di essermi spiegato bene


    codice:
    Public Function CombinazioniS(ByVal N&, ByVal K&, CombiS&()) As Boolean
    '
    '   Ritorna, nella matrice CombiS(Cnk(N, K), K) con N >= K
    '   e K > 0, le combinazioni semplici di N oggetti della classe K:
    '
        
        N = Val(lblSelezionati.Caption)
        K = Val(ElemScelti)
        Dim R&, NR&, c&, P&
        Dim progresso As Double
        progresso = 0
    '
        On Error GoTo CombinazioniS_ERR
    '
        NR = Cnk(N, K)  ' Numero delle righe.
        ReDim CombiS(1 To NR, 1 To K)
    '
        ' Scrivo la prima riga:
        For c = 1 To K
            CombiS(1, c) = c
        Next c
    '
        ' Righe rimanenti:
        For R = 2 To NR
    '
            P = K
            Do Until CombiS(R - 1, P) < N - K + P
                P = P - 1
            Loop
    
            For c = 1 To P - 1
                CombiS(R, c) = CombiS(R - 1, c)
            Next c
    '
            CombiS(R, P) = CombiS(R - 1, P) + 1
    '
            For c = P + 1 To K
                CombiS(R, c) = CombiS(R, c - 1) + 1
            Next c
            progresso = progresso + 1
            ProgressBar.Value = progresso * 100 / NR
    '
        Next R
    '
    '
    CombinazioniS_ERR:
        CombinazioniS = (Err = 0)
        If (Err <> 0) Then
            Dim M$
            M$ = "Err. N° " & Err.Number & "  " & Err.Description & vbNewLine
            MsgBox M$, vbCritical, " Function CombinazioniS"
        End If
    '
    '
    '
    End Function
    Successivamente scrivo le combinazioni su una textbox

    codice:
        If CombinazioniS(N, K, CombiS()) Then
            txtCombi.Text = strTabella$(CombiS())
        Else
            txtCombi.Text = ""
        End If

    codice:
    Private Function strTabella$(Tabella&(), Optional ByVal LimiteTB As Boolean = True)
    '
    '   Ritorna una stringa con il contenuto della Tabella.
    '   Se NR e' molto grande, il tempo impiegato puo' essere
    '   notevole.  Se LimiteTB = True la lunghezza della stringa
    '   di ritorno viene limitata alla capienza massima di un
    '   TextBox (circa 32000 caratteri).
    '
        Dim R&, NR&, c&, NC&, LenMax&, TxT$
    '
        NR = UBound(Tabella, 1)
        NC = UBound(Tabella, 2)
    
        For R = 1 To NR
            For c = 1 To NC - 1
                TxT$ = TxT$ & Right$("   " & Str$(Tabella(R, c)), 3) & ","
            Next c
            TxT$ = TxT$ & Right$("   " & Str$(Tabella(R, NC)), 3) & vbNewLine
    '
            DoEvents
        Next R
    '
        strTabella$ = TxT$
    '
    '
    End Function

  2. #2
    Il mio problema l'ho risolto.
    Adesso ho una piccola domanda, dato che creo una matrice "combiS" fatta da milioni di righe, già a 50 Milioni il programma mi dà errore 7 memoria esaurita. A me servirebbe che arrivasse per lo meno a 300 Milioni, come posso fare? C'è un limite alle dimensioni di un array?

  3. #3

  4. #4
    Si la matrice è double..

  5. #5
    ti serve double perchè hai dei numeri con i decimali? se non è cosi prova a farla di tipo long. Dovrebbe tenere più numeri.

  6. #6
    Anche di tipo long è lo stesso.. i numeri che deve contenere sono solo dall'1 al 90, solo che deve avere milioni di righe, altrimenti come posso fare?

    Inoltre ho problemi anche di visualizzazione perchè riesco si a calcolare le combinazioni fino a qualche milione, ma visualizzandole in una textbox non ce ne vanno oltre 60 000 e sono costretto a salvare in un file .txt per poterle vedere tutte..

  7. #7
    stai lavorando con numeri decisamente troppo alti.
    prova a guardare qua: http://www.vbitalia.it/static/Lez13.htm

    perchè ti serve immaganizzare tutti questi dati? non puoi immagazzinarne un tot alla volta? puoi postare il codice in cui vai a popolare la matrice?

  8. #8
    il link che mi hai "linkato" dice:
    "Il limite superiore deve essere compreso nell'intervallo di valori valido per il tipo Long (-2147483648/+2147483647)"

    ma la mia matrice non arriva neanche a 50 milioni... perchè?
    il codice cmq è questo

    codice:
    ' bingo sono i 90 tasti che compongono la matrice, prima li cambio di colore cliccandoli
    ' poi faccio un ciclo per vedere quali\quanti ne ho cliccati
    
    Private Sub bingo_Click(Index As Integer)
    
        contatore = 0
    
        If bingo(Index).BackColor = &H8000000E Then
            bingo(Index).BackColor = &HFFF80
        Else
            bingo(Index).BackColor = &H8000000E
        End If
         
        For I = 0 To 89
            If bingo(I).BackColor = &HFFF80 Then
                selezionati(I) = I + 1
            Else
                selezionati(I) = 0
            End If
        Next
        
        For S = 0 To 89
            If selezionati(S) > 0 Then
                contatore = contatore + 1
            End If
        Next
    
    'fattoriale è una function che mi rende il fattoriale di un numero, bin è il coefficiente binomiale
    'n!/k!(n-k)!               ElemScelti = K
     
        If contatore > 0 Then
            If contatore > ElemScelti - 1 Then
            
                numeratore = fattoriale(contatore)
                denominatore = (fattoriale(ElemScelti) * fattoriale(contatore - ElemScelti))
                bin = numeratore / denominatore
    
            End If
        End If
    
    ' già prima di riempirla mi da l'errore quando bin supera i 50 milioni
    
        ReDim CombiS(1 To bin, 1 To ElemScelti)
    
    End Sub

  9. #9
    Secondo me ti conviene fare una funzione che ti restituisce una matrice parziale. cioè, al posto di fare una matrice che contiene tutto, restituisci una matrice di (per esempio) 20 righe, che l'utente può visionare. Se l'utente vuole visionare le successive 20 righe, clicca un tasto (o quello che preferisci) e la funzione restituisce le 20 righe successive.

    Per farti capire meglio:
    Se ho 100 righe, posso visualizzarne 20 alla volta e mettere un tasto avanti e indietro che, ad ogni click mi ricarica la lista con le 20 righe successive o precedenti. In questo modo il tutto diventa più leggero e non ti carichi milioni di righe in memoria.

    Questa potrebbe essere una soluzione, che va bene se devi solo visualizzare i dati, se devi farci operazioni o altro il tutto diventa più complesso ma il principio rimane lo stesso...

  10. #10
    In realtà devo fare operazioni e confronti sulla matrice totale..

    Potrei anche visualizzare 50 000 combinazioni alla volta, e ad ogni click il programma calcolerebbe solo le 50 000 seguenti. Ma come faccio a farlo ripartire dal punto esatto in cui si era fermato? E le combinazioni che l'utente scorre, non rimangono in memoria lo stesso?

    è possibile scaricare(o salvare provvisoriamente) la memoria del processore durante il calcolo in un foglio .txt, che poi richiamo dalla textbox, magari a 50 000 righe alla volta?


    Colgo l'occasione anche per ringraziarti dell'interessamento

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.