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

    [VB6 ] confrontare tra loro le righe di una matrice

    Buonasera a tutti, sono 4 giorni che non vengo a capo di questa cosa. supponiamo che io abbia questa matrice

    1) 1 2 3 4 5 6
    2) 1 2 3 4 5 7
    3) 1 2 3 4 5 8
    4) 1 2 3 4 6 7
    5) 1 2 3 4 6 8
    6)1 2 3 4 7 8
    7)1 2 3 5 6 7
    8)1 2 3 5 6 8
    9)1 2 3 5 7 8
    10)1 2 3 6 7 8
    11)1 2 4 5 6 7
    12)1 2 4 5 6 8
    13)1 2 4 5 7 8
    14)1 2 4 6 7 8
    15)1 2 5 6 7 8
    16)1 3 4 5 6 7
    17)1 3 4 5 6 8
    18)1 3 4 5 7 8
    19)1 3 4 6 7 8
    20)1 3 5 6 7 8
    21)1 4 5 6 7 8
    22)2 3 4 5 6 7
    23)2 3 4 5 6 8
    24)2 3 4 5 7 8
    25)2 3 4 6 7 8
    26)2 3 5 6 7 8
    27)2 4 5 6 7 8
    28)3 4 5 6 7 8

    io vorrei prendere la riga 2 e confrontarla con la 1, se hanno piu di 5 elementi uguali la scarto. Passo quindi a confrontare la 3 con la 1, se di nuovo trovo 5 elementi uguali scarto anche la 3.. e cosi via...scartando praticamente le righe 2-3-4-5-6-7-8. La numero 9 non la scarto perchè ha solo 4 elementi in comune con la 1, quindi proseguo con la riga 10 confrontandola solo con la 1) e la 9) perchè le altre sono "disabilitate".
    La 10 ha 5 elementi in comune con la 9, quindi la scarto/disabilito
    la 11 ha 5 comuni sia con uno che con 9....scartata
    e cosi via.. fino alla fine

    La matrice ridotta risulta essere

    123456
    123478
    125678
    234578

    il codice me lo scriverei da solo, solo che gli algoritmi che implemento non fanno quello che dovrebbero.. qualcuno ha un'idea di come va impostato l'algoritmo?
    Conviene fare una routine che confronti 2 righe? e dica quanti elementi in comune hanno le righe... oppure copiare le righe che non scarto in un'altra matrice?

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    758

    Re: [VB6 ] confrontare tra loro le righe di una matrice

    Originariamente inviato da litterone
    ... gli algoritmi che implemento non fanno quello che dovrebbero..
    Vediamoli.

  3. #3
    in una riga di 6 elementi, avere PIU' di 5 elementi uguali vuol dire averli uguali tutti! quindi - se le specifiche sono giuste - ti basta confrontare riga(i) e riga(i-1)

  4. #4
    questo è l'ultimo che ho fatto, decisamente il più efficiente.
    La variabile ok scrivi è un vettore booleano di tanti elementi quante sono le righe della matrice, inizializzati tutti a false tranne il primo elemento(che sarebbe la riga 1). La prima parte confronta tutte le righe con la prima (1-2-3-4-5-6 che è true perchè è la prima anche nel ridotto) dichiarandole true se hanno più di 4 elementi comuni. La seconda parte entra in gioco se la riga R non è scartata al confronto con la prima. Il ragionamento sarebbe: "Scorri le altre righe sopra di te, e se ne trovi una true confrontati con quella, altrimenti sei da scartare"
    Quelle vere devono essere 1,6,15,24
    L'algoritmo riconosce vere 1-6, ma al confronto tra 15 e 6 dichiara la 15 falsa e la scarta! quindi prosegue..confrontando tutte le righe solo con le prime 2 che trova TRUE.

    bin=numero di righe=28
    elemscelti=6
    combiS=è la matrice 28x6

    (in fondo posto anche il codice per generare le combinazioni)

    codice:
    '' riga di confronto è la 1.. 1-2-3-4-5-6
    For R = 2 To bin
        Conta = 0
        For c = 1 To ElemScelti
            If CombiS(R, c) = CombiS(1, c) Then
                Conta = Conta + 1
                If Conta > 4 Then
                '' vai alla riga successiva
                GoTo RigaSuccessiva
                End If
                GoTo ColonnaSuccessiva
            Else
                For K = 1 To ElemScelti
                    If CombiS(R, K) = CombiS(1, c) Then
                        Conta = Conta + 1
                        If Conta > 4 Then
                '' vai alla riga successiva
                        GoTo RigaSuccessiva
                        End If
                    GoTo ColonnaSuccessiva
                    End If
                Next
            End If
    ColonnaSuccessiva:
        Next
        
        I = 2
        Do While I < R
            Conta = 0
                If okScrivi(I) = False Then
                    GoTo RigaSuccessiva2
                Else
    
        '' confronto con la riga I
                    For c = 1 To ElemScelti
                        If CombiS(R, c) = CombiS(I, c) Then
                            Conta = Conta + 1
                            If Conta > 4 Then
                '' vai alla riga successiva
                            GoTo RigaSuccessiva
                            End If
                            GoTo ColonnaSuccessiva2
                        Else
                            For K = 1 To ElemScelti
                                If CombiS(R, K) = CombiS(I, c) Then
                                    Conta = Conta + 1
                                    If Conta > 4 Then
                                    GoTo RigaSuccessiva
                                    End If
                                End If
                            Next
    '                        GoTo ColonnaSuccessiva2
                        End If
    ColonnaSuccessiva2:
                    Next
    '' fai il debug fino qui, noterai che la colonna 15(R=15)
    '' al confronto con la 6(I=6) risulta misteriosamente falsa, quando invece è vera
                    okScrivi(R) = True
                    GoTo RigaSuccessiva
                End If
    RigaSuccessiva2:
            I = I + 1
        Loop
        okScrivi(R) = True
    RigaSuccessiva:
    Next

    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 As Long
        Dim c&, P As Integer
        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

  5. #5
    in pratica, quello che devi fare è eliminare i duplicati?

  6. #6
    Duplicati non ce ne sono perchè sono combinazioni semplici di N oggetti in classe K, quello che voglio io è non avere 2 righe con 5 elementi uguali.

  7. #7
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    758
    Premesso che possono esserci molte soluzioni, grosso modo io procederei così.

    Una funzione che confronta due righe e restituisce un valore booleano che indica se sono "simili" o meno. Per "simili" si intende che abbiano cinque o più numeri uguali anche se in posizioni diverse.
    Per fare il confronto può essere utile un'altra funzione che ordina i numeri di ciascuna riga.

    Con un ciclo principale (For...Next) si esamina ciascuna riga e, con un ciclo secondario e interno al precedente, la si confronta (tramite la funzione di cui sopra) con tutte le righe successive; quelle "simili" si marcano in un modo qualunque, per esempio impostando a zero o ad un altro valore convenzionale il primo numero della riga "simile".

    Al termine del ciclo principale si copiano tutte le righe non marcate come "simili" in una nuova matrice.

  8. #8
    Originariamente inviato da Grumpy

    Per fare il confronto può essere utile un'altra funzione che ordina i numeri di ciascuna riga.

    Con un ciclo principale (For...Next) si esamina ciascuna riga e, con un ciclo secondario e interno al precedente, la si confronta (tramite la funzione di cui sopra) con tutte le righe successive;
    1) che cosa intendi per funzione che ordina i numeri di ciascuna riga? Sono già messi in ordine crescente..

    2) il confronto deve essere fatto con le righe precedenti, non con le successive. Ed il fatto che debba confrontarle con tutte rende il ciclo molto lungo quando si tratta di confrontare una matrice da 1 milione di righe, per non pensare al fatto che l'80% (% a caso, ma cmq alta) delle righe che gli stanno sopra sono già false,quindi con loro è un confronto inutile.

  9. #9
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    758
    Originariamente inviato da litterone
    1) che cosa intendi per funzione che ordina i numeri di ciascuna riga? Sono già messi in ordine crescente..
    Ok, quindi l'ordinamento non serve.

    Originariamente inviato da litterone
    2) il confronto deve essere fatto con le righe precedenti, non con le successive.
    Il verso del confronto è irrilevante. L'importante è che ogni riga venga confrontata con tutte le altre tranne che con quelle che sono già state confrontate con essa stessa.

    Ed il fatto che debba confrontarle con tutte rende il ciclo molto lungo quando si tratta di confrontare una matrice da 1 milione di righe,...
    Questo perché hai deciso di generare una matrice contenente tutte le combinazioni possibili, anziché solo quelle compatibili con il tuo criterio di riduzione. Una matrice con un milione di righe è ingestibile.

  10. #10
    Originariamente inviato da Grumpy

    Questo perché hai deciso di generare una matrice contenente tutte le combinazioni possibili, anziché solo quelle compatibili con il tuo criterio di riduzione. Una matrice con un milione di righe è ingestibile.
    Ma io devo per forza generare prima la matrice integrale, è proprio quella che contiene tutte le possibili sestine, ed è da quella che devo estrapollare determinate sestine che mi permettono di fare almeno "cinquina" qualora io azzecchi i sei numeri nel sistema giocato.Se il confronto non parte dall'integrale il 5 matematico non può essere garantito. Da questa cosa non si scappa, il mio algoritmo è quasi corretto perchè trova le prime 2 sestine da mettere nel ridotto, ma non le altre... o meglio non trova la 3-a, quindi confronta le restanti solo con le prime 2..(creando cmq un ridotto.. ma non abbastanza)

    Ringrazio comunque tutti quelli che sono intervenuti nella discussione.

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.