annuncio

Comprimi
Ancora nessun annuncio.

Confronto tra Array VB6

Comprimi
X
  • Filtro
  • Ora
  • Visualizza
Elimina tutto
nuovi messaggi

  • Confronto tra Array VB6

    Ciao, sono alla ricerca di una routine per velocizzare il confronto tra Array. In un forum di programmatori ho trovato un thread interessante, ma incompleto. Un utente chiedeva aiuto per una routine di riduzione di un sistema per il 10 e lotto. Al termine della discussione è stato postato il seguente codice, sicuramente incompleto, che ho mandato in esecuzione ma non riesco a comprendere cosa fa.


    1 Form
    name=fMain
    Size=Bello alto

    1 text boxt = txt
    name=txt
    Multiline=true
    Scrool=Vertical

    1 Command Button

    1 Module
    Name = Come vi pare e piace

    fMain Code

    codice:
    Private Sub Command1_Click()
        Dim b(2) As String
    
        b(0) = App.Path & "\" & App.EXEName & ".exe"
        b(1) = "3"
        b(2) = "90"
    
        TestMain UBound(b) + 1, b()
    End Sub


    Module1 Code


    codice:
    Public Function BinCoef(ByVal n As Long, ByVal r As Long) As Long
        Dim i As Long, b As Long
    
        If (r < 0) Or (n < r) Then Exit Function
    
        If (2 * r) > n Then r = n - r
    
        b = 1
    
        If r > 0 Then
            For i = 0 To r - 1
                b = (b * (n - i)) / (i + 1)
            Next
        End If
    
        BinCoef = b
    End Function
    
    Public Sub PrintkSubset(ByVal k As Long, T() As Long)
        Dim i As Long
    
        With Fmain.txt
            .SelText = "["
    
            If k > 0 Then
                .SelText = CStr(T(0)) & "    " & CStr(T(1))
                For i = 2 To k
                    .SelText = "," & CStr(T(i))
                Next
            End If
    
            .SelText = "]"
        End With
    End Sub
    
    Public Function kSubsetRevDoorRank(T() As Long, ByVal k As Long) As Long
        Dim i As Long, r As Long, s As Long
    
        s = 1
    
        For i = k To 1 Step -1
            r = r + BinCoef(T(i), i) * s
            s = -s
        Next
    
        If (k Mod 2) = 1 Then r = r - 1
    
        kSubsetRevDoorRank = r
    End Function
    
    Public Sub kSubsetRevDoorUnrank(ByVal r As Long, ByVal k As Long, ByVal n As Long, T() As Long)
        Dim x As Long, i As Long, y As Long
    
        x = n
    
        For i = k To 1 Step -1
            y = BinCoef(x, i)
    
            Do While (y > r)
                x = x - 1
                y = BinCoef(x, i)
            Loop
            T(i) = x + 1
            r = BinCoef(x + 1, i) - r - 1
        Next
    End Sub
    
    Public Sub kSubsetRevDoorSuccessor(T() As Long, ByVal k As Long, ByVal n As Long)
        Dim j As Long
    
        T(k + 1) = n + 1
        j = 1
        Do While ((j <= k) And (T(j) = j))
            j = j + 1
        Loop
    
        If ((k - j) Mod 2) <> 0 Then
            If j = 1 Then
                T(1) = T(1) - 1
            Else
                T(j - 1) = j
                T(j - 2) = j - 1
            End If
        Else
            If T(j + 1) <> T(j) + 1 Then
                T(j - 1) = T(j)
                T(j) = T(j) + 1
            Else
                T(j + 1) = T(j)
                T(j) = j
            End If
        End If
    End Sub
    
    Public Sub TestMain(ByVal ac As Long, av() As String)
        Dim NN As Long, n As Long, k As Long, r As Long, s As Long, done As Boolean
        Dim T() As Long
    
        If ac <> 3 Then
            Fmain.txt.SelText = "Error,usage: " & av(0) & " k n" & vbCrLf
            Exit Sub
        End If
    
        k = CLng(av(1))
        n = CLng(av(2))
    
        If k < 0 Then
            Fmain.txt.SelText = "Error,Sorry k must be greater than 0" & vbCrLf & "Usage: " & av(0) & " k n" & vbCrLf
            Exit Sub
        End If
    
        If k > n Then
            Fmain.txt.SelText = "Error,There are no " & CStr(k) & "-subset of an " & CStr(n) & "-set?" & vbCrLf & "Usage: " & av(0) & " k n" & vbCrLf
            Exit Sub
        End If
    
        ReDim T(k + 2) As Long
    
        NN = BinCoef(n, k)
    
        Fmain.txt.SelText = "Testing rank/unrank." & vbCrLf & " " & CStr(n) & " " & CStr(k) & " " & CStr(NN) & vbCrLf
    
        For r = 0 To NN - 1
            With Fmain.txt
                .SelText = " " & CStr(r)
                kSubsetRevDoorUnrank r, k, n, T()
                PrintkSubset k, T
                .SelText = "    "
                s = kSubsetRevDoorRank(T, k)
                .SelText = "rank = " & CStr(s) & vbCrLf
            End With
        Next
    
        Fmain.txt.SelText = "Testing successor." & vbCrLf
    
        kSubsetRevDoorUnrank 0, k, n, T()
        s = kSubsetRevDoorRank(T, k)
        T(0) = 0
    
        Do While (done = False)
            PrintkSubset k, T
            Fmain.txt.SelText = "rank = " & CStr(s) & vbCrLf
            kSubsetRevDoorSuccessor T(), k, n
            s = kSubsetRevDoorRank(T, k)
            If s = 0 Then done = True
        Loop
    End Sub
    Ultima modifica di mirapep; 16-04-2019, 20:07.

  • #2
    In fMain b(1) era = 5 e b(2)=20

    Per provare ho settato i parametri per lo sviluppo in terni. Al termine il risultato è come da immagine allegata. In particolare non comprendo cosa rappresenta il primo numero a sx

    Commenta


    • #3
      ordine delle fasce dei117000 terni
      Ultima modifica di ghio; 16-04-2019, 23:23.

      Commenta


      • #4
        In quali fasce? Puoi fare un esempio?

        Commenta


        • #5
          l ordine che ti da infondo è un suo ordine,
          ma se tu li vedi in origine anno un ordine esempio, il primo numero della colonna .1 a sempre nella terzina il numero2 il 2 sempre il 3 il 3 sempre4 e cosi via ma le terzine con 1 non possono essere cosi poche se non filtrate,gli da probabilmente uan fascia

          Commenta


          • #6
            Poichè alcuni utenti erano interessati all'argomento pubblico quanto segue

            """"""""""""""""
            Generalmente vi sono tre ottimi motivi che tengono ben lontani gli esperti in combinatorica e matematica discreta da campi come questo: l'insofferenza dei matematici d'ogni ordine e grado verso i giochi d'azzardo legalizzati, nei quali gli unici vincitori sicuri sono il demanio e i non giocatori; l'allergia al BASIC; l'esilarante mix di dilettantismo, gelosia bottegaia, attitudine da "quadratoridicerchi" e "ricercatoridiverità" che trasuda dai siti degli "esperti", Specialmente Quelli Che Si Prendono Parecchio Sul Serio e usano un Pretenzioso Gergo Specialistico Infarcito Con Un Sacco Di Iniziali Maiuscole A Casaccio Per Magnificare Le Loro Pompose Banalità.

            Nel caso del sottoscritto, si aggiunge a tali motivi - tutti condivisi appieno - anche la contingenza della mancanza di tempo libero.

            In ogni caso, senza venir meno ai miei principi, vorrei almeno indicare la via per mettere insieme una soluzione, e fornire qualche consiglio sparso, alla luce della mia ormai ventennale esperienza in ottimizzazione combinatoria, matematica discreta e dintorni - con rimandi ad una bibliografia minimale, forse impegnativa per chi parte da zero ma indispensabile per chi abbia davvero intenzione di affrontare il problema con gli strumenti giusti e senza improvvisazioni.

            1) Le strutture dati in questo genere di problemi sono solamente bit array o, al più, array di booleani negli HLL.
            In linea di principio, trattandosi di generare dei sottoinsiemi (problema banale di norma liquidato entro le prime cinquanta pagine di qualsiasi testo decente, es. [A04], [A05], [A06]) è anche possibile didatticamente fare ricorso ad array di indici. Dunque, a fronte di un insieme di scelta con cardinalità pari a 35, si useranno i primi 35 naturali, quali che siano i valori contenuti nell'insieme di scelta. L'ultima cosa da fare è però ricorrere direttamente ai numeri scelti dall'utente, pena la perdita di flessibilità e generalità (ma anche di prestazioni, in taluni casi).

            2) Un noto (e ovvio) teorema ci dice che le tipiche strutture discrete con cardinalità finita (insiemi, multinsiemi, liste...) sono sempre mappabili su ordinali naturali in una corrispondenza biunivoca.
            Quasi tutti sono anche mappabili in modo intelligente, ossia facilmente reversibile tramite una coppia di funzioni di ranking e unranking di complessità O() costante o - al più - CAT. Si veda, ad esempio, il capitolo 2 di [A04] che unisce i pregi di essere moderno, molto comprensibile, accettabilmente rigoroso e di presentare codice C leggibile e portabile, soggetto ad ulteriori ottimizzazioni in mani veramente esperte.

            Ricordo che dati due insiemi A e B, la distanza di Hamming tra questi è pari al numero complessivo di elementi che occorre "aggiungere a" ed "eliminare da" A per ottenere B. Si tratta di un altro modo per indicare l'operazione booleana di differenza simmetrica. Se A e B sono caratterizzati dalla medesima arietà o cardinalità, una ovvia conseguenza è che la distanza di Hamming tra i due è sicuramente pari, e risulta maggiore o uguale a 2 se i due insiemi sono distinti.

            Come suggerirò anche numericamente più sotto, la scelta di un idoneo ordinamento del totale delle combinazioni ("sistema integrale", secondo i "sistemisti") è un elemento essenziale per l'approccio corretto al problema di esplorazione esaustiva di tale spazio e per la progettazione di un primo algoritmo, sia pure generico ma con prestazioni decorose: il mio consiglio è quello di prestare la massima attenzione alle funzioni di ordinamento, ranking e generazione dei sottoinsiemi basate su "minimal change", ossia sulla distanza di Hamming. Casualmente ​, l'uso di strutture dati booleane riduce il calcolo della distanza di H. tra due sottoinsiemi a uno XOR e un lookup per il conteggio dei bit. Si vedano di nuovo [A04] e [A06] in particolare, nella eccellente prima parte sugli algoritmi bit oriented.

            Se è qualcuno è rimbalzata per la testa anche l'espressione "compressione dei dati" nel leggere il nome di Hamming, sappia che ciò non è del tutto peregrino.

            3) Visti l'argomento e il linguaggio, c'è posto anche per una considerazione ingegneristica, di ordine molto pratico. Su una serie di macchine decorose, ma certo non esorbitanti (Intel Xeon 5110, Pentium IV, Pentium M...), riesco abitualmente a generare circa cento milioni di combinazioni al secondo in C, usando routine e strutture dati come quelle di Arndt ([A06] e relativo sito) e Ruskey ([A05] e naturalmente COS). In casi particolari faccio anche di meglio.
            Ne segue che anche per un programmatore meno scafato, sia pure usando un HLL e algoritmi scarsini, in O(N^2) o peggiori, i tempi di elaborazione - con N dell'ordine dei milioni - si misurano comunque in minuti, a meno di clamorosi errori d'impostazione.

            4) Non esiste letteratura specifica su questo problema, in buona parte per i motivi accennati sopra. Generalizzazioni molto più utili sono tuttavia ampiamente studiate nei capitoli avanzati di tutti i manuali di combinatorica e ottimizzazione, sebbene trattazioni approfondite siano alquanto inaccessibili per i profani (es. [B07], [B08], [B10] ma anche il volume IV dello Knuth e [A07], [A08] per la stima analitica dei minimi e lo studio dell'andamento).
            Specialmente per chi parte da zero, sarà un ottimo compromesso tra fattibilità, usabilità e genericità una cauta ma robusta applicazione degli strumenti e dei concetti più elementari della combinatorica: ranking, distanza di Hamming, algoritmi elementari basati sul crivello (con qualche buona euristica). Mancano solo il principio della piccionaia e quello di inclusione-esclusione per completare il contenuto delle prime pagine di un buon manuale in materia.


            Francamente, grazie al lessico affumicato e autoreferenziale degli "esperti" sui due o tre siti che ho avuto il coraggio di consultare, non sono neppure certo di aver compreso appieno la definizione di "sistema ridotto". Di certo mi mancano il tempo (e la voglia) per studiare la caratterizzazione analitica di tale questione, incluso tutto ciò che concerne la ricerca di eventuali minimi e una seria stima dei lower bound.

            Poiché sono costretto ad una estrema sintesi, propongo invece sbrigativamente una definizione operativa su cui iniziare a ragionare. Siano dati i naturali n, k, j con n &gt; k &gt; j &gt; 0.
            Per vincoli di regolamento, k = 10 mentre j esprime la famosa "garanzia" n-1, n-2 ("ridotto", "biridotto" etc) sempre nel gergo dei "sistemisti".

            • Dato un insieme di scelta finito, consistente in n elementi rigorosamente distinti e tutti appartenenti all'intervallo naturale [1, 90], si generano tutti i suoi possibili sottoinsiemi di ordine k (k-subsets, con k &lt; n) ovvero, ciò che fa lo stesso, le C(n, k) combinazioni di rango k. Ne risulterà una matrice W di dimensioni 10 x C(n, k).

            • Si sceglie arbitrariamente uno di tali sottoinsiemi, chiamiamolo S(i). A questo punto, si può procedere in almeno due modi:

            a) Si ordina l'intera matrice W in base alla distanza di Hamming relativa ad S(i). Ciò fatto, si eliminano semplicemente i primi Cj elementi dalla matrice (sieve o crivello), esclusa ovviamente la combinazione S(i): si veda sotto per la semplice determinazione numerica di tale valore Cj al primo passo.
            In altri termini, eliminiamo dal totale tutte e sole le combinazioni che distano 2, 4, ..., 2 · j da quella data, ossia che differiscono per 1, 2, ..., j elementi da quella arbitraria di partenza. Ciò risulta enormemente facilitato se l'insieme complessivo delle combinazioni viene in qualche modo mantenuto ordinato in base alla distanza relativa all'insieme scelto (in un contesto più serio, si userebbero magari uno heap ed uno o più bbtree per l'indicizzazione).

            b) In alternativa, è anche fattibile generare (o almeno enumerare) tutte le possibili combinazioni derivate da S(i), per distanza di Hamming crescente sempre relativa ad S(i), ed eliminarle dal "sistema integrale" tramite una funzione di ricerca in O(1), ossia un rank (pensate, per semplice analogia, ad una funzione hash strettamente deterministica e priva di collisioni).
            Ciò semplifica ulteriormente il codice, e spalanca le porte ad un uso ancor più intensivo di tabelle di lookup precalcolate.

            • Si sceglie ora come nuova combinazione di riferimento una S(i+1) tra quelle con distanza di Hamming pari a 2 · j + 1 rispetto alla precedente, e si itera il procedimento fino ad esaurimento delle combinazioni disponibili - almeno in prima approssimazione.

            La descrizione verbale sembra forse complessa, ma in realtà è decisamente banale (e perfino relativamente efficiente). Studiate con la dovuta calma i testi, in parallelo a sorgenti come revdoor.c nel'archivio GEN.tar.gz di Kreher e Stinson, e vi si accenderà la classica "lampadina" sopra la testa...

            Al termine le combinazioni superstiti, ossia non cancellate, dovrebbero (se ho ben compreso) costituire l'agognato "sistema ridotto assoluto". In questo quadro sarebbe inoltre sensato analizzare la frequenza con cui ciascun indice compare nella matrice finale 10 x w, se non altro a fini euristici.

            Vale invece la pena di notare che questo problema, visto con gli occhi dell'algebrista lineare anziché nella sua natura reticolare combinatoria, si traduce nella eliminazione di ipersfere da uno spazio ipercubico (in questo caso decadimensionale) di vettori di naturali. Provate a visualizzare una (falsa ma intuitiva) proiezione del problema nell'ordinario 3-spazio normato, usando la distanza di Hamming desiderata come raggio delle sfere da eliminare, in modo tale che - data la prima sfera - il centro della sfera successiva viene scelto sulla superficie della attuale... tralasciando altri dettagli, tale immagine è un buon punto di partenza per comprendere intuitivamente la natura del problema e le sovrapposizioni combinatorie che generano una certa confusione in un approccio troppo naif alla soluzione.

            Trattandosi per natura di un problema di esplorazione esaustiva, nulla poi vieta di mettere in campo tutto il consueto arsenale della ricerca operativa, dalla discesa deterministica al backtracking, agli algoritmi genetici (usati sempre cum grano salis): l'esistenza di un algoritmo generativo ad hoc è comunque subordinata ad uno studio più approfondito dell'andamento delle sovrapposizioni (pensate sempre alle ipersfere), che probabilmente nessuno si darà la pena di portare a termine - visti anche i punti 3 e 4 di cui sopra.

            Dati i tempi e gli spazi a disposizione, non posso aggiungere molto altro, se non uno stimolo per lo studio ulteriore del problema: vi garantisco che nei testi consigliati vi sono almeno sette o otto "soluzioni" algoritmiche non troppo complicate adattabili al caso.

            Consideriamo l'insieme S(i) di partenza. Parlare di "riduzione" con j = 1 significa eliminare tutti gli insiemi (le "decine" o "colonne") che contengono nove elementi identici a quelli dati in S(i), combinati con un elemento arbitrariamente scelto tra gli n - 10 disponibili. Ciò darebbe luogo ad un totale di k(n-k) combinazioni possibili, formuletta banale che si legge spesso sui siti degli "esperti" ma che in realtà deriva da una identità combinatoria più generale.

            Il numero complessivo delle combinazioni "equivalenti" per un dato j, infatti, è pari a



            Infatti, fissato un k-insieme arbitrario, se vogliamo sostituire j dei suoi elementi (ottenendo così una distanza Hamming pari a 2 · j) il procedimento mentale consiste nello scegliere uno qualsiasi dei suoi sottoinsiemi con k-j elementi, unendolo poi con uno dei possibili sottoinsiemi di j elementi scelti tra gli n-k elementi non presenti nel k-insieme di partenza. Ne segue in modo immediato la formuletta sopra.

            Ora, tale procedimento può essere validamente impiegato nell'algoritmo delineato sopra, per generare la famiglia di combinazioni derivate da quella correntemente considerata. Ricordo solo che questa parte può essere ottimizzata in modo estremo con l'uso di ampie tabelle di lookup precalcolate.

            Con ciò ben chiaro in mente, si possono contare in modo immediato gli insiemi entro un raggio j da quello attualmente considerato. Per fissare le idee, siano n = 30, k = 10 e facciamo variare j tra 0 e k. Come sopra, C con pedice j indica il numero di combinazioni scelte tra le C(n, k) totali che hanno distanza di Hamming pari a 2 · j da un insieme arbitrariamente fissato.



            Molto ancora si può dire in merito a formula, tabella, algoritmo, sovrapposizioni e numero delle "colonne" nel sistema finale.
            Mi preme però rimarcare con forza che la comparsa di quel numeretto

            nel totale non è affatto casuale.

            Il fatto lapalissiano che sia possibile ordinare e classificare l'intero insieme delle combinazioni (a maggior ragione, operativamente, la parte di nostro interesse) in base alla distanza di Hamming relativa alla combinazione corrente è di estrema importanza per mostrare intuitivamente (ma anche formalmente, e i lettori sono caldamente invitati a farlo) la validità di questo approccio necessariamente superficiale e iniziale - ma sensato, e ben fondato - alla questione.
            Ultima modifica di M.A.W. 1968; 26-06-2010 11:33 """""""""""""""""""""""""""""""""""""""""""""" ""

            Commenta


            • #7
              Sia i numeri al lotto che un elemento radioattivo possono sortire/decadere subito
              oppure anche mai.
              Ma nonostante questa certezza, in natura nella radioattività si constata un decadimento
              che ha un certo andamento.

              Forse può incuriosire qualcuno: a cosa serve questa costante di decadimento applicata al lotto?
              Serve a calcolare con ottima approssimazione
              quanti (non quali!)
              ambi
              restano ancora da sorteggiare dopo un tot qualsiasi di estrazioni.
              Ad es., sempre su tutte le ruote al Lotto:
              Quanti dei 4005 ambi rimangono vergini dopo 500estrazioni
              (stabilito un inizio in cui sono ovviamente vergini tutti i 4005 ambi)?

              N = 4005*exp(-0,0025*500) = 11,47
              Provare a contare per credere (l'errore massimo è +-5 ambi circa)

              E' esattamente la stessa formula del decadimento radioattivo:
              A = Ao * e^(-lambda*t)
              dove A è l'attività residua dopo il tempo t (all'inizio era Ao)
              e lambda è la costante di decadimento dei vari radionuclidi.

              Questa formula è applicabile per il lotto, considerando che i fenomeni
              (radioattività e sorteggio)
              in entrambi i casi seguono una distribuzione poissoniana,
              rappresentabile come una retta su scala semi-logaritmica.
              E' una riga scarsa su excel.

              Applicazione pratica:
              -parto da 90 numeri e 4005 ambi componibili.
              Mi calcolo quanti concorsi devo considerare per ottenere gli ultimi 5 ambi ancora non sortiti.
              Se, casualmente ,
              saranno necessari più concorsi rispetto a quello che la formula indica
              ho uno squilibrio tra quello che le leggi naturali sulla casualità dicono
              (ad esempio che gli ambi sopravvissuti siano 4 o meno)
              e quelli che mi ritrovo, ossia 5 o più ambi.
              Questo indica che è tempo di
              raccolta
              perchè come per la radioattività
              si deve raggiungere un equilibrio.

              Caso pratico:
              5 ambi da giocare al lotto su tutte costano 5 euro.
              Ricavo con la formula esposta gli ultimi 5 :
              |
              07,79
              | 09,31 |
              09,37
              | 29,71 |
              53,71
              |

              Commenta

              Unconfigured Ad Widget

              Comprimi

              Ultima estrazione del lotto

              Comprimi

              Estrazione del lotto
              martedì 18 giugno 2019
              Bari
              74
              44
              18
              29
              70
              Cagliari
              37
              33
              90
              26
              86
              Firenze
              18
              43
              47
              63
              15
              Genova
              45
              88
              81
              03
              13
              Milano
              15
              14
              41
              49
              36
              Napoli
              21
              82
              73
              39
              03
              Palermo
              25
              67
              40
              81
              71
              Roma
              51
              54
              08
              71
              06
              Torino
              80
              72
              59
              12
              88
              Venezia
              49
              35
              34
              77
              15
              Nazionale
              46
              16
              28
              89
              26
              Sto operando...
              X