Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Sudoku_Solver_DK - Donald_Knuth_Dancing_Links_Solver.vb

Donald_Knuth_Dancing_Links_Solver.vb

Caricato da: Ultimo
Scarica il programma completo

  1. Imports System.Threading
  2. Imports System.Threading.Tasks
  3.  
  4. ''' <summary>
  5. ''' Dancing Links Algoritmo solutivo di copertura esatta degli schemi sudoku
  6. ''' del Dott. Donald Knuth
  7. ''' </summary>
  8. ''' <remarks></remarks>
  9. Public Class Donald_Knuth_Dancing_Links_Solver
  10.  
  11.  
  12. #Region "Variabili_e_costanti_generiche"
  13.     'base del sudoku.
  14.     Public nBase As Integer
  15.     'Numero totale celle
  16.     Public cToT As Integer = nBase * nBase
  17.     'Variabili candidati
  18.     Public c1, c2, c3, c4, c5, c6, c7, c8, c9
  19.     Public c10, c11, c12, c13, c14, c15, c16
  20.     'Matrice vettore candidati
  21.     Public M_Cand9(0 To 9)
  22.     Public M_Cand16(0 To 16)
  23.     'Costanti indice simboli candidati
  24.     Public s1 = 1, s2 = 2, s3 = 3, s4 = 4, s5 = 5, s6 = 6, s7 = 7, s8 = 8, s9 = 9, _
  25.                  s10 = 10, s11 = 11, s12 = 12, s13 = 13, s14 = 14, s15 = 15, s16 = 16
  26.     'Matrice Simboli
  27.     Public M_Simb9(0 To 9)
  28.     Public M_Simb16(0 To 16)
  29.     'Costanti potenze di due riferite a indice simboli candidati
  30.     Public p1 = 2, p2 = 4, p3 = 8, p4 = 16, p5 = 32, p6 = 64, p7 = 128, p8 = 256, p9 = 512, _
  31.                  p10 = 1024, p11 = 2048, p12 = 4096, p13 = 8192, p14 = 16384, p15 = 32768, p16 = 65536
  32.  
  33.     'Somma Square 9  (potenze di 2)
  34.     Public SSq9 As Int32 = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9
  35.     'Somma Square 16  (potenze di 2)
  36.     Public SSq16 As Int32 = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + _
  37.                          p10 + p11 + p12 + p13 + p14 + p15 + p16
  38.  
  39.     'Matrici vettore Square
  40.     Public M_Square9(0 To 9) As Int32
  41.     Public M_Square16(0 To 16) As Int32
  42.  
  43.     'Matrice con indirizzi di cella stile "A1"
  44.     Public M_Indy(0 To cToT) As String
  45.  
  46.     'indica se la soluzione è unica.
  47.     Public Unica As Boolean
  48.  
  49.     ''' <summary>
  50.     ''' Classe struttura dati DLX.
  51.     ''' </summary>
  52.     ''' <remarks></remarks>
  53.     Public Class DatiSchemaSudoku
  54.  
  55.         Private _Name As String = ""
  56.         Private _Cand As String(,) = {}        'Cand = Candidati-chiavi    C(0 To nBase * cTOT, 0 To nBase + 1)
  57.         Private _Vinc As String(,) = {}        'Vinc = Vincoli-chiavi       V(0 To cTOT * 4, 0 To nBase + 1)
  58.         Private _Solution As String(,) = {}    'Solution = Soluzione       S(0 To cTOT, 0 To 1)
  59.         Private _Index_Vincolo_PT As Integer = Nothing  'Tentativi: Index del vincolo per tentativo nella lista vincoli_PT
  60.         Private _t_CVE As Integer = Nothing        'Tentativi: Chiave Vincolo in Esame
  61.         Private _t_IC As Integer = Nothing         'Tentativi: Inizio Conta per il backtraching  
  62.         Private _t_UCR As Integer = Nothing        'Tentativi: Ultima Chiave Rilasciata
  63.  
  64.         '***** Proprietà ******
  65.         Public Property Name As String
  66.             Get
  67.                 Return _Name
  68.             End Get
  69.             Set(ByVal value As String)
  70.                 _Name = value
  71.             End Set
  72.         End Property
  73.  
  74.         Public Property Index_Vincolo_PT As Int32
  75.             Get
  76.                 Return _Index_Vincolo_PT
  77.             End Get
  78.             Set(ByVal value As Int32)
  79.                 _Index_Vincolo_PT = value
  80.             End Set
  81.         End Property
  82.  
  83.         Public Property t_CVE As Int32
  84.             Get
  85.                 Return _t_CVE
  86.             End Get
  87.             Set(ByVal value As Int32)
  88.                 _t_CVE = value
  89.             End Set
  90.         End Property
  91.  
  92.         Public Property t_IC As Int32
  93.             Get
  94.                 Return _t_IC
  95.             End Get
  96.             Set(ByVal value As Int32)
  97.                 _t_IC = value
  98.             End Set
  99.         End Property
  100.  
  101.         Public Property t_UCR As Int32
  102.             Get
  103.                 Return _t_UCR
  104.             End Get
  105.             Set(ByVal value As Int32)
  106.                 _t_UCR = value
  107.             End Set
  108.         End Property
  109.  
  110.         Public Property Cand As String(,)
  111.             Get
  112.                 Return _Cand
  113.             End Get
  114.             Set(ByVal value As String(,))
  115.                 _Cand = value
  116.             End Set
  117.         End Property
  118.  
  119.         Public Property Vinc As String(,)
  120.             Get
  121.                 Return _Vinc
  122.             End Get
  123.             Set(ByVal value As String(,))
  124.                 _Vinc = value
  125.             End Set
  126.         End Property
  127.  
  128.         Public Property Solution As String(,)
  129.             Get
  130.                 Return _Solution
  131.             End Get
  132.             Set(ByVal value As String(,))
  133.                 _Solution = value
  134.             End Set
  135.         End Property
  136.  
  137.     End Class
  138.  
  139.  
  140.  
  141.     'Metrice del sudoku.
  142.     Public Mastersudoku(,) As Int32
  143.  
  144.     'struttura dati schema principale.
  145.     Public dss As DatiSchemaSudoku
  146.  
  147.     'Lista Matrici Schemi Avanzamento Tentativi
  148.     Public Lst_SAT As List(Of DatiSchemaSudoku) = Nothing
  149.     'flag
  150.     Public PrimoTentativoInCorso As Boolean
  151.  
  152.     'Matrice(Dizionario) Probabilità per Tentativi
  153.     Public M_PT(,) As Int32
  154.     'Matrice dove vengono registrate le eliminazioni dei Candidati prima dei Tentativi.
  155.     Public Matrice_Candidati_Eliminati(,) As Int32
  156.     'Dizionario dei Candidati non eliminati per la fase a Tentativi.
  157.     Public Elenco_Candidati_nonEliminati_daVincoliPT As Dictionary(Of Int32, List(Of Int32))
  158.  
  159.     'se si vuole che si trovino più soluzioni
  160.     Public Multisoluzioni As Boolean
  161.  
  162.     Public log_sequenza_Matrici As New System.Text.StringBuilder
  163.  
  164.     Public log_Dancing_Links As New System.Text.StringBuilder
  165.  
  166.     'Dizionario dei vincoli bloccanti.
  167.     Public VincoliBloccanti As Dictionary(Of String, Int32)
  168.  
  169. #End Region
  170.  
  171. #Region "Costanti_ChiaviCandidati"
  172.  
  173.     'Dizionario delle chiavi_candidati
  174.     Friend dc As New Dictionary(Of String, Int32)
  175.  
  176.     Public Sub iniDizionariChiaviCandidati()
  177.         Dim nomechiavecandidato As String = String.Empty
  178.         Dim numchiavecandidato As Int32 = 0
  179.         'righe del sudoku
  180.         For r As Int32 = 1 To nBase
  181.             'colonne del sudoku
  182.             For c As Int32 = 1 To nBase
  183.                 'simboli del sudoku
  184.                 For s As Int32 = 1 To nBase
  185.                     nomechiavecandidato = ""
  186.                     numchiavecandidato += 1
  187.                     nomechiavecandidato = "r" & r & "_c" & c & "_s" & s
  188.                     dc.Add(nomechiavecandidato, numchiavecandidato)
  189.                 Next s
  190.             Next c
  191.         Next r
  192.     End Sub
  193.  
  194. #End Region
  195.  
  196. #Region "Costanti_ChiaviVincoli"
  197.  
  198.     'Dizionario delle chiavi_vincoli
  199.     Friend dv As New Dictionary(Of String, Int32)
  200.  
  201.     Public Sub iniDizionariChiaviVincoli()
  202.         Dim nomechiaveVincoli As String = String.Empty
  203.         Dim numchiaveVincolo As Int32 = 0
  204.         Dim nCelle As Int32 = nBase * nBase
  205.         'celle del sudoku (nbase * nbase)
  206.         For i As Int32 = 1 To nCelle
  207.             numchiaveVincolo += 1
  208.             nomechiaveVincoli = "cella_" & numchiaveVincolo
  209.             dv.Add(nomechiaveVincoli, numchiaveVincolo)
  210.         Next i
  211.         'righe+simboli del sudoku
  212.         For j As Int32 = 1 To nBase
  213.             For s As Int32 = 1 To nBase
  214.                 numchiaveVincolo += 1
  215.                 nomechiaveVincoli = "row" & j & "_s" & s
  216.                 dv.Add(nomechiaveVincoli, numchiaveVincolo)
  217.             Next s
  218.         Next j
  219.         'colonne+simboli del sudoku
  220.         For k As Int32 = 1 To nBase
  221.             For s As Int32 = 1 To nBase
  222.                 numchiaveVincolo += 1
  223.                 nomechiaveVincoli = "col" & k & "_s" & s
  224.                 dv.Add(nomechiaveVincoli, numchiaveVincolo)
  225.             Next s
  226.         Next k
  227.         'box+simboli del sudoku
  228.         For z As Int32 = 1 To nBase
  229.             For s As Int32 = 1 To nBase
  230.                 numchiaveVincolo += 1
  231.                 nomechiaveVincoli = "box" & z & "_s" & s
  232.                 dv.Add(nomechiaveVincoli, numchiaveVincolo)
  233.             Next s
  234.         Next z
  235.  
  236.     End Sub
  237.  
  238.  
  239. #End Region
  240.  
  241. #Region "Inizzializzazione_variabili"
  242.  
  243.     Public Sub New(ByRef nBaseSudoku As Int32, Optional ByRef inivar As Boolean = False)
  244.         nBase = nBaseSudoku
  245.         cToT = nBase * nBase
  246.         iniDizionariChiaviCandidati()
  247.         iniDizionariChiaviVincoli()
  248.         dss = New DatiSchemaSudoku
  249.         dss.Name = "StrutturaDatiPrincipale"
  250.         dss.Index_Vincolo_PT = 1
  251.         ReDim dss.Cand(nBase * cToT, nBase + 2)
  252.         ReDim dss.Vinc(cToT * 4, nBase + 2)
  253.         ReDim dss.Solution(cToT, 2)
  254.         ReDim Matrice_Candidati_Eliminati(cToT * 4, nBase + 1)
  255.         Lst_SAT = New List(Of DatiSchemaSudoku)
  256.         VincoliBloccanti = New Dictionary(Of String, Int32)
  257.         If inivar Then ImpostaVariabili(inivar)
  258.  
  259.     End Sub
  260.  
  261.     Sub ImpostaVariabili(ByRef inivar As Boolean)
  262.         If Not inivar Then Exit Sub
  263.         PrimoTentativoInCorso = True
  264.         Unica = True
  265.         Call CaricaCandidatiNumericiSudoku()
  266.         Call CaricaMatriceCandidatiPresceltiConSquare()
  267.         Call CaricaMatriceDatiSchemaSudoku()
  268.         log_sequenza_Matrici.Clear()
  269.         log_Dancing_Links.Clear()
  270.         VincoliBloccanti = New Dictionary(Of String, Int32)
  271.     End Sub
  272.  
  273. #End Region
  274.  
  275. #Region "Codice_Algoritmo_Base"
  276.  
  277.     Public Sub RisolviSudoku_DLX_Solver(ByVal Msudoku(,) As Int32, ByVal nThreads As Int32, ByVal nPercorsi As Int32, ByRef ferma As Boolean, Optional ByVal Multisol As Boolean = False)
  278.  
  279.         Dim KeyCandidato As String
  280.         Dim CollectionAppoggio As Collection
  281.         Dim EsitoInserimento As Boolean
  282.         Dim Conta As Integer
  283.         Dim IndiceCandidato As Integer
  284.         Dim IndSquere As Integer = nBase + 2
  285.         Dim Lst_vincoli_ad_1 As New List(Of Int32)
  286.         Dim Msku(nBase, nBase) As Int32
  287.         Dim rcs(2) As Int32
  288.         Multisoluzioni = Multisol
  289.         Call ImpostazioniIniziali(Msudoku)
  290.         CollectionAppoggio = New Collection
  291.         'Call Controllo_correttezza_Matrici()
  292.  
  293.         'Ripeti finché la matrice dei candidati e quella dei vincoli non sono entrambe azzerate
  294.         Do While dss.Cand(0, 0) > 0 Or dss.Vinc(0, 0) > 0 Or dss.Solution(0, 0) < cToT
  295.             Conta = 0
  296.             IndiceCandidato = 0
  297.             'Lst_vincoli_ad1.Clear()
  298.             For Conta = 1 To cToT * 4
  299.                 'Se un vincolo rimane con un solo possibile candidato da scegliere,
  300.                 'memorizziamo il candidato nella collection da passare alla funzione
  301.                 'di inserimento nella soluzione finale; poiché lo stesso candidato può
  302.                 '"emergere" contemporaneamente da più vincoli sui 4 possibili,
  303.                 'utilizziamo la collection per passare valori univoci.
  304.                 If CInt(dss.Vinc(Conta, 1)) = 1 Then
  305.                     KeyCandidato = _
  306.                         dss.Vinc(Conta, IndiceSimboloCandidatoDaCostantiSquare(CInt(dss.Vinc(Conta, IndSquere))))
  307.  
  308.                     IndiceCandidato = dc(KeyCandidato)
  309.                     If Not CollectionAppoggio.Contains(IndiceCandidato) Then
  310.                         CollectionAppoggio.Add(IndiceCandidato, CStr(IndiceCandidato))
  311.                         'Lst_vincoli_ad1.Add(Conta)
  312.                     End If
  313.                 End If
  314.             Next Conta
  315.  
  316.             'Se abbiamo trovato qualche candidato inseribile dopo il controllo vincoli ...
  317.             If CollectionAppoggio.Count > 0 Then
  318.                 '... lo passiamo alla funzione di inserimento
  319.                 'azzerando poi la collection per utilizzi futuri
  320.                 If InserisciCandidatiFissiMultipli(CollectionAppoggio, Lst_vincoli_ad_1) = True Then
  321.                     For Conta = 1 To CollectionAppoggio.Count
  322.                         CollectionAppoggio.Remove(1)
  323.                     Next
  324.                     'Se però l'inserimento candidati fissi non va a buon fine
  325.                     '(perché la funzione di inserimento controlla che non si
  326.                     'generino delle incongruenze nel piazzamento dei candidati) ...
  327.                 Else
  328.                     '... azzeriamo semplicemente la collection per utilizzi futuri
  329.                     For Conta = 1 To CollectionAppoggio.Count
  330.                         CollectionAppoggio.Remove(1)
  331.                     Next
  332.                     'A questo punto: se siamo nei tentativi bisogna tornare indietro ...
  333.                     If PrimoTentativoInCorso = False Then
  334.                         '... e cercare un altro candidato
  335.                         IndiceCandidato = ChiaveCandidato_PerTentativoDiRitorno()
  336.                         'Se troviamo un candidato di ritorno lo inseriamo nella soluzione
  337.                         If IndiceCandidato > 0 Then
  338.                             Call InserisciSingoloCandidatoFisso(IndiceCandidato, "TR1")
  339.                             'se invece non troviamo alcun candidato di ritorno
  340.                             'lo schema non è risolvibile
  341.                         Else
  342.                             MsgBox(" Lo schema è errato o irrisolvibile da TR1. ", MsgBoxStyle.Information)
  343.                             GoTo esce
  344.  
  345.                         End If
  346.                         '... se invece non siamo nei tentativi lo schema non è risolvibile
  347.                     Else
  348.  
  349.                         MsgBox(" Lo schema è errato o irrisolvibile. da CMIniziali", MsgBoxStyle.Information)
  350.                         GoTo esce
  351.  
  352.                     End If
  353.                 End If
  354.                 'se invece non abbiamo trovato candidati inseribili dopo il controllo vincoli
  355.             Else
  356.                 'Al primo mancato ritrovamento prepariamo il vettore ordinato
  357.                 'che ci indicherà d'ora in poi le priorità di vincolo su cui provare
  358.                 If PrimoTentativoInCorso = True And IndiceCandidato = 0 Then
  359.                     If nBase = 9 Or nPercorsi = 1 Then
  360.                         Call CaricaVettoreProbabilitaTentativi()
  361.                     Else
  362.                         'se il sudoku è superiore ad un 9x9
  363.                         Call CaricaVettoreProbabilitaTentativi()
  364.                         'avviamo il multi threads.
  365.                         Call Inizializza_Elenco_Candidati_per_Tentativi()
  366.                         Call Multi_Threading_Work(nThreads, nPercorsi)
  367.                         While (Trovata_Soluzione = False) AndAlso (num_Thread > 0) AndAlso ferma = False
  368.                             'Thread_avviati = Thread_avviati
  369.                             Thread.Sleep(250)
  370.                         End While
  371.                         If Trovata_Soluzione = True Then
  372.                             GoTo esce
  373.                         Else
  374.                             MsgBox(" Lo schema è errato o irrisolvibile. da Tentativi Multi_Thread, Thread avviati: " & Thread_avviati.ToString, MsgBoxStyle.Information)
  375.                             GoTo esce
  376.                         End If
  377.                     End If
  378.                 End If
  379.                 'Individuiamo un candidato da inserire nella soluzione
  380.                 IndiceCandidato = ChiaveCandidato_PerTentativo()
  381.                 'Se lo troviamo lo inseriamo
  382.                 If IndiceCandidato > 0 Then
  383.                     Call InserisciSingoloCandidatoFisso(IndiceCandidato, "PT")
  384.                     'se non lo troviamo bisogna cercare un candidato di ritorno
  385.                 Else
  386.                     'MsgBox(" Lo schema è errato o irrisolvibile, da funzione ChiaveCandidato_PerTentativo PT", MsgBoxStyle.Information)
  387.                     'GoTo esce
  388.                     IndiceCandidato = ChiaveCandidato_PerTentativoDiRitorno()
  389.                     If Not IndiceCandidato = 0 Then
  390.                         Call InserisciSingoloCandidatoFisso(IndiceCandidato, "TR2")
  391.                     Else
  392.                         MsgBox(" Lo schema è errato o irrisolvibile. da Tentativi di Ritorno 2", MsgBoxStyle.Information)
  393.                         GoTo esce
  394.                     End If
  395.                 End If
  396.             End If
  397.             If dss.Solution(0, 0) = cToT Or ferma = True Then
  398.                 Exit Do
  399.             End If
  400.             Application.DoEvents()
  401.         Loop
  402. esce:
  403.         Call ChiusuraElaborazione(Msudoku)
  404.         CollectionAppoggio = Nothing
  405.         EsitoInserimento = True
  406.         ferma = False
  407.  
  408.     End Sub
  409.  
  410.     Private Sub ImpostazioniIniziali(ByVal Msudoku(,) As Int32)
  411.         'copio la matrice del sudoku.
  412.         Mastersudoku = Msudoku.Clone
  413.         Call ImpostaVariabili(True)
  414.         Call CaricaCandidatiFissiIniziali(Msudoku)
  415.     End Sub
  416.  
  417.     Private Sub ChiusuraElaborazione(ByRef Msudoku(,) As Int32)
  418.  
  419.         Call RitornaSoluzione(Msudoku)
  420.         Call RilasciaCollectionMatrici()
  421.  
  422.     End Sub
  423.  
  424.     Friend Sub Inizializza_MatriciStruttureDati(ByRef MSD As DatiSchemaSudoku, Optional ByVal nLst As Int32 = -1)
  425.         'inizzializziamo le matrici.
  426.         ReDim MSD.Cand(cToT * nBase, nBase + 2)
  427.         ReDim MSD.Vinc(cToT * 4, nBase + 2)
  428.         ReDim MSD.Solution(cToT, 2)
  429.         MSD.Name = "NewSD " & nLst
  430.     End Sub
  431.  
  432.     Friend Sub Clona_MatriciDati(ByRef V_MatrRef()(,) As String, ByVal V_MatrVal()(,) As String, ByVal nM As Int32)
  433.  
  434.         If nM = 0 Then
  435.             Dim ncan As Int32 = cToT * nBase
  436.             'candidati
  437.             For i As Int32 = 0 To ncan
  438.                 For j As Int32 = 0 To 11
  439.                     If V_MatrVal(nM)(i, j) = Nothing Then Continue For
  440.                     V_MatrRef(nM)(i, j) = V_MatrVal(nM)(i, j).ToString.Trim
  441.                 Next j
  442.             Next i
  443.             'ricorsiva
  444.             Clona_MatriciDati(V_MatrRef, V_MatrVal, nM + 1)
  445.         ElseIf nM = 1 Then
  446.             Dim nvin As Int32 = cToT * 4
  447.             Dim subcv As Int32 = nBase + 2
  448.             'vincoli
  449.             For i As Int32 = 0 To nvin
  450.                 For j As Int32 = 0 To subcv
  451.                     If V_MatrVal(nM)(i, j) = Nothing Then Continue For
  452.                     V_MatrRef(nM)(i, j) = V_MatrVal(nM)(i, j).ToString.Trim
  453.                 Next j
  454.             Next i
  455.             'ricorsiva
  456.             Clona_MatriciDati(V_MatrRef, V_MatrVal, nM + 1)
  457.         ElseIf nM = 2 Then
  458.             'soluzione
  459.             For i As Int32 = 0 To cToT
  460.                 For j As Int32 = 0 To 2
  461.                     If V_MatrVal(nM)(i, j) = Nothing Then Continue For
  462.                     V_MatrRef(nM)(i, j) = V_MatrVal(nM)(i, j).ToString.Trim
  463.                 Next j
  464.             Next i
  465.  
  466.         End If
  467.  
  468.     End Sub
  469.  
  470.     Public Numero_del_Thread_solutivo As Int32 = 0
  471.     Public UltimoLivelloProfonditàRaggiunto As Int32 = 0
  472.     Public MaxProfonditàRicerca As Int32 = 0
  473.  
  474.     Friend Sub Aggiorna_Lista_StruttureDati(ByVal StrutDati As DatiSchemaSudoku, ByRef ListaSD As List(Of DatiSchemaSudoku), ByVal Aggiungi As Byte, Optional ByRef StdatiRef As DatiSchemaSudoku = Nothing)
  475.  
  476.         If Aggiungi = 1 Then
  477.             'aggiunge nuova stuttura dati alla lista.
  478.             Dim NuovaSD As New DatiSchemaSudoku
  479.             Call Inizializza_MatriciStruttureDati(NuovaSD, ListaSD.Count)
  480.             ListaSD.Add(NuovaSD)
  481.             'registriamo i livelli di profondità ricerca.
  482.             UltimoLivelloProfonditàRaggiunto = ListaSD.Count
  483.             If UltimoLivelloProfonditàRaggiunto > MaxProfonditàRicerca Then
  484.                 MaxProfonditàRicerca = UltimoLivelloProfonditàRaggiunto
  485.             End If
  486.             'eseguo la ricorsione per passare alla fase due.
  487.             Aggiorna_Lista_StruttureDati(StrutDati, ListaSD, 2)
  488.         ElseIf Aggiungi = 2 Then
  489.             'copia struttura dati nella lista.
  490.             Dim inls As Integer = ListaSD.Count - 1
  491.             ListaSD(inls).Index_Vincolo_PT = StrutDati.Index_Vincolo_PT
  492.             ListaSD(inls).t_CVE = StrutDati.t_CVE
  493.             ListaSD(inls).t_IC = StrutDati.t_IC
  494.             ListaSD(inls).t_UCR = StrutDati.t_UCR
  495.             Dim vmsd1()(,) As String = {ListaSD(inls).Cand, ListaSD(inls).Vinc, ListaSD(inls).Solution}
  496.             Dim vmsd2()(,) As String = {StrutDati.Cand, StrutDati.Vinc, StrutDati.Solution}
  497.             Call Clona_MatriciDati(vmsd1, vmsd2, 0)
  498.         ElseIf Aggiungi = 3 Then
  499.             'copia nella struttura dati principale dalla listastrutture.
  500.             StdatiRef.Index_Vincolo_PT = StrutDati.Index_Vincolo_PT
  501.             StdatiRef.t_CVE = StrutDati.t_CVE
  502.             StdatiRef.t_IC = StrutDati.t_IC
  503.             StdatiRef.t_UCR = StrutDati.t_UCR
  504.             Dim vmsd3()(,) As String = {StdatiRef.Cand, StdatiRef.Vinc, StdatiRef.Solution}
  505.             Dim vmsd4()(,) As String = {StrutDati.Cand, StrutDati.Vinc, StrutDati.Solution}
  506.             Call Clona_MatriciDati(vmsd3, vmsd4, 0)
  507.         End If
  508.     End Sub
  509.  
  510.     Private Sub Controllodiverificadebug()
  511.         Dim flagok As Boolean = True
  512.  
  513.         For i As Int32 = 1 To cToT * 4
  514.  
  515.             If Lst_SAT(0).Vinc(i, 1) = Lst_SAT(Lst_SAT.Count - 1).Vinc(i, 1) Then
  516.             Else
  517.                 flagok = False
  518.             End If
  519.  
  520.             If Lst_SAT(0).Vinc(i, 1) = dss.Vinc(i, 1) Then
  521.             Else
  522.                 flagok = False
  523.             End If
  524.  
  525.         Next i
  526.  
  527.     End Sub
  528.  
  529.     Public NumeroTotale_Salti_Back As ULong = 0
  530.  
  531.     Private Function ChiaveCandidato_PerTentativoDiRitorno() As Integer
  532.         'Backtracking
  533.         Dim Conta As Integer
  534.         Dim InizioConta As Integer
  535.         Dim IUEM As Integer         'IndiceUltimoElementoMatrice
  536.         Dim ChiaveCandidatoDiRitorno As Int32
  537.         Dim ChiaveVincoloInEsame As Integer
  538.         Dim UltimaChiaveRialasciataUBound_M_SAT As Int32
  539.         Dim dssX As New DatiSchemaSudoku
  540.         Call Inizializza_MatriciStruttureDati(dssX)
  541.         'Call Controllodiverificadebug()
  542.  
  543.         ChiaveCandidatoDiRitorno = 0
  544.         ChiaveCandidato_PerTentativoDiRitorno = ChiaveCandidatoDiRitorno
  545.  
  546.         Do While ChiaveCandidatoDiRitorno = 0
  547.  
  548.             IUEM = Lst_SAT.Count - 1
  549.             If IUEM = -1 Then
  550.                 ChiaveCandidatoDiRitorno = 0
  551.                 Return ChiaveCandidatoDiRitorno
  552.             End If
  553.             Call Aggiorna_Lista_StruttureDati(Lst_SAT(IUEM), Lst_SAT, 3, dssX)
  554.             InizioConta = dssX.t_IC + 1
  555.             ChiaveVincoloInEsame = dssX.t_CVE
  556.             UltimaChiaveRialasciataUBound_M_SAT = dssX.t_UCR
  557.             If ChiaveVincoloInEsame = 0 Then Exit Do
  558.  
  559.             For Conta = (InizioConta) To (nBase + 1)
  560.  
  561.                 ChiaveCandidatoDiRitorno = dc(dssX.Vinc(ChiaveVincoloInEsame, Conta))
  562.  
  563.                 If ChiaveCandidatoDiRitorno <> UltimaChiaveRialasciataUBound_M_SAT Then
  564.  
  565.                     If (CInt(dssX.Cand(ChiaveCandidatoDiRitorno, 1))) = 1 Then
  566.  
  567.                         dssX.t_IC = Conta
  568.                         dssX.t_CVE = ChiaveVincoloInEsame
  569.                         dssX.t_UCR = ChiaveCandidatoDiRitorno
  570.                         Lst_SAT(IUEM).t_IC = dssX.t_IC
  571.                         Lst_SAT(IUEM).t_CVE = dssX.t_CVE
  572.                         Lst_SAT(IUEM).t_UCR = dssX.t_UCR
  573.                         Call Aggiorna_Lista_StruttureDati(Lst_SAT(IUEM), Lst_SAT, 3, dss)
  574.                         ChiaveCandidato_PerTentativoDiRitorno = ChiaveCandidatoDiRitorno
  575.                         Sequenza_index_vincoli.Add("-indexcand-PTR: " & Conta & "     vin: " & dssX.Vinc(ChiaveVincoloInEsame, 0) & "     can: " & dssX.Cand(ChiaveCandidatoDiRitorno, 0))
  576.                         Exit Do
  577.                     Else
  578.                         ChiaveCandidatoDiRitorno = 0
  579.                     End If
  580.                 Else
  581.                     ChiaveCandidatoDiRitorno = 0
  582.                 End If
  583.             Next
  584.  
  585.             Lst_SAT.RemoveAt(IUEM)
  586.             Sequenza_index_vincoli.RemoveAt(IUEM)
  587.             NumeroTotale_Salti_Back += 1
  588.         Loop
  589.  
  590.         Return ChiaveCandidato_PerTentativoDiRitorno
  591.  
  592.     End Function
  593.  
  594.     Public IndexMaxRaggiuntoVettoreTentativi As Int32 = 0
  595.     Public IndexUltimoRaggiuntoVettoreTentativi As Int32 = 0
  596.     Public NumeroTotale_vincoli_in_esame_scansionati As ULong = 0
  597.  
  598.     Private Function ChiaveCandidato_PerTentativo() As Integer
  599.  
  600.         Dim Ultimo_Index_Vinc_PT As Int32 = dss.Index_Vincolo_PT
  601.         Dim ContaEst As Integer
  602.         Dim ContaInt As Integer
  603.         Dim ChiaveVincolo As Integer
  604.         Dim ChiaveCandidato As String
  605.         Dim FotoDatiPT As New DatiSchemaSudoku
  606.         Dim n_El_PT As Int32 = UBound(M_PT)
  607.         Call Inizializza_MatriciStruttureDati(FotoDatiPT)
  608.  
  609.         For ContaEst = Ultimo_Index_Vinc_PT To n_El_PT
  610.  
  611.             ChiaveVincolo = M_PT(ContaEst, 1)
  612.  
  613.             If (CInt(dss.Vinc(ChiaveVincolo, 1))) > 0 Then
  614.  
  615.                 For ContaInt = 2 To (nBase + 1)
  616.                     ChiaveCandidato = dss.Vinc(ChiaveVincolo, ContaInt)
  617.  
  618.                     If (Not (CInt(dss.Cand(dc(ChiaveCandidato), 1))) = 1) Or VerificaCongruenzaInserimentoFisso(dc(ChiaveCandidato), 1) = False Then
  619.                         Continue For
  620.                     Else
  621.                         dss.Index_Vincolo_PT = ContaEst
  622.                         dss.t_CVE = ChiaveVincolo
  623.                         dss.t_IC = ContaInt
  624.                         dss.t_UCR = dc(ChiaveCandidato)
  625.                         IndexUltimoRaggiuntoVettoreTentativi = ContaEst
  626.                         Sequenza_index_vincoli.Add(" indexvin-PT: " & ContaEst & "     vin: " & dss.Vinc(ChiaveVincolo, 0) & "     can: " & ChiaveCandidato)
  627.                         If IndexUltimoRaggiuntoVettoreTentativi > IndexMaxRaggiuntoVettoreTentativi Then
  628.                             IndexMaxRaggiuntoVettoreTentativi = IndexUltimoRaggiuntoVettoreTentativi
  629.                         End If
  630.                         NumeroTotale_vincoli_in_esame_scansionati += 1
  631.                         Call Aggiorna_Lista_StruttureDati(dss, Lst_SAT, 3, FotoDatiPT)
  632.                         'memorizziamo foto struttura dati.
  633.                         Call Aggiorna_Lista_StruttureDati(FotoDatiPT, Lst_SAT, 1)
  634.                         ChiaveCandidato_PerTentativo = dc(ChiaveCandidato)
  635.                         Return ChiaveCandidato_PerTentativo
  636.                     End If
  637.                 Next
  638.             End If
  639.         Next
  640.  
  641.         ChiaveCandidato_PerTentativo = 0
  642.  
  643.     End Function
  644.  
  645.     Private Sub CaricaVettoreProbabilitaTentativi()
  646.  
  647.         Dim Conta As Integer
  648.         Dim i As Integer
  649.         i = 0
  650.         For Conta = 1 To cToT * 4
  651.             If CInt(dss.Vinc(Conta, 1)) > 0 Then
  652.                 i = i + 1
  653.             End If
  654.         Next
  655.         ReDim Preserve M_PT(i, 2)
  656.         M_PT(0, 0) = i
  657.         i = 0
  658.         For Conta = 1 To cTOT * 4
  659.             If (CInt(dss.Vinc(Conta, 1))) > 0 Then
  660.                 i = i + 1
  661.                 M_PT(i, 1) = Conta
  662.                 M_PT(i, 2) = dss.Vinc(Conta, 1)
  663.  
  664.             End If
  665.         Next
  666.  
  667.         If Multisoluzioni = False Then
  668.             Call QuickSortChiaviPerTentativi(M_PT)
  669.         Else
  670.             Call QuickSortChiaviPerTentativi(M_PT)
  671.             Call Mischia(M_PT, i, 10)
  672.             Call QuickSortChiaviPerTentativi(M_PT)
  673.         End If
  674.  
  675.         'Ragruppa la lista vincoli per tentativi, in base ai vincoli diretti.
  676.         Dim Matrice_per_vincoli_diretti(,) As String
  677.         'impostiamo le dimensioni della matrice
  678.         ReDim Matrice_per_vincoli_diretti(UBound(M_PT), nBase * 3)
  679.         'rileviamo i candidati rimasti per i tentativi, in base ai quali cerchiamo eventuali vincoli diretti nella lista.
  680.         Call Inizializza_Elenco_Candidati_per_Tentativi()
  681.         'carichiamo la matrice con i vincoli ragruppati.
  682.         Call Ragruppa_vincoli_diretti(Matrice_per_vincoli_diretti, dss)
  683.         'aggiorniamo la lista M_PT in base ai ragruppamenti.
  684.         Call Aggiorna_la_Lista_M_PT(Matrice_per_vincoli_diretti)
  685.  
  686.         PrimoTentativoInCorso = False
  687.  
  688.     End Sub
  689.  
  690.     Public Sub Ragruppa_vincoli_diretti(ByRef MVD(,) As String, ByRef mds As DatiSchemaSudoku)
  691.  
  692.         Dim cont1 As Int32 = 0
  693.         Dim cont2 As Int32 = 0
  694.         Dim lista1 As New List(Of Int32)
  695.         Dim lista2 As New List(Of String)
  696.         Dim Lista_Vincoli As New List(Of String)
  697.  
  698.         For Each vinc1 As Int32 In Elenco_Candidati_nonEliminati_daVincoliPT.Keys
  699.             cont1 += 1
  700.             cont2 = 0
  701.             Lista_Vincoli.Add(vinc1)
  702.             lista1.AddRange(Elenco_Candidati_nonEliminati_daVincoliPT(vinc1))
  703.             For Icand As Int32 = 1 To lista1.Count
  704.  
  705.                 lista2.Add(mds.Vinc(vinc1, lista1(Icand - 1)))
  706.             Next Icand
  707.             For Each vinc2 As Int32 In Elenco_Candidati_nonEliminati_daVincoliPT.Keys
  708.                 cont2 += 1
  709.                 If cont2 > cont1 Then
  710.                     For Each Icand2 As Int32 In Elenco_Candidati_nonEliminati_daVincoliPT(vinc2)
  711.  
  712.                         If lista2.Contains(mds.Vinc(vinc2, Icand2)) = True Then
  713.  
  714.                             Lista_Vincoli.Add(vinc2)
  715.                             Exit For
  716.                         End If
  717.                     Next Icand2
  718.                 End If
  719.             Next vinc2
  720.             lista2.Clear()
  721.  
  722.             For i As Int32 = 0 To Lista_Vincoli.Count - 1
  723.  
  724.                 MVD(cont1, i + 1) = Lista_Vincoli(i)
  725.             Next i
  726.  
  727.             Lista_Vincoli.Clear()
  728.             lista1.Clear()
  729.         Next vinc1
  730.  
  731.  
  732.  
  733.     End Sub
  734.  
  735.     Public Sub Aggiorna_la_Lista_M_PT(ByRef MVD(,) As String)
  736.  
  737.         'Dizionario dei Candidati non eliminati per la fase a Tentativi.
  738.         Dim Elenco_Candidati_nonEliminati_daVincoliPT2 As New Dictionary(Of Int32, List(Of Int32))
  739.  
  740.         For x As Int32 = 1 To UBound(MVD) - 1
  741.  
  742.             For y As Int32 = 1 To nBase + 2
  743.  
  744.                 If Not MVD(x, y) = "" Then
  745.                     If Not Elenco_Candidati_nonEliminati_daVincoliPT2.ContainsKey(CInt(MVD(x, y))) Then
  746.  
  747.                         Elenco_Candidati_nonEliminati_daVincoliPT2.Add(CInt(MVD(x, y)), New List(Of Int32))
  748.                     End If
  749.  
  750.                 End If
  751.             Next y
  752.         Next x
  753.  
  754.         For Each vinc As Int32 In Elenco_Candidati_nonEliminati_daVincoliPT2.Keys
  755.  
  756.             Elenco_Candidati_nonEliminati_daVincoliPT2(vinc).AddRange(Elenco_Candidati_nonEliminati_daVincoliPT(vinc))
  757.  
  758.         Next vinc
  759.  
  760.         Elenco_Candidati_nonEliminati_daVincoliPT.Clear()
  761.  
  762.         For Each vinc As Int32 In Elenco_Candidati_nonEliminati_daVincoliPT2.Keys
  763.  
  764.             Elenco_Candidati_nonEliminati_daVincoliPT.Add(vinc, New List(Of Int32))
  765.  
  766.             Elenco_Candidati_nonEliminati_daVincoliPT(vinc).AddRange(Elenco_Candidati_nonEliminati_daVincoliPT2(vinc))
  767.         Next vinc
  768.  
  769.         For i As Int32 = 1 To UBound(M_PT)
  770.             M_PT(i, 1) = 0
  771.             M_PT(i, 2) = 0
  772.         Next i
  773.  
  774.         Dim cont As Int32 = 0
  775.         For Each vinc As Int32 In Elenco_Candidati_nonEliminati_daVincoliPT2.Keys
  776.             cont += 1
  777.             M_PT(cont, 1) = vinc
  778.             M_PT(cont, 2) = Elenco_Candidati_nonEliminati_daVincoliPT2(vinc).Count
  779.         Next vinc
  780.         Dim MLengh As Int32 = UBound(M_PT)
  781.         For idx As Int32 = 1 To MLengh
  782.             If M_PT(idx, 1) = 0 Then
  783.                 MLengh = idx - 1
  784.                 Exit For
  785.             End If
  786.         Next
  787.         Call QuickSortChiaviPerTentativi(M_PT, -2, MLengh)
  788.  
  789.     End Sub
  790.  
  791.     Public Sub Inizializza_Elenco_Candidati_per_Tentativi()
  792.  
  793.         Elenco_Candidati_nonEliminati_daVincoliPT = New Dictionary(Of Int32, List(Of Int32))
  794.  
  795.         For i As Int32 = 1 To UBound(M_PT) - 1
  796.  
  797.             For j As Int32 = 1 To UBound(Matrice_Candidati_Eliminati) - 1
  798.  
  799.                 If M_PT(i, 1) = Matrice_Candidati_Eliminati(j, 1) Then
  800.  
  801.                     Elenco_Candidati_nonEliminati_daVincoliPT.Add(M_PT(i, 1), New List(Of Int32))
  802.  
  803.                     For k As Int32 = 2 To nBase + 1
  804.  
  805.                         If Matrice_Candidati_Eliminati(j, k) > 0 Then
  806.                             Elenco_Candidati_nonEliminati_daVincoliPT(Matrice_Candidati_Eliminati(j, 1)).Add(Matrice_Candidati_Eliminati(j, k))
  807.                         End If
  808.  
  809.                     Next k
  810.                     Exit For
  811.                 End If
  812.  
  813.             Next j
  814.  
  815.         Next i
  816.  
  817.     End Sub
  818.  
  819.     Public Function RitornaNindxNpercorsi(ByRef newECV As Object, ByVal nThr As Int32) As Int32()
  820.         Dim nv(2) As Int32
  821.         Dim nvie As Int32 = 1
  822.         nv(0) = 0
  823.  
  824.         For Each vinc As Int32 In newECV.Keys
  825.  
  826.             nvie *= newECV(vinc).count
  827.             If nvie > nThr Then
  828.                 If nThr = 1 Then nv(1) = 1
  829.                 Exit For
  830.             Else
  831.                 nv(0) += 1
  832.                 nv(1) = nvie
  833.             End If
  834.  
  835.         Next
  836.  
  837.         Return nv
  838.     End Function
  839.  
  840.     Public Sub Carica_matrice_prercorsi_MT(ByRef Matrice_Percorsi As Int32(,), ByRef newelenco As Dictionary(Of Int32, List(Of Int32)), ByVal nindx As Int32, ByVal nper As Int32)
  841.  
  842.         Dim matrice_di_appoggio(,) As Int32
  843.         ReDim matrice_di_appoggio(nindx, 5)
  844.         'inizializzazione della matrice di appoggio.
  845.         For x As Int32 = 1 To nindx
  846.  
  847.             For y As Int32 = 1 To 5
  848.  
  849.                 If y = 1 Then
  850.                     'indice dei vincoli in esame.
  851.                     matrice_di_appoggio(x, y) = x
  852.                 End If
  853.                 If y = 2 Then
  854.                     'quantità degli elementi candidati per vincolo.
  855.                     Dim cont As Int32 = 1
  856.                     For Each elv As Int32 In newelenco.Keys
  857.                         If cont = x Then
  858.                             matrice_di_appoggio(x, y) = newelenco(elv).Count
  859.                             Exit For
  860.                         End If
  861.                         cont += 1
  862.                     Next elv
  863.                 End If
  864.                 If y = 3 Then
  865.                     'moltiplicatore dei percorsi.
  866.                     If x = 1 Then
  867.                         matrice_di_appoggio(x, y) = 1
  868.                     Else
  869.                         matrice_di_appoggio(x, y) = matrice_di_appoggio(x, 2)
  870.                     End If
  871.                 End If
  872.                 If y = 4 Then
  873.                     'numero quantità per elemento candidato
  874.                     If x = 1 Then
  875.                         matrice_di_appoggio(x, y) = matrice_di_appoggio(x, 2) * matrice_di_appoggio(x, 3)
  876.                     Else
  877.                         matrice_di_appoggio(x, y) = matrice_di_appoggio(x, 3) * matrice_di_appoggio(x - 1, 4)
  878.                     End If
  879.                 End If
  880.                 If y = 5 Then
  881.                     'quantità di ripetizioni per elemento candidato nella matrice dei percorsi.
  882.                     matrice_di_appoggio(x, y) = nper / matrice_di_appoggio(x, 4)
  883.                 End If
  884.             Next y
  885.  
  886.         Next x
  887.  
  888.  
  889.  
  890.         'inizializziamo la matrice dei percorsi.
  891.         Dim Conta_elementi As Int32 = 0
  892.         Dim elemento_in_esame As Int32 = 0
  893.         Dim Quant_Elem_per_cand As Int32
  894.  
  895.         For x As Int32 = 1 To nindx
  896.             'numero di elementi consecutivi nella matrice di appoggio.
  897.             Quant_Elem_per_cand = matrice_di_appoggio(x, 5)
  898.             elemento_in_esame = 1
  899.  
  900.             For y As Int32 = 1 To nper
  901.                 Conta_elementi += 1
  902.  
  903.  
  904.                 If Conta_elementi > Quant_Elem_per_cand Then
  905.  
  906.                     If elemento_in_esame = matrice_di_appoggio(x, 2) Then
  907.                         elemento_in_esame = 1
  908.                     Else
  909.                         elemento_in_esame += 1
  910.                     End If
  911.  
  912.                     Conta_elementi = 1
  913.                 Else
  914.  
  915.                 End If
  916.  
  917.                 Dim cont As Int32 = 1
  918.                 For Each elv As Int32 In newelenco.Keys
  919.                     If cont = x Then
  920.                         Matrice_Percorsi(x, y) = newelenco(elv)(elemento_in_esame - 1)
  921.                         Exit For
  922.                     End If
  923.                     cont += 1
  924.                 Next elv
  925.  
  926.             Next y
  927.             Conta_elementi = 0
  928.         Next x
  929.  
  930.         Dim matrice_dei_percorsi As String = ""
  931.  
  932.         For x As Int32 = 1 To nindx
  933.  
  934.             matrice_dei_percorsi &= Environment.NewLine
  935.  
  936.             For y As Int32 = 1 To nper
  937.                 If Matrice_Percorsi(x, y) < 10 Then
  938.                     matrice_dei_percorsi &= "0" & Matrice_Percorsi(x, y) & "  "
  939.                 Else
  940.                     matrice_dei_percorsi &= Matrice_Percorsi(x, y) & "  "
  941.                 End If
  942.             Next y
  943.  
  944.         Next x
  945.  
  946.         'MsgBox(matrice_dei_percorsi, MsgBoxStyle.Information)
  947.  
  948.  
  949.     End Sub
  950.  
  951.     Public Function Imposta_le_vie_iniziali(ByVal newelencoX As Dictionary(Of Int32, List(Of Int32)), ByVal Matrice_Percorsi As Int32(,), ByVal ncvin() As Int32, ByVal npercorso As Int32) As Dictionary(Of Int32, List(Of Int32))
  952.  
  953.         Dim numero_ultimo_indx_listavinc As Int32 = ncvin(0)
  954.         Dim numero_percorsi As Int32 = ncvin(1)
  955.  
  956.         Dim conta As Int32 = 1
  957.         For Each elemv As Int32 In newelencoX.Keys
  958.             If conta > numero_ultimo_indx_listavinc Then
  959.                 Exit For
  960.             End If
  961.             Dim flg As Boolean
  962.  
  963.             Do
  964.                 flg = False
  965.                 'eliminiamo i candidati non neccessari dal percorso.
  966.                 For Each cand As Int32 In newelencoX(elemv)
  967.  
  968.                     If Not cand = Matrice_Percorsi(conta, npercorso) Then
  969.                         newelencoX(elemv).Remove(cand)
  970.                         flg = True
  971.                         Exit For
  972.                     End If
  973.                 Next cand
  974.  
  975.             Loop While (flg = True)
  976.  
  977.             conta += 1
  978.         Next
  979.  
  980.         Return newelencoX
  981.     End Function
  982.  
  983.     Public Elenchi_candidati_da_vincoli_MT As New List(Of Dictionary(Of Int32, List(Of Int32)))
  984.  
  985.     Public Sub Distribuisci_elenco_per_il_MT(ByVal numThreads As Int32, ByVal elencocandidati As Dictionary(Of Int32, List(Of Int32)))
  986.  
  987.         Dim newelenco() As Dictionary(Of Int32, List(Of Int32))
  988.  
  989.         'ritorna il numero di index dell'elenco dei candidati che ci servono, ed il numero di vie.
  990.         'ncvin(0)= numero index
  991.         'ncvin(1)= numero percorsi sviluppati
  992.         Dim ncvin() As Int32 = RitornaNindxNpercorsi(elencocandidati, num_Thread)
  993.         'creiamo la matrice dei percorsi.
  994.         Dim Matrice_Percorsi(,) As Int32
  995.         ReDim Matrice_Percorsi(ncvin(0), ncvin(1))
  996.         'se i thread sono maggiori di 1
  997.         If ncvin(1) > 1 Then
  998.             'carichiamo la matrice dei percorsi.
  999.             Call Carica_matrice_prercorsi_MT(Matrice_Percorsi, elencocandidati, ncvin(0), ncvin(1))
  1000.         End If
  1001.  
  1002.         numThreads = ncvin(1)
  1003.         'impostiamo il numero di thread necessari per ogni percorso.
  1004.         num_Thread = ncvin(1)
  1005.  
  1006.         ReDim newelenco(ncvin(1))
  1007.         Dim contapercorsi As Int32 = 0
  1008.  
  1009.         While numThreads > 0
  1010.  
  1011.             Dim newelencoXT As Dictionary(Of Int32, List(Of Int32))
  1012.             newelenco(contapercorsi) = New Dictionary(Of Int32, List(Of Int32))
  1013.  
  1014.  
  1015.             For Each elem As Int32 In elencocandidati.Keys
  1016.  
  1017.                 newelenco(contapercorsi).Add(elem, New List(Of Int32))
  1018.  
  1019.                 For Each ic As Int32 In elencocandidati(elem)
  1020.                     newelenco(contapercorsi)(elem).Add(ic)
  1021.                 Next ic
  1022.  
  1023.  
  1024.             Next elem
  1025.             contapercorsi += 1
  1026.             newelencoXT = New Dictionary(Of Int32, List(Of Int32))
  1027.             'elimina le vie(candidati) che non servono per i percorsi iniziali.
  1028.             'se i thread sono maggiori di 1
  1029.             If ncvin(1) >= 1 Then
  1030.                 newelencoXT = Imposta_le_vie_iniziali(newelenco(contapercorsi - 1), Matrice_Percorsi, ncvin, contapercorsi)
  1031.             End If
  1032.             'inseriamo la nuova lista dei percorsi candidati per il MultiThreading.
  1033.             Elenchi_candidati_da_vincoli_MT.Add(newelencoXT)
  1034.  
  1035.             numThreads -= 1
  1036.         End While
  1037.  
  1038.     End Sub
  1039.  
  1040.     Public Sub Multi_Threading_Work(ByVal nt As Int32, ByVal np As Int32)
  1041.  
  1042.         'ThreadingPool Delegate WaitCallback instance.
  1043.         Dim ThrPool As WaitCallback = New WaitCallback(AddressOf Thread_Solver_Job2_MT)
  1044.         num_step = np
  1045.         'ThreadingPool
  1046.         Dim nThreads As Int32
  1047.         Try
  1048.             nThreads = (nt)
  1049.             num_Thread = nThreads
  1050.         Catch ex As Exception
  1051.             nThreads = 128
  1052.             num_Thread = nThreads
  1053.         End Try
  1054.         Dim maxThreadPool As Int32 = nThreads
  1055.         Dim aviablethreadsPool As Int32 = nThreads
  1056.         ThreadPool.SetMaxThreads(maxThreadPool, aviablethreadsPool)
  1057.  
  1058.         'distribuzione su più elenchi per il MT.
  1059.         Call Distribuisci_elenco_per_il_MT(nThreads, Elenco_Candidati_nonEliminati_daVincoliPT)
  1060.  
  1061.         'se il numero dei percorsi trovati è inferiore al numero di thread
  1062.         If num_Thread < nThreads Then
  1063.             'si diminuiscono i thread
  1064.             nThreads = num_Thread
  1065.         End If
  1066.         'se il numero dei percorsi trovati è superiore al numero di thread
  1067.         If num_Thread > nThreads Then
  1068.             'si diminuiscono i thread
  1069.             nThreads = num_Thread
  1070.         End If
  1071.  
  1072.         'ThreadingPool
  1073.         For t As Int32 = 1 To nThreads
  1074.  
  1075.             If Trovata_Soluzione = True Then Exit For
  1076.  
  1077.             ThreadPool.QueueUserWorkItem(ThrPool, t)
  1078.  
  1079.         Next t
  1080.  
  1081.  
  1082.     End Sub
  1083.  
  1084.     Public num_Thread As Int32
  1085.     Public Thread_avviati As Int32 = 0
  1086.     Public num_step As Int32 = 0
  1087.     Public Trovata_Soluzione As Boolean = False
  1088.  
  1089.     ''' <summary>
  1090.     ''' Unità thread job per il multi threading
  1091.     ''' </summary>
  1092.     ''' <param name="n_Thread"></param>
  1093.     ''' <remarks></remarks>
  1094.     Public Sub Thread_Solver_Job2_MT(ByVal n_Thread As Int32)
  1095.  
  1096.  
  1097.  
  1098.  
  1099.     End Sub
  1100.  
  1101.     ''' <summary>
  1102.     ''' Unità thread job per il multi threading
  1103.     ''' </summary>
  1104.     ''' <param name="n_Thread"></param>
  1105.     ''' <remarks></remarks>
  1106.     Public Sub Thread_Solver_Job_MT(ByVal n_Thread As Int32)
  1107.  
  1108.         Dim FotoDatiPT As New DatiSchemaSudoku
  1109.         Dim n_El_PT As Int32 = UBound(M_PT)
  1110.         Call Inizializza_MatriciStruttureDati(FotoDatiPT, n_Thread)
  1111.         Dim sd1()(,) As String = {dss.Cand, dss.Vinc, dss.Solution}
  1112.         Dim sd2()(,) As String = {FotoDatiPT.Cand, FotoDatiPT.Vinc, FotoDatiPT.Solution}
  1113.         Dim Numero_percorsi As Int32 = num_step
  1114.         Dim indx_cand As Int32 = 0
  1115.         Dim candidato As String = ""
  1116.         Dim chiave_candidato As Int32 = 0
  1117.         Dim nc As Int32 = 0
  1118.         Dim indxcand As Int32 = 0
  1119.         Dim num_PT As Int32 = Numero_percorsi * n_Thread
  1120.         Dim conta_P As Int32 = (num_PT - Numero_percorsi) + 1
  1121.         Dim cont_indx As Int32 = 0
  1122.         Dim conta_vincoli As Int32 = 0
  1123.         Dim n_soluzione As Int32 = cToT
  1124.         Dim Modificatore As Int32 = 1
  1125.         Thread_avviati += 1
  1126.         Application.DoEvents()
  1127.  
  1128.         Call Clona_MatriciDati(sd2, sd1, 0) 'clona sd1(master) in sd2(step0)
  1129.         Call Clona_step_avanzamenti_MT(FotoDatiPT, dss)
  1130.         Dim Lista_Step_Avanzamenti() As DatiSchemaSudoku
  1131.         ReDim Lista_Step_Avanzamenti(Elenchi_candidati_da_vincoli_MT(n_Thread - 1).Count)
  1132.         Dim FotoDatiAvanzamento As New DatiSchemaSudoku
  1133.         Dim vincoloinesame As Int32
  1134.         Dim contvinc As Int32
  1135.         Dim matrice_segna_passi(,) As Int32
  1136.         ReDim matrice_segna_passi(Elenchi_candidati_da_vincoli_MT(n_Thread - 1).Count, 2)
  1137.         Dim sd3()(,) As String
  1138.         Dim Ultimo_step_buono As Int32
  1139.         Dim Pila_step_buoni As New List(Of Int32)
  1140.         Dim backtrack As Boolean = False
  1141.         'step di partenza.
  1142.         Lista_Step_Avanzamenti(0) = (FotoDatiPT)
  1143.         Pila_step_buoni.Add(0)
  1144.  
  1145.         For contvinc = 1 To Elenchi_candidati_da_vincoli_MT(n_Thread - 1).Count
  1146. back2:
  1147.  
  1148.             conta_vincoli = 0
  1149.             For Each iv As Int32 In Elenchi_candidati_da_vincoli_MT(n_Thread - 1).Keys
  1150.                 conta_vincoli += 1
  1151.                 If contvinc = conta_vincoli Then
  1152.                     vincoloinesame = iv
  1153.                     Exit For
  1154.                 End If
  1155.             Next iv
  1156.  
  1157.             If backtrack = False Then
  1158.                 FotoDatiAvanzamento = New DatiSchemaSudoku
  1159.                 Call Inizializza_MatriciStruttureDati(FotoDatiAvanzamento, n_Thread)
  1160.                 FotoDatiAvanzamento.Name = n_Thread & "-" & contvinc
  1161.                 sd3 = {FotoDatiAvanzamento.Cand, FotoDatiAvanzamento.Vinc, FotoDatiAvanzamento.Solution}
  1162.                 Call Clona_MatriciDati(sd3, sd2, 0) 'clona sd2(master) in sd3(step+)
  1163.                 Call Clona_step_avanzamenti_MT(FotoDatiAvanzamento, FotoDatiPT)
  1164.                 'step di avanzamento.
  1165.                 Lista_Step_Avanzamenti(contvinc) = (FotoDatiAvanzamento)
  1166.                 'se il vincolo in esame non è valido, avanza al prossimo.
  1167.                 If Not (CInt(Lista_Step_Avanzamenti(contvinc).Vinc(vincoloinesame, 1))) > 0 Then
  1168.                     backtrack = False
  1169.                     Continue For
  1170.                 End If
  1171.             Else
  1172.                 'backtrak ritorna allo step precedente.
  1173.                 If contvinc = 1 Then
  1174.                     sd3 = {Lista_Step_Avanzamenti(0).Cand, Lista_Step_Avanzamenti(0).Vinc, Lista_Step_Avanzamenti(0).Solution}
  1175.                     Call Clona_MatriciDati(sd2, sd3, 0) 'clona sd3(backtrack) in sd2(master)
  1176.                     Call Clona_step_avanzamenti_MT(FotoDatiPT, Lista_Step_Avanzamenti(1))
  1177.                     backtrack = False
  1178.                     GoTo back2
  1179.                 Else
  1180.                     sd3 = {Lista_Step_Avanzamenti(contvinc - 1).Cand, Lista_Step_Avanzamenti(contvinc - 1).Vinc, Lista_Step_Avanzamenti(contvinc - 1).Solution}
  1181.                     Call Clona_MatriciDati(sd2, sd3, 0) 'clona sd3(backtrack) in sd2(master)
  1182.                     Call Clona_step_avanzamenti_MT(FotoDatiPT, Lista_Step_Avanzamenti(contvinc - 1))
  1183.                     backtrack = False
  1184.                     GoTo back2
  1185.                 End If
  1186.             End If
  1187.  
  1188.             If Trovata_Soluzione = True Then
  1189.                 GoTo esce
  1190.             End If
  1191.  
  1192.             nc = Elenchi_candidati_da_vincoli_MT(n_Thread - 1)(vincoloinesame).Count
  1193.             cont_indx = 0
  1194.             candidato = ""
  1195.             Modificatore = nc
  1196.  
  1197.             If Lista_Step_Avanzamenti(contvinc).t_IC > 0 Then
  1198.                 cont_indx = Lista_Step_Avanzamenti(contvinc).t_IC
  1199.             End If
  1200. back1:
  1201.             If cont_indx = Modificatore Then
  1202.                 matrice_segna_passi(contvinc, 2) = 0
  1203.                 If contvinc = Elenchi_candidati_da_vincoli_MT(n_Thread - 1).Count - 1 Then
  1204.                     GoTo esce
  1205.                 Else
  1206.                     backtrack = False
  1207.                     'Lista_Step_Avanzamenti(contvinc) = Nothing
  1208.                     contvinc += 1
  1209.                     GoTo back2
  1210.                 End If
  1211.             End If
  1212.  
  1213.             While cont_indx < Modificatore
  1214.  
  1215.                 For i As Int32 = 0 To nc - 1
  1216.                     cont_indx += 1
  1217.                     If cont_indx <= Modificatore Then
  1218.                         indx_cand = Elenchi_candidati_da_vincoli_MT(n_Thread - 1)(vincoloinesame)(cont_indx - 1)
  1219.                         candidato = Lista_Step_Avanzamenti(contvinc).Vinc(vincoloinesame, indx_cand)
  1220.                         matrice_segna_passi(contvinc, 1) = vincoloinesame
  1221.                         matrice_segna_passi(contvinc, 2) = cont_indx
  1222.                         Exit While
  1223.                     End If
  1224.  
  1225.                 Next i
  1226.  
  1227.             End While
  1228.  
  1229.             'se il vincolo in esame non è valido, avanza al prossimo.
  1230.             If Not (CInt(Lista_Step_Avanzamenti(contvinc).Vinc(vincoloinesame, 1))) > 0 Then
  1231.                 backtrack = False
  1232.                 Continue For
  1233.             End If
  1234.  
  1235.             'verifico se il candidato è valido.
  1236.             If (Not (CInt(Lista_Step_Avanzamenti(contvinc).Cand(dc(candidato), 1))) = 1) Or VerificaCongruenzaInserimentoFisso_MT(dc(candidato), Lista_Step_Avanzamenti(contvinc)) = False Then
  1237.                 'se il candidato abbinato al vincolo, non è valido avanza al successivo.
  1238.                 GoTo back1
  1239.                 'Continue For
  1240.             Else
  1241.  
  1242.                 'se è valido, inseriamo il candidato e eseguiamo gli aggiornamenti.
  1243.                 chiave_candidato = dc(candidato)
  1244.                 Call InserisciSingoloCandidatoFisso_MT(chiave_candidato, "MultiThread" & n_Thread.ToString, Lista_Step_Avanzamenti(contvinc))
  1245.  
  1246.                 'se il sudoku è risolto esce.
  1247.                 If Lista_Step_Avanzamenti(contvinc).Solution(0, 0) = n_soluzione Then
  1248.                     Trovata_Soluzione = True
  1249.                     Call Clona_MatriciDati(sd1, sd3, 0) 'clona sd3 in sd1
  1250.                     UltimoLivelloProfonditàRaggiunto = Pila_step_buoni.Count
  1251.                     Numero_del_Thread_solutivo = n_Thread
  1252.                     MaxProfonditàRicerca = contvinc
  1253.                     GoTo esce
  1254.                 End If
  1255.  
  1256.                 'inserisce eventuali candidati dal dansinglinks dei vincoli.
  1257.                 If Candidati_multipli_dai_vincoli_MT(n_Thread, Lista_Step_Avanzamenti(contvinc)) = False Then
  1258.                     'se si verifica un False, passiamo ai tentativi di ritorno backtracking
  1259.                     Dim indx_ultimo_step As Int32
  1260.                     If contvinc = 1 Or Pila_step_buoni.Count = 0 Then
  1261.                         GoTo esce
  1262.                     Else
  1263.                         'matrice_segna_passi(contvinc, 2) = 0
  1264.                         For i As Int32 = contvinc To Elenchi_candidati_da_vincoli_MT(n_Thread - 1).Count
  1265.                             matrice_segna_passi(contvinc, 2) = 0
  1266.                         Next i
  1267.                         indx_ultimo_step = Pila_step_buoni.Count - 1
  1268.                         contvinc = Pila_step_buoni(indx_ultimo_step)
  1269.                         Pila_step_buoni.RemoveAt(indx_ultimo_step)
  1270.                         backtrack = True
  1271.                         GoTo back2
  1272.                     End If
  1273.  
  1274.                 Else
  1275.                     'altrimenti memorizza un nuovo step e prosegue normalmente.
  1276.                     sd3 = {Lista_Step_Avanzamenti(contvinc).Cand, Lista_Step_Avanzamenti(contvinc).Vinc, Lista_Step_Avanzamenti(contvinc).Solution}
  1277.                     Lista_Step_Avanzamenti(contvinc).t_CVE = vincoloinesame
  1278.                     Lista_Step_Avanzamenti(contvinc).t_IC = cont_indx
  1279.                     Lista_Step_Avanzamenti(contvinc).t_UCR = chiave_candidato
  1280.                     Call Clona_step_avanzamenti_MT(FotoDatiPT, Lista_Step_Avanzamenti(contvinc))
  1281.                     Call Clona_MatriciDati(sd2, sd3, 0) 'clona sd3(avanzamento) in sd2(master-back)
  1282.                     Ultimo_step_buono = contvinc
  1283.                     Pila_step_buoni.Add(Ultimo_step_buono)
  1284.                 End If
  1285.  
  1286.                 'se il sudoku è risolto esce.
  1287.                 If Lista_Step_Avanzamenti(contvinc).Solution(0, 0) = n_soluzione Then
  1288.                     Trovata_Soluzione = True
  1289.                     Call Clona_MatriciDati(sd1, sd3, 0) 'clona sd3 in sd1
  1290.                     UltimoLivelloProfonditàRaggiunto = Pila_step_buoni.Count
  1291.                     Numero_del_Thread_solutivo = n_Thread
  1292.                     MaxProfonditàRicerca = contvinc
  1293.                     GoTo esce
  1294.                 End If
  1295.  
  1296.             End If
  1297.  
  1298.             backtrack = False
  1299.  
  1300.         Next contvinc
  1301.  
  1302. esce:
  1303.         UltimoLivelloProfonditàRaggiunto = Pila_step_buoni.Count
  1304.         Numero_del_Thread_solutivo = n_Thread
  1305.         MaxProfonditàRicerca = contvinc
  1306.         If num_Thread > 0 Then
  1307.             num_Thread -= 1
  1308.             Application.DoEvents()
  1309.         End If
  1310.  
  1311.     End Sub
  1312.  
  1313.     Public Sub Clona_step_avanzamenti_MT(ByRef a As DatiSchemaSudoku, ByVal b As DatiSchemaSudoku)
  1314.         'chiave vincolo in esame
  1315.         a.t_CVE = b.t_CVE
  1316.         'index candidato
  1317.         a.t_IC = b.t_IC
  1318.         'ultimo candidato rilasciato
  1319.         a.t_UCR = b.t_UCR
  1320.     End Sub
  1321.  
  1322.     Public Function Candidati_multipli_dai_vincoli_MT(ByRef nThread As String, ByRef mds As Object) As Boolean
  1323.  
  1324.         Dim Conta As Int32 = 0
  1325.         Dim IndiceCandidato As Int32 = 0
  1326.         Dim KeyCandidato As String
  1327.         Dim CollectionAppoggio As Collection
  1328.         Dim IndSquere As Integer = nBase + 2
  1329.         Dim resultok As Boolean = True
  1330.         CollectionAppoggio = New Collection
  1331.  
  1332.         For Conta = 1 To cToT * 4
  1333.             'Se un vincolo rimane con un solo possibile candidato da scegliere,
  1334.             'memorizziamo il candidato nella collection da passare alla funzione
  1335.             'di inserimento nella soluzione finale; poiché lo stesso candidato può
  1336.             '"emergere" contemporaneamente da più vincoli sui 4 possibili,
  1337.             'utilizziamo la collection per passare valori univoci.
  1338.             If CInt(mds.Vinc(Conta, 1)) = 1 Then
  1339.                 KeyCandidato = _
  1340.                     mds.Vinc(Conta, IndiceSimboloCandidatoDaCostantiSquare(CInt(mds.Vinc(Conta, IndSquere))))
  1341.  
  1342.                 IndiceCandidato = dc(KeyCandidato)
  1343.                 If Not CollectionAppoggio.Contains(IndiceCandidato) Then
  1344.                     CollectionAppoggio.Add(IndiceCandidato, CStr(IndiceCandidato))
  1345.                 End If
  1346.             End If
  1347.         Next Conta
  1348.  
  1349.         'Se abbiamo trovato qualche candidato inseribile dopo il controllo vincoli ...
  1350.         If CollectionAppoggio.Count > 0 Then
  1351.             '... lo passiamo alla funzione di inserimento
  1352.             'azzerando poi la collection per utilizzi futuri
  1353.             If InserisciCandidatiFissiMultipli_MT(CollectionAppoggio, mds) = True Then
  1354.                 CollectionAppoggio = New Collection
  1355.                 resultok = True
  1356.             Else
  1357.                 CollectionAppoggio = New Collection
  1358.                 resultok = False
  1359.             End If
  1360.  
  1361.         End If
  1362.  
  1363.         Return resultok
  1364.     End Function
  1365.  
  1366.     Private Function IndiceSimboloCandidatoDaCostantiSquare(ByVal CostanteSquare As Integer) As Integer
  1367.  
  1368.         Select Case CostanteSquare
  1369.             Case p1
  1370.                 IndiceSimboloCandidatoDaCostantiSquare = s1 + 1
  1371.             Case p2
  1372.                 IndiceSimboloCandidatoDaCostantiSquare = s2 + 1
  1373.             Case p3
  1374.                 IndiceSimboloCandidatoDaCostantiSquare = s3 + 1
  1375.             Case p4
  1376.                 IndiceSimboloCandidatoDaCostantiSquare = s4 + 1
  1377.             Case p5
  1378.                 IndiceSimboloCandidatoDaCostantiSquare = s5 + 1
  1379.             Case p6
  1380.                 IndiceSimboloCandidatoDaCostantiSquare = s6 + 1
  1381.             Case p7
  1382.                 IndiceSimboloCandidatoDaCostantiSquare = s7 + 1
  1383.             Case p8
  1384.                 IndiceSimboloCandidatoDaCostantiSquare = s8 + 1
  1385.             Case p9
  1386.                 IndiceSimboloCandidatoDaCostantiSquare = s9 + 1
  1387.             Case p10
  1388.                 IndiceSimboloCandidatoDaCostantiSquare = s10 + 1
  1389.             Case p11
  1390.                 IndiceSimboloCandidatoDaCostantiSquare = s11 + 1
  1391.             Case p12
  1392.                 IndiceSimboloCandidatoDaCostantiSquare = s12 + 1
  1393.             Case p13
  1394.                 IndiceSimboloCandidatoDaCostantiSquare = s13 + 1
  1395.             Case p14
  1396.                 IndiceSimboloCandidatoDaCostantiSquare = s14 + 1
  1397.             Case p15
  1398.                 IndiceSimboloCandidatoDaCostantiSquare = s15 + 1
  1399.             Case p16
  1400.                 IndiceSimboloCandidatoDaCostantiSquare = s16 + 1
  1401.             Case Else
  1402.                 IndiceSimboloCandidatoDaCostantiSquare = 0
  1403.         End Select
  1404.  
  1405.     End Function
  1406.  
  1407.     Public Sub InserisciSingoloCandidatoFisso_MT(ByVal IndiceCandidato As Integer, ByVal TipoTentativo As String, ByRef mds As Object)
  1408.  
  1409.         Dim I_Cella As Integer
  1410.         Dim I_Candidato As Integer
  1411.  
  1412.         I_Cella = CInt(mds.Cand(IndiceCandidato, 6))
  1413.         I_Candidato = CInt(mds.Cand(IndiceCandidato, 11))
  1414.         Call InserisciCandidatoFissoInSoluzioneFinale_MT(I_Cella, I_Candidato, mds)
  1415.  
  1416.         Call AggiornamentiPostInserimentoFisso_MT(IndiceCandidato, mds)
  1417.  
  1418.     End Sub
  1419.  
  1420.     Private Sub InserisciSingoloCandidatoFisso(ByVal IndiceCandidato As Integer, ByVal TipoTentativo As String)
  1421.  
  1422.         Dim I_Cella As Integer
  1423.         Dim I_Candidato As Integer
  1424.  
  1425.         I_Cella = CInt(dss.Cand(IndiceCandidato, 6))
  1426.         I_Candidato = CInt(dss.Cand(IndiceCandidato, 11))
  1427.         Call InserisciCandidatoFissoInSoluzioneFinale(I_Cella, I_Candidato)
  1428.         'Traccio il candidato inserito.
  1429.         'dss.Cand(IndiceCandidato, 0) += "-" & TipoTentativo & "-" & dss.Solution(0, 0)
  1430.         Call AggiornamentiPostInserimentoFisso(IndiceCandidato)
  1431.  
  1432.     End Sub
  1433.  
  1434.     Public Function InserisciCandidatiFissiMultipli_MT(ByVal CollectionAppoggio As Collection, ByRef mds As Object) As Boolean
  1435.         'ElementoCandidato_Collection
  1436.         Dim elemcand As Integer
  1437.  
  1438.         Dim I_Cella As Integer
  1439.         Dim I_Candidato As Integer
  1440.         Dim Elemento_Collection As String
  1441.         InserisciCandidatiFissiMultipli_MT = False
  1442.  
  1443.         For Each elemcand In CollectionAppoggio
  1444.  
  1445.             Elemento_Collection = mds.Cand(elemcand, 0)
  1446.  
  1447.             If VerificaCongruenzaInserimentoFisso_MT(elemcand, mds) = True Then
  1448.                 I_Cella = CInt(mds.Cand(elemcand, 6))
  1449.                 I_Candidato = CInt(mds.Cand(elemcand, 11))
  1450.                 Call InserisciCandidatoFissoInSoluzioneFinale_MT(I_Cella, I_Candidato, mds)
  1451.  
  1452.                 Call AggiornamentiPostInserimentoFisso_MT(elemcand, mds)
  1453.                 InserisciCandidatiFissiMultipli_MT = True
  1454.             Else
  1455.                 InserisciCandidatiFissiMultipli_MT = False
  1456.                 Exit For
  1457.             End If
  1458.  
  1459.             If mds.Solution(0, 0) = cToT Then
  1460.                 Exit For
  1461.             End If
  1462.  
  1463.         Next
  1464.  
  1465.         Return InserisciCandidatiFissiMultipli_MT
  1466.  
  1467.     End Function
  1468.  
  1469.     Private Function InserisciCandidatiFissiMultipli(ByVal CollectionAppoggio As Collection, Optional ByRef LstVincolo_ad1 As List(Of Int32) = Nothing) As Boolean
  1470.         'ElementoCandidato_Collection
  1471.         Dim ecand As Integer
  1472.  
  1473.         Dim I_Cella As Integer
  1474.         Dim I_Candidato As Integer
  1475.         Dim Elemento_Collection As String
  1476.         InserisciCandidatiFissiMultipli = False
  1477.  
  1478.         For Each ecand In CollectionAppoggio
  1479.             'CInt(ec) = Indice Candidato
  1480.             Elemento_Collection = dss.Cand(ecand, 0)
  1481.             'ec = dc(Elemento_Collection)
  1482.             If VerificaCongruenzaInserimentoFisso(ecand, 1, LstVincolo_ad1) = True Then
  1483.                 I_Cella = CInt(dss.Cand(ecand, 6))
  1484.                 I_Candidato = CInt(dss.Cand(ecand, 11))
  1485.                 Call InserisciCandidatoFissoInSoluzioneFinale(I_Cella, I_Candidato)
  1486.                 'Traccio il candidato inserito.
  1487.                 'dss.Cand(ecand, 0) += "-CM-" & dss.Solution(0, 0)
  1488.                 'log_Dancing_Links.AppendLine("| Inserito CM  " & dss.Cand(ecand, 0) & "        **********************     POSIZIONE DI INSERIMENTO: " & dss.Solution(0, 0))
  1489.                 Call AggiornamentiPostInserimentoFisso(ecand)
  1490.                 InserisciCandidatiFissiMultipli = True
  1491.             Else
  1492.                 InserisciCandidatiFissiMultipli = False
  1493.                 Exit For
  1494.             End If
  1495.         Next
  1496.  
  1497.         Return InserisciCandidatiFissiMultipli
  1498.  
  1499.     End Function
  1500.  
  1501.     Public Sequenza_index_vincoli As New List(Of String)
  1502.     Public ElencoVincolibloccanti As New Dictionary(Of String, Int32)
  1503.     Public Mischiate As Int32 = 0
  1504.  
  1505.     Private Function VerificaCongruenzaInserimentoFisso(ByVal IndiceCandidato As Integer, ByRef controllo As Byte, Optional ByRef Vincolo_rimasto_ad_1 As List(Of Int32) = Nothing) As Boolean
  1506.  
  1507.         'Dim Lst_Vinc As New List(Of Int32)
  1508.         Dim Conta As Integer
  1509.         Dim vincoloDiretto As String = ""
  1510.         Dim indicevincolodiretto As Int32
  1511.         Dim Candidato As String = ""
  1512.         VerificaCongruenzaInserimentoFisso = True
  1513.         Dim Targhet As Int32 = nBase / 2
  1514.         Dim Targhet2 As Int32
  1515.         'If Not Vincolo_rimasto_ad_1 Is Nothing Then
  1516.         'Lst_Vinc.AddRange(Vincolo_rimasto_ad_1)
  1517.         'End If
  1518.  
  1519.         'verifica i vincoli di cella, riga, colonna, box.
  1520.         For Conta = 2 To 5
  1521.  
  1522.             vincoloDiretto = dss.Cand(IndiceCandidato, Conta)
  1523.             indicevincolodiretto = dv(vincoloDiretto)
  1524.  
  1525.  
  1526.             If (CInt(dss.Vinc(indicevincolodiretto, 1))) < 1 Then
  1527.  
  1528.                 If Not VincoliBloccanti.ContainsKey(vincoloDiretto) Then
  1529.                     VincoliBloccanti.Add(vincoloDiretto, 1)
  1530.                 Else
  1531.                     VincoliBloccanti(vincoloDiretto) += 1
  1532.                 End If
  1533.  
  1534.                 Dim nc As Int32 = 0
  1535.                 For Each cand As String In dc.Keys
  1536.                     nc += 1
  1537.                     If nc = IndiceCandidato Then
  1538.                         Candidato = cand
  1539.                         Exit For
  1540.                     End If
  1541.                 Next
  1542.  
  1543.                 Dim ns As Int32 = 0
  1544.                 For Each strd In Lst_SAT
  1545.                     ns += 1
  1546.                     If controllo = 1 And strd.t_CVE = indicevincolodiretto Then
  1547.                         If VincoliBloccanti(vincoloDiretto) > Targhet Then
  1548.                             For i As Int32 = Lst_SAT.Count - 1 To ns Step -1
  1549.                                 'Lst_SAT.RemoveAt(i)
  1550.                             Next i
  1551.                             'scambia con elementi in coda.
  1552.                             'Call scambia_posizione_priorità_vincoli_lastindex(indicevincolodiretto, conta_swaps)
  1553.                             'scambia con elementi successivi.
  1554.                             'Call scambia_posizione_priorità_vincoli_nextindex(indicevincolodiretto, conta_swaps)
  1555.                             Dim vincolobloccante As String = vincoloDiretto & " che blocca il Candidato: " & Candidato & " "
  1556.                             If Not ElencoVincolibloccanti.Keys.Contains(vincolobloccante) Then
  1557.                                 ElencoVincolibloccanti.Add(vincolobloccante, 1)
  1558.                             Else
  1559.                                 ElencoVincolibloccanti(vincolobloccante) += 1
  1560.                             End If
  1561.                             conta_swaps += 1
  1562.                             Targhet2 = 5 'nBase
  1563.                             'If Lst_SAT.Count = 1 OrElse conta_swaps > Targhet2 Then
  1564.                             'If Lst_SAT.Count > 1 Then
  1565.                             'For i As Int32 = Lst_SAT.Count - 1 To 1 Step -1
  1566.                             'Lst_SAT.RemoveAt(i)
  1567.                             'Next i
  1568.                             'End If
  1569.                             'If Lst_SAT.Count > 0 Then Lst_SAT(0).t_IC = 2
  1570.                             'Call Mischia(M_PT, UBound(M_PT), nBase)
  1571.                             'Call QuickSortChiaviPerTentativi(M_PT, 1, (UBound(M_PT) / 2) + 1)
  1572.                             'Mischiate += 1
  1573.                             'If Lst_SAT.Count > 0 Then
  1574.                             'For i As Int32 = 1 To UBound(M_PT)
  1575.                             'If M_PT(i, 1) = Lst_SAT(0).t_CVE Then
  1576.                             'M_PT(i, 1) = 0
  1577.                             'M_PT(i, 2) = 0
  1578.                             'Exit For
  1579.                             'End If
  1580.                             'Next i
  1581.                             'End If
  1582.                             'conta_swaps = 0
  1583.                             'lista_vincoli_scambiati.Clear()
  1584.                             'End If
  1585.                             VincoliBloccanti.Clear()
  1586.                         End If
  1587.  
  1588.                         Exit For
  1589.  
  1590.                     End If
  1591.                     'dss.Cand(strd.t_UCR, 0) &= ""
  1592.                 Next strd
  1593.                 'dss.Cand(IndiceCandidato, 0) &= ""
  1594.  
  1595.                 'se un vincolo diretto è bloccante ritorna False.
  1596.                 VerificaCongruenzaInserimentoFisso = False
  1597.                 Return False
  1598.             End If
  1599.         Next
  1600.  
  1601.  
  1602.     End Function
  1603.  
  1604.     Public Function VerificaCongruenzaInserimentoFisso_MT(ByVal IndiceCandidato As Integer, ByRef mdati As Object) As Boolean
  1605.  
  1606.         Dim CongruenzaInserimentoFisso As Boolean = True
  1607.         Dim Conta As Integer
  1608.         Dim vincoloDiretto As String = ""
  1609.         Dim indicevincolodiretto As Int32
  1610.  
  1611.         'verifica i vincoli di cella, riga, colonna, box.
  1612.         For Conta = 2 To 5
  1613.  
  1614.             vincoloDiretto = mdati.Cand(IndiceCandidato, Conta)
  1615.             indicevincolodiretto = dv(vincoloDiretto)
  1616.  
  1617.  
  1618.             If (CInt(mdati.Vinc(indicevincolodiretto, 1))) < 1 Then
  1619.  
  1620.  
  1621.                 'se un vincolo diretto è bloccante ritorna False.
  1622.                 CongruenzaInserimentoFisso = False
  1623.                 Return CongruenzaInserimentoFisso
  1624.  
  1625.             End If
  1626.  
  1627.         Next Conta
  1628.  
  1629.  
  1630.         Return CongruenzaInserimentoFisso
  1631.     End Function
  1632.  
  1633.     Public conta_swaps As Int32 = 0
  1634.  
  1635.     Public Sub scambia_posizione_priorità_vincoli_lastindex(ByVal indicevincolodiretto As Int32, ByVal contatore_scambi As Int32)
  1636.         Dim indexelement As Int32 = (UBound(M_PT) - 1) - contatore_scambi
  1637.         Dim swap(2) As Int32
  1638.  
  1639.         swap(0) = M_PT(indexelement, 1)
  1640.  
  1641.         M_PT(indexelement, 1) = indicevincolodiretto
  1642.  
  1643.  
  1644.         swap(1) = M_PT(indexelement, 2)
  1645.  
  1646.         For i As Int32 = 1 To indexelement
  1647.  
  1648.             If M_PT(i, 1) = indicevincolodiretto Then
  1649.                 M_PT(indexelement, 2) = M_PT(i, 2)
  1650.                 M_PT(i, 1) = swap(0)
  1651.                 M_PT(i, 2) = swap(1)
  1652.                 Exit For
  1653.             End If
  1654.  
  1655.         Next i
  1656.  
  1657.         M_PT(0, 0) = UBound(M_PT)
  1658.  
  1659.     End Sub
  1660.  
  1661.     Public lista_vincoli_scambiati As New List(Of Int32)
  1662.  
  1663.     Public Sub scambia_posizione_priorità_vincoli_nextindex(ByVal indicevincolodiretto As Int32, ByVal contatore_scambi As Int32)
  1664.         Dim nextindex As Int32
  1665.         Dim nextelement1 As Int32
  1666.         Dim nextelement2 As Int32
  1667.         Dim newindex As Int32
  1668.         Dim lastelement As Int32 = UBound(M_PT)
  1669.         Dim swap(2) As Int32
  1670.  
  1671.         For indx As Int32 = 1 To lastelement
  1672.  
  1673.             If M_PT(indx, 1) = indicevincolodiretto Then
  1674.  
  1675.                 nextindex = indx + 1
  1676.                 Exit For
  1677.             End If
  1678.         Next
  1679.  
  1680.         For indx2 As Int32 = nextindex To lastelement Step +1
  1681.  
  1682.             If lista_vincoli_scambiati.Contains(M_PT(indx2, 1)) = True Then
  1683.                 Continue For
  1684.             Else
  1685.                 newindex = indx2
  1686.                 nextelement1 = M_PT(indx2, 1)
  1687.                 nextelement2 = M_PT(indx2, 2)
  1688.  
  1689.                 swap(0) = M_PT(nextindex - 1, 1)
  1690.                 swap(1) = M_PT(nextindex - 1, 2)
  1691.  
  1692.                 M_PT(nextindex - 1, 1) = M_PT(newindex, 1)
  1693.                 M_PT(nextindex - 1, 2) = M_PT(newindex, 2)
  1694.  
  1695.                 M_PT(newindex, 1) = swap(0)
  1696.                 M_PT(newindex, 2) = swap(1)
  1697.  
  1698.                 lista_vincoli_scambiati.Add(indicevincolodiretto)
  1699.                 Exit For
  1700.             End If
  1701.         Next
  1702.  
  1703.  
  1704.         M_PT(0, 0) = UBound(M_PT)
  1705.  
  1706.     End Sub
  1707.  
  1708.     Private Sub CaricaCandidatiFissiIniziali(ByVal Msudoku(,) As Int32)
  1709.  
  1710.         Dim CandidatoTest As Integer
  1711.         Dim Test As Integer
  1712.         Dim Conta As Integer = 0
  1713.         Dim nIniziali As Integer = 0
  1714.         Dim indxCand As Int32
  1715.         Dim KeyCand As String
  1716.         Dim c_App As New Collection
  1717.         'log_Dancing_Links.AppendLine("|     Log squenza Dancing-Links | | Candidati Fissi Iniziali | |")
  1718.  
  1719.         For r As Int32 = 1 To nBase
  1720.             For c As Int32 = 1 To nBase
  1721.                 Conta += 1
  1722.                 If Msudoku(r, c) <> 0 Then
  1723.  
  1724.                     'scansioniamo la matrice sudoku.
  1725.                     CandidatoTest = Msudoku(r, c)
  1726.  
  1727.                     Test = VerificaCandidatoAmmissibile(CandidatoTest)
  1728.                     If Test > 0 Then
  1729.                         nIniziali += 1
  1730.                         indxCand = Indice_in_MatriceCandidati_da_Cella_con_Candidato(Conta, Test)
  1731.                         KeyCand = dss.Cand(indxCand, 0)
  1732.                         c_App.Add(indxCand)
  1733.                         'log_Dancing_Links.AppendLine(nIniziali & ")  r-c: " & r & "-" & c & "  Cella-" & Conta & "   Segno:" & Test & "    KeyCand: " & KeyCand & "    IndxCand: " & indxCand & "|")
  1734.                     Else
  1735.                         MsgBox(" Errore In Fase Di Caricamento Schema Iniziale. ", MsgBoxStyle.Information)
  1736.                         Exit Sub
  1737.                     End If
  1738.  
  1739.                 End If
  1740.             Next c
  1741.         Next r
  1742.         If c_App.Count = 0 Then
  1743.             Multisoluzioni = True
  1744.             Exit Sub
  1745.         End If
  1746.  
  1747.         If InserisciCandidatiFissiMultipli(c_App) = False Then
  1748.             MsgBox(" Errore In Fase Di Caricamento Schema Iniziale. ", MsgBoxStyle.Information)
  1749.             Exit Sub
  1750.         End If
  1751.  
  1752.         c_App = Nothing
  1753.  
  1754.     End Sub
  1755.  
  1756.     Private Function VerificaCandidatoAmmissibile(ByVal ValoreCandidato As Int32) As Integer
  1757.  
  1758.         Select Case ValoreCandidato
  1759.             Case c1, CStr(c1)
  1760.                 VerificaCandidatoAmmissibile = s1
  1761.             Case c2, CStr(c2)
  1762.                 VerificaCandidatoAmmissibile = s2
  1763.             Case c3, CStr(c3)
  1764.                 VerificaCandidatoAmmissibile = s3
  1765.             Case c4, CStr(c4)
  1766.                 VerificaCandidatoAmmissibile = s4
  1767.             Case c5, CStr(c5)
  1768.                 VerificaCandidatoAmmissibile = s5
  1769.             Case c6, CStr(c6)
  1770.                 VerificaCandidatoAmmissibile = s6
  1771.             Case c7, CStr(c7)
  1772.                 VerificaCandidatoAmmissibile = s7
  1773.             Case c8, CStr(c8)
  1774.                 VerificaCandidatoAmmissibile = s8
  1775.             Case c9, CStr(c9)
  1776.                 VerificaCandidatoAmmissibile = s9
  1777.             Case c10, CStr(c10)
  1778.                 VerificaCandidatoAmmissibile = s10
  1779.             Case c11, CStr(c11)
  1780.                 VerificaCandidatoAmmissibile = s11
  1781.             Case c12, CStr(c12)
  1782.                 VerificaCandidatoAmmissibile = s12
  1783.             Case c13, CStr(c13)
  1784.                 VerificaCandidatoAmmissibile = s13
  1785.             Case c14, CStr(c14)
  1786.                 VerificaCandidatoAmmissibile = s14
  1787.             Case c15, CStr(c15)
  1788.                 VerificaCandidatoAmmissibile = s15
  1789.             Case c16, CStr(c16)
  1790.                 VerificaCandidatoAmmissibile = s16
  1791.             Case Else
  1792.                 VerificaCandidatoAmmissibile = 0
  1793.         End Select
  1794.  
  1795.     End Function
  1796.  
  1797.     Private Function Indice_in_MatriceCandidati_da_Cella_con_Candidato _
  1798.         (ByVal I_Cella As Integer, ByVal I_Candidato As Integer) As Int32
  1799.  
  1800.         Dim keycandidato As String
  1801.         Dim Idx_Candidato As Integer
  1802.  
  1803.         Idx_Candidato = (I_Cella - 1) * nBase + I_Candidato
  1804.  
  1805.         keycandidato = dss.Cand(Idx_Candidato, 0)
  1806.  
  1807.         Indice_in_MatriceCandidati_da_Cella_con_Candidato = Idx_Candidato
  1808.  
  1809.     End Function
  1810.  
  1811.     Public Sub InserisciCandidatoFissoInSoluzioneFinale_MT _
  1812.        (ByVal I_Cella As Integer, ByVal I_Candidato As Integer, ByRef mds As Object)
  1813.  
  1814.         Dim IndiceSoluzione As Integer
  1815.  
  1816.         IndiceSoluzione = mds.Solution(0, 0) + 1
  1817.  
  1818.         mds.Solution(0, 0) = IndiceSoluzione
  1819.         mds.Solution(IndiceSoluzione, 1) = I_Cella
  1820.         mds.Solution(IndiceSoluzione, 2) = I_Candidato
  1821.  
  1822.  
  1823.     End Sub
  1824.  
  1825.     Private Sub InserisciCandidatoFissoInSoluzioneFinale _
  1826.         (ByVal I_Cella As Integer, ByVal I_Candidato As Integer)
  1827.  
  1828.         Dim IndiceSoluzione As Integer
  1829.  
  1830.         IndiceSoluzione = dss.Solution(0, 0) + 1
  1831.         'If IndiceSoluzione < nBase * nBase Then
  1832.         dss.Solution(0, 0) = IndiceSoluzione
  1833.         dss.Solution(IndiceSoluzione, 1) = I_Cella
  1834.         dss.Solution(IndiceSoluzione, 2) = I_Candidato
  1835.         'End If
  1836.  
  1837.     End Sub
  1838.  
  1839.     Public Sub AggiornamentiPostInserimentoFisso_MT _
  1840.        (ByVal IndiceCandidatoInInserimento As Int32, ByRef mds As Object)
  1841.  
  1842.         Dim v_Cella As String
  1843.         Dim v_Riga As String
  1844.         Dim v_Colonna As String
  1845.         Dim v_Riquadro As String
  1846.         Dim MatriceVincoli(0 To 3) As Int32
  1847.         Dim ContaEst As Integer
  1848.         Dim ContaInt As Integer
  1849.         Dim IndiceCandidatoDaEliminare As Integer
  1850.  
  1851.  
  1852.         v_Cella = mds.Cand(IndiceCandidatoInInserimento, 2)
  1853.         v_Riga = mds.Cand(IndiceCandidatoInInserimento, 3)
  1854.         v_Colonna = mds.Cand(IndiceCandidatoInInserimento, 4)
  1855.         v_Riquadro = mds.Cand(IndiceCandidatoInInserimento, 5)
  1856.  
  1857.  
  1858.         MatriceVincoli(0) = dv(v_Cella)
  1859.         MatriceVincoli(1) = dv(v_Riga)
  1860.         MatriceVincoli(2) = dv(v_Colonna)
  1861.         MatriceVincoli(3) = dv(v_Riquadro)
  1862.  
  1863.         For ContaEst = 0 To 3
  1864.             Call EliminaVincoloEliminabile_MT(MatriceVincoli(ContaEst), IndiceCandidatoInInserimento, mds)
  1865.  
  1866.             For ContaInt = 2 To (nBase + 1)
  1867.  
  1868.                 IndiceCandidatoDaEliminare = dc(mds.Vinc(MatriceVincoli(ContaEst), ContaInt))
  1869.  
  1870.                 If (CInt(mds.Cand(IndiceCandidatoDaEliminare, 1))) = 1 Then
  1871.                     Call EliminaCandidatoEliminabile_MT(IndiceCandidatoDaEliminare, IndiceCandidatoInInserimento, mds)
  1872.  
  1873.                 End If
  1874.  
  1875.             Next
  1876.         Next
  1877.  
  1878.     End Sub
  1879.  
  1880.     Private Sub AggiornamentiPostInserimentoFisso _
  1881.         (ByVal IndiceCandidatoInInserimento As Int32)
  1882.  
  1883.         Dim v_Cella As String
  1884.         Dim v_Riga As String
  1885.         Dim v_Colonna As String
  1886.         Dim v_Riquadro As String
  1887.         Dim MatriceVincoli(0 To 3) As Int32
  1888.         Dim ContaEst As Integer
  1889.         Dim ContaInt As Integer
  1890.         Dim IndiceCandidatoDaEliminare As Integer
  1891.  
  1892.  
  1893.         v_Cella = dss.Cand(IndiceCandidatoInInserimento, 2)
  1894.         v_Riga = dss.Cand(IndiceCandidatoInInserimento, 3)
  1895.         v_Colonna = dss.Cand(IndiceCandidatoInInserimento, 4)
  1896.         v_Riquadro = dss.Cand(IndiceCandidatoInInserimento, 5)
  1897.  
  1898.  
  1899.         MatriceVincoli(0) = dv(v_Cella)
  1900.         MatriceVincoli(1) = dv(v_Riga)
  1901.         MatriceVincoli(2) = dv(v_Colonna)
  1902.         MatriceVincoli(3) = dv(v_Riquadro)
  1903.  
  1904.         For ContaEst = 0 To 3
  1905.             Call EliminaVincoloEliminabile(MatriceVincoli(ContaEst), IndiceCandidatoInInserimento)
  1906.             'log_Dancing_Links.AppendLine("| VincoloDirettoAzzerato: " & dss.Vinc(MatriceVincoli(ContaEst), 0) & "|")
  1907.             For ContaInt = 2 To (nBase + 1)
  1908.  
  1909.                 IndiceCandidatoDaEliminare = dc(dss.Vinc(MatriceVincoli(ContaEst), ContaInt))
  1910.  
  1911.                 If (CInt(dss.Cand(IndiceCandidatoDaEliminare, 1))) = 1 Then
  1912.                     Call EliminaCandidatoEliminabile(IndiceCandidatoDaEliminare, IndiceCandidatoInInserimento)
  1913.                     'log_Dancing_Links.AppendLine("| *******************  Candidato-da-Vincolo-Diretto-Azzerato: " & dss.Vinc(MatriceVincoli(ContaEst), ContaInt) & "|")
  1914.                 End If
  1915.  
  1916.             Next
  1917.         Next
  1918.  
  1919.     End Sub
  1920.  
  1921.     Public Sub EliminaCandidatoEliminabile_MT(ByVal IndiceCandidatoDE As Int32, ByVal IndiceCandININS As Int32, ByRef mds As Object)
  1922.         If IndiceCandidatoDE = IndiceCandININS Then
  1923.             mds.Cand(IndiceCandidatoDE, 1) = -nBase
  1924.             mds.Cand(0, 0) = (CInt(mds.Cand(0, 0)) - 1).ToString
  1925.             Call AggiornaArraySubElementiVincoli_MT(IndiceCandININS, IndiceCandININS, mds)
  1926.         Else
  1927.             mds.Cand(IndiceCandidatoDE, 1) = 0
  1928.  
  1929.             mds.Cand(0, 0) = (CInt(mds.Cand(0, 0)) - 1).ToString
  1930.             Call AggiornaArraySubElementiVincoli_MT(IndiceCandidatoDE, IndiceCandININS, mds)
  1931.         End If
  1932.     End Sub
  1933.  
  1934.     Private Sub EliminaCandidatoEliminabile(ByVal IndiceCandidatoDE As Int32, ByVal IndiceCandININS As Int32)
  1935.         If IndiceCandidatoDE = IndiceCandININS Then
  1936.             dss.Cand(IndiceCandidatoDE, 1) = -nBase
  1937.             dss.Cand(0, 0) = (CInt(dss.Cand(0, 0)) - 1).ToString
  1938.             Call AggiornaArraySubElementiVincoli(IndiceCandININS, IndiceCandININS)
  1939.         Else
  1940.             dss.Cand(IndiceCandidatoDE, 1) = 0
  1941.             'dss.Cand(IndiceCandidatoDE, 0) &= " **##** " & dss.Cand(IndiceCandININS, 0)
  1942.             dss.Cand(0, 0) = (CInt(dss.Cand(0, 0)) - 1).ToString
  1943.             Call AggiornaArraySubElementiVincoli(IndiceCandidatoDE, IndiceCandININS)
  1944.         End If
  1945.     End Sub
  1946.  
  1947.     Public Sub AggiornaArraySubElementiVincoli_MT(ByVal IndiceCandidatoDE As Int32, ByVal IndiceCandININS As Int32, ByRef mds As Object)
  1948.  
  1949.         Dim Conta As Integer
  1950.         Dim squareX As Int32
  1951.         Dim square As Int32
  1952.         Dim npsquare As Int32
  1953.  
  1954.         If nBase = 16 Then
  1955.  
  1956.             For Conta = 2 To 5
  1957.  
  1958.                 mds.Vinc(dv(mds.Cand(IndiceCandidatoDE, Conta)), 1) = _
  1959.                     CInt(mds.Vinc(dv(mds.Cand(IndiceCandidatoDE, Conta)), 1)) - 1
  1960.                 'si decrementa il valore
  1961.                 square = M_Square16(CInt(mds.Cand(IndiceCandidatoDE, Conta + 5)))
  1962.                 npsquare = IndiceSimboloCandidatoDaCostantiSquare(square)
  1963.                 If PrimoTentativoInCorso = True Then
  1964.                     Matrice_Candidati_Eliminati(dv(dss.Cand(IndiceCandidatoDE, Conta)), npsquare) = 0 ' "Eliminato"
  1965.                 End If
  1966.                 squareX = CInt(mds.Vinc(dv(mds.Cand(IndiceCandidatoDE, Conta)), 18))
  1967.                 mds.Vinc(dv(mds.Cand(IndiceCandidatoDE, Conta)), 18) = (squareX - square).ToString
  1968.             Next Conta
  1969.         End If
  1970.  
  1971.  
  1972.     End Sub
  1973.  
  1974.     Private Sub AggiornaArraySubElementiVincoli(ByVal IndiceCandidatoDE As Int32, ByVal IndiceCandININS As Int32)
  1975.  
  1976.         Dim Conta As Integer
  1977.         Dim squareX As Int32
  1978.         Dim square As Int32
  1979.         Dim npsquare As Int32
  1980.  
  1981.         If nBase = 9 Then
  1982.             For Conta = 2 To 5
  1983.  
  1984.                 dss.Vinc(dv(dss.Cand(IndiceCandidatoDE, Conta)), 1) = _
  1985.                     CInt(dss.Vinc(dv(dss.Cand(IndiceCandidatoDE, Conta)), 1)) - 1
  1986.                 'si decrementa il valore
  1987.                 square = M_Square9(CInt(dss.Cand(IndiceCandidatoDE, Conta + 5)))
  1988.                 npsquare = IndiceSimboloCandidatoDaCostantiSquare(square)
  1989.                 If PrimoTentativoInCorso = True Then
  1990.                     Matrice_Candidati_Eliminati(dv(dss.Cand(IndiceCandidatoDE, Conta)), npsquare) = 0 ' "Eliminato"
  1991.                 End If
  1992.                 squareX = CInt(dss.Vinc(dv(dss.Cand(IndiceCandidatoDE, Conta)), 11))
  1993.                 dss.Vinc(dv(dss.Cand(IndiceCandidatoDE, Conta)), 11) = (squareX - square).ToString
  1994.                 'dss.Vinc(dv(dss.Cand(IndiceCandidatoDE, Conta)), 0) &= "| " & square & "-" & dss.Cand(IndiceCandidatoDE, 0) & " Null " & dss.Cand(IndiceCandININS, 0)
  1995.                 'log_Dancing_Links.AppendLine("| AggSubCanVinc: " & dss.Vinc(dv(dss.Cand(IndiceCandidatoDE, Conta)), 0) & " ElimSquare: " & square & " =CV: " & dss.Vinc(dv(dss.Cand(IndiceCandidatoDE, Conta)), npsquare))
  1996.             Next Conta
  1997.  
  1998.         Else
  1999.             For Conta = 2 To 5
  2000.  
  2001.                 dss.Vinc(dv(dss.Cand(IndiceCandidatoDE, Conta)), 1) = _
  2002.                     CInt(dss.Vinc(dv(dss.Cand(IndiceCandidatoDE, Conta)), 1)) - 1
  2003.                 'si decrementa il valore
  2004.                 square = M_Square16(CInt(dss.Cand(IndiceCandidatoDE, Conta + 5)))
  2005.                 npsquare = IndiceSimboloCandidatoDaCostantiSquare(square)
  2006.                 If PrimoTentativoInCorso = True Then
  2007.                     Matrice_Candidati_Eliminati(dv(dss.Cand(IndiceCandidatoDE, Conta)), npsquare) = 0 ' "Eliminato"
  2008.                 End If
  2009.                 squareX = CInt(dss.Vinc(dv(dss.Cand(IndiceCandidatoDE, Conta)), 18))
  2010.                 dss.Vinc(dv(dss.Cand(IndiceCandidatoDE, Conta)), 18) = (squareX - square).ToString
  2011.             Next Conta
  2012.         End If
  2013.  
  2014.  
  2015.     End Sub
  2016.  
  2017.     Public Sub EliminaVincoloEliminabile_MT(ByVal IndiceVincolo As Int32, ByVal IndiceCandININS As Int32, ByRef mds As Object)
  2018.  
  2019.         mds.Vinc(IndiceVincolo, 1) = -10
  2020.         mds.Vinc(0, 0) = (CInt(mds.Vinc(0, 0)) - 1).ToString
  2021.  
  2022.     End Sub
  2023.  
  2024.     Private Sub EliminaVincoloEliminabile(ByVal IndiceVincolo As Int32, ByVal IndiceCandININS As Int32)
  2025.  
  2026.         dss.Vinc(IndiceVincolo, 1) = -10
  2027.         dss.Vinc(0, 0) = (CInt(dss.Vinc(0, 0)) - 1).ToString
  2028.         'dss.Vinc(IndiceVincolo, 0) &= "|{CH-" & IndiceCandININS & "}"
  2029.     End Sub
  2030.  
  2031.  
  2032. #End Region
  2033.  
  2034. #Region "Funzioni_e_Procedure_generali"
  2035.  
  2036.     Public Function RitornaSoluzione(ByRef Msku(,) As Int32) As Int32(,)
  2037.  
  2038.         Dim ContaCella As Integer = 0
  2039.         Dim contatore As Integer
  2040.         Dim contaM As Int32 = UBound(dss.Solution) 'M_SAT.Length - 1
  2041.         If contaM = 0 Then
  2042.             MsgBox(" Sudoku errato o irrisolvibile. ", MsgBoxStyle.Information)
  2043.         Else
  2044.             For contatore = 1 To contaM
  2045.                 ContaCella = 0
  2046.                 'carichiamo la soluzione in una matrice
  2047.                 For r As Int32 = 1 To nBase
  2048.                     For c As Int32 = 1 To nBase     'CInt(M_SAT(contaM).Solution(contatore, 1))
  2049.                         ContaCella += 1
  2050.                         If ContaCella = CInt(dss.Solution(contatore, 1)) Then
  2051.                             Msku(r, c) = CandidatoDaCostantiIndiceCandidato(CInt(dss.Solution(contatore, 2)))
  2052.                         End If
  2053.                     Next c
  2054.                 Next r
  2055.             Next contatore
  2056.         End If
  2057.  
  2058.         'restituiamo la matrice con la soluzione
  2059.         RitornaSoluzione = Msku.Clone
  2060.     End Function
  2061.  
  2062.     Private Sub CaricaCandidatiNumericiSudoku()
  2063.         c1 = 1 : c2 = 2 : c3 = 3 : c4 = 4 : c5 = 5 : c6 = 6 : c7 = 7 : c8 = 8 : c9 = 9
  2064.         c10 = 10 : c11 = 11 : c12 = 12 : c13 = 13 : c14 = 14 : c15 = 15 : c16 = 16
  2065.     End Sub
  2066.  
  2067.     Private Function CandidatoDaCostantiIndiceCandidato(ByVal CostanteIndice As Integer) As Int32
  2068.  
  2069.         Select Case CostanteIndice
  2070.             Case s1
  2071.                 CandidatoDaCostantiIndiceCandidato = c1
  2072.             Case s2
  2073.                 CandidatoDaCostantiIndiceCandidato = c2
  2074.             Case s3
  2075.                 CandidatoDaCostantiIndiceCandidato = c3
  2076.             Case s4
  2077.                 CandidatoDaCostantiIndiceCandidato = c4
  2078.             Case s5
  2079.                 CandidatoDaCostantiIndiceCandidato = c5
  2080.             Case s6
  2081.                 CandidatoDaCostantiIndiceCandidato = c6
  2082.             Case s7
  2083.                 CandidatoDaCostantiIndiceCandidato = c7
  2084.             Case s8
  2085.                 CandidatoDaCostantiIndiceCandidato = c8
  2086.             Case s9
  2087.                 CandidatoDaCostantiIndiceCandidato = c9
  2088.             Case s10
  2089.                 CandidatoDaCostantiIndiceCandidato = c10
  2090.             Case s11
  2091.                 CandidatoDaCostantiIndiceCandidato = c11
  2092.             Case s12
  2093.                 CandidatoDaCostantiIndiceCandidato = c12
  2094.             Case s13
  2095.                 CandidatoDaCostantiIndiceCandidato = c13
  2096.             Case s14
  2097.                 CandidatoDaCostantiIndiceCandidato = c14
  2098.             Case s15
  2099.                 CandidatoDaCostantiIndiceCandidato = c15
  2100.             Case s16
  2101.                 CandidatoDaCostantiIndiceCandidato = c16
  2102.             Case Else
  2103.                 CandidatoDaCostantiIndiceCandidato = 0
  2104.         End Select
  2105.  
  2106.     End Function
  2107.  
  2108.     Private Sub CaricaMatriceCandidatiPresceltiConSquare()
  2109.  
  2110.         M_Cand9(1) = c1 : M_Cand9(2) = c2 : M_Cand9(3) = c3
  2111.         M_Cand9(4) = c4 : M_Cand9(5) = c5 : M_Cand9(6) = c6
  2112.         M_Cand9(7) = c7 : M_Cand9(8) = c8 : M_Cand9(9) = c9
  2113.  
  2114.         M_Simb9(1) = s1 : M_Simb9(2) = s2 : M_Simb9(3) = s3
  2115.         M_Simb9(4) = s4 : M_Simb9(5) = s5 : M_Simb9(6) = s6
  2116.         M_Simb9(7) = s7 : M_Simb9(8) = s8 : M_Simb9(9) = s9
  2117.  
  2118.         M_Square9(1) = p1 : M_Square9(2) = p2 : M_Square9(3) = p3
  2119.         M_Square9(4) = p4 : M_Square9(5) = p5 : M_Square9(6) = p6
  2120.         M_Square9(7) = p7 : M_Square9(8) = p8 : M_Square9(9) = p9
  2121.  
  2122.         M_Cand16(1) = c1 : M_Cand16(2) = c2 : M_Cand16(3) = c3
  2123.         M_Cand16(4) = c4 : M_Cand16(5) = c5 : M_Cand16(6) = c6
  2124.         M_Cand16(7) = c7 : M_Cand16(8) = c8 : M_Cand16(9) = c9
  2125.         M_Cand16(10) = c10 : M_Cand16(11) = c11 : M_Cand16(12) = c12
  2126.         M_Cand16(13) = c13 : M_Cand16(14) = c14 : M_Cand16(15) = c15 : M_Cand16(16) = c16
  2127.  
  2128.         M_Simb16(1) = s1 : M_Simb16(2) = s2 : M_Simb16(3) = s3
  2129.         M_Simb16(4) = s4 : M_Simb16(5) = s5 : M_Simb16(6) = s6
  2130.         M_Simb16(7) = s7 : M_Simb16(8) = s8 : M_Simb16(9) = s9
  2131.         M_Simb16(10) = s10 : M_Simb16(11) = s11 : M_Simb16(12) = s12
  2132.         M_Simb16(13) = s13 : M_Simb16(14) = s14 : M_Simb16(15) = s15 : M_Simb16(16) = s16
  2133.  
  2134.         M_Square16(1) = p1 : M_Square16(2) = p2 : M_Square16(3) = p3
  2135.         M_Square16(4) = p4 : M_Square16(5) = p5 : M_Square16(6) = p6
  2136.         M_Square16(7) = p7 : M_Square16(8) = p8 : M_Square16(9) = p9
  2137.         M_Square16(10) = p10 : M_Square16(11) = p11 : M_Square16(12) = p12
  2138.         M_Square16(13) = p13 : M_Square16(14) = p14 : M_Square16(15) = p15 : M_Square16(16) = p16
  2139.  
  2140.     End Sub
  2141.  
  2142.     Private Sub CaricaMatriceDatiSchemaSudoku()
  2143.  
  2144.         'matrice chiavi candidati
  2145.         Call carica_matrice_chiavi_Candidati()
  2146.         dss.Cand(0, 0) = nBase * cToT
  2147.         'matrice chiavi vincoli
  2148.         Call carica_matrice_chiavi_Vincoli()
  2149.         dss.Vinc(0, 0) = cToT * 4
  2150.         'matrice soluzione
  2151.         dss.Solution(0, 0) = 0
  2152.  
  2153.         dss.t_CVE = 0
  2154.         dss.t_IC = 0
  2155.         dss.t_UCR = 0
  2156.  
  2157.     End Sub
  2158.  
  2159.     Private Sub Controllo_correttezza_Matrici()
  2160.         Dim flagok As Boolean = True
  2161.         Dim cand As String = ""
  2162.         Dim vinc As String = ""
  2163.         Dim indVinc As Int32 = 0
  2164.         Dim indiceCand_in_Vinc As Int32 = 0
  2165.         Dim square As Int32 = 0
  2166.         Dim pvds As Int32
  2167.  
  2168.         For i As Int32 = 1 To cToT * nBase
  2169.             cand = dss.Cand(i, 0)
  2170.             For j As Int32 = 2 To 5
  2171.                 vinc = dss.Cand(i, j)
  2172.                 indVinc = dv(vinc)
  2173.                 indiceCand_in_Vinc = CInt(dss.Cand(i, j + 5))
  2174.                 If nBase = 9 Then
  2175.                     square = M_Square9(indiceCand_in_Vinc)
  2176.                 Else
  2177.                     square = M_Square16(indiceCand_in_Vinc)
  2178.                 End If
  2179.                 pvds = IndiceSimboloCandidatoDaCostantiSquare(square)
  2180.                 If Not cand = dss.Vinc(dv(vinc), pvds) Then
  2181.                     flagok = False
  2182.                 End If
  2183.                 If Not vinc = dss.Vinc(indVinc, 0) Then
  2184.                     flagok = False
  2185.                 End If
  2186.             Next j
  2187.         Next i
  2188.  
  2189.     End Sub
  2190.  
  2191.     Private Sub carica_matrice_chiavi_Candidati()
  2192.         Dim conta_nbase As Int32 = 0
  2193.         Dim conta_nTot As Int32 = 0
  2194.         Dim avanzacella As Int32 = 1
  2195.         Dim contarighe As Int32 = 1
  2196.         Dim contacolonne As Int32 = 1
  2197.         Dim contabox As Int32 = 1
  2198.         Dim base9 As Int32 = 3
  2199.         Dim base16 As Int32 = 4
  2200.         Dim baseX As Int32
  2201.         Dim nCand As Int32 = 0
  2202.         If nBase = 9 Then
  2203.             baseX = base9
  2204.         Else
  2205.             baseX = base16
  2206.         End If
  2207.  
  2208.         For Each cc As String In dc.Keys
  2209.             conta_nbase += 1
  2210.             conta_nTot += 1
  2211.             nCand += 1
  2212.             For i As Int32 = 0 To 11
  2213.                 Select Case i
  2214.                     Case 0
  2215.                         'Chiave candidato
  2216.                         dss.Cand(dc(cc), i) = cc 'dc(cc) & "]-" & cc
  2217.                     Case 1
  2218.                         ' Chiave candidato non ancora eliminato di Valore = "1"
  2219.                         dss.Cand(dc(cc), i) = 1
  2220.                     Case 2
  2221.                         'Costante indice chiave vincolo di cella
  2222.                         dss.Cand(dc(cc), i) = "cella_" & avanzacella
  2223.                     Case 3
  2224.                         'Costante indice chiave vincolo di riga        
  2225.                         dss.Cand(dc(cc), i) = "row" & contarighe & "_s" & conta_nbase
  2226.                     Case 4
  2227.                         'Costante indice chiave vincolo di colonna
  2228.                         dss.Cand(dc(cc), i) = "col" & contacolonne & "_s" & conta_nbase
  2229.                     Case 5
  2230.                         contabox = RitornaQuadranteBox(contarighe, contacolonne, nBase)(4)
  2231.                         'Costante indice chiave vincolo di riquadro
  2232.                         dss.Cand(dc(cc), i) = "box" & contabox & "_s" & conta_nbase
  2233.                     Case 6
  2234.                         'Numero indice di cella
  2235.                         dss.Cand(dc(cc), i) = avanzacella
  2236.                     Case 7
  2237.                         'Indice candidato(numero o simbolo) in vincolo di cella
  2238.                         dss.Cand(dc(cc), i) = conta_nbase
  2239.                     Case 8
  2240.                         'Indice candidato in vincolo di colonna
  2241.                         dss.Cand(dc(cc), i) = contacolonne
  2242.                     Case 9
  2243.                         'Indice candidato in vincolo di riga
  2244.                         dss.Cand(dc(cc), i) = contarighe
  2245.                     Case 10
  2246.                         'Indice candidato in vincolo di riquadro
  2247.                         dss.Cand(dc(cc), i) = Ritornaindicebox(baseX, nCand).ToString
  2248.                     Case 11
  2249.                         'Costante indice simbolo chiave candidato
  2250.                         If nBase = 9 Then
  2251.                             dss.Cand(dc(cc), i) = M_Simb9(conta_nbase)
  2252.                         Else
  2253.                             dss.Cand(dc(cc), i) = M_Simb16(conta_nbase)
  2254.                         End If
  2255.  
  2256.                 End Select
  2257.  
  2258.             Next i
  2259.             If conta_nbase = nBase Then
  2260.                 conta_nbase = 0
  2261.                 avanzacella += 1
  2262.                 contacolonne += 1
  2263.             End If
  2264.             If contacolonne > nBase Then
  2265.                 contacolonne = 1
  2266.             End If
  2267.             If conta_nTot = cToT Then
  2268.                 conta_nTot = 0
  2269.                 If contarighe < nBase Then contarighe += 1
  2270.             End If
  2271.         Next cc
  2272.  
  2273.     End Sub
  2274.  
  2275.     Friend Function Ritornaindicebox(ByVal baseX As Int32, ByVal ncount As Int32) As Int32
  2276.  
  2277.         Dim nsudoku As Int32 = baseX * baseX
  2278.         Dim nsom As Int32 = 0
  2279.         Dim conta As Int32 = 1
  2280.         Dim steps As Int32 = 2
  2281.         Dim contastep As Int32 = 0
  2282.         Dim value As Int32 = 0
  2283.  
  2284.         While conta <= ncount
  2285.  
  2286.             For i As Int32 = 1 To baseX
  2287.  
  2288.                 For j As Int32 = 1 To nsudoku
  2289.  
  2290.                     value = nsom + i
  2291.                     If conta = ncount Then
  2292.                         If value > nsudoku Then
  2293.                             Exit For
  2294.                         End If
  2295.                         Return value
  2296.                     End If
  2297.                     conta += 1
  2298.                 Next j
  2299.  
  2300.             Next i
  2301.             contastep += 1
  2302.  
  2303.             If nsom = (nsudoku - baseX) And contastep = baseX Then
  2304.                 nsom = 0
  2305.                 contastep = 0
  2306.             End If
  2307.             If contastep = baseX Then
  2308.                 contastep = 0
  2309.                 nsom += baseX
  2310.             End If
  2311.         End While
  2312.  
  2313.         Return value
  2314.  
  2315.     End Function
  2316.  
  2317.     Public Function RitornaQuadranteBox(ByVal r As Int32, ByVal c As Int32, ByVal bs As Int32) As Int32()
  2318.         Dim ValoriQ As Int32() = {1, 2, 3, 4, 5}
  2319.         'valore base.
  2320.         Dim vb As Int32 = Math.Sqrt(bs)
  2321.         'ricerca coordinate riquadro.
  2322.         Dim ax As Int32
  2323.         Dim ay As Int32
  2324.         Dim bx As Int32
  2325.         Dim by As Int32
  2326.         For a As Int32 = r To bs
  2327.             If a Mod vb = 0 Then
  2328.                 ay = a
  2329.                 Exit For
  2330.             End If
  2331.         Next a
  2332.         ax = (ay - vb) + 1
  2333.         For b As Int32 = c To bs
  2334.             If b Mod vb = 0 Then
  2335.                 by = b
  2336.                 Exit For
  2337.             End If
  2338.         Next b
  2339.         bx = (by - vb) + 1
  2340.         Dim Qp1 As Int32 = CInt(((by - 1) / vb))
  2341.         Dim Qp2 As Int32 = CInt((((ay - 1) / vb) * vb))
  2342.         Dim Q As Int32 = CInt(Qp1 + Qp2 + 1) - vb
  2343.         ValoriQ(0) = ax
  2344.         ValoriQ(1) = ay
  2345.         ValoriQ(2) = bx
  2346.         ValoriQ(3) = by
  2347.         ValoriQ(4) = Q
  2348.  
  2349.         Return ValoriQ
  2350.  
  2351.     End Function
  2352.  
  2353.     Private Sub carica_matrice_chiavi_Vincoli()
  2354.         Dim conta As Int32 = 1
  2355.         For Each cv As String In dv.Keys
  2356.             ' Chiave Vincolo
  2357.             dss.Vinc(dv(cv), 0) = cv 'conta & "]-" & cv
  2358.             ' Chiave Vincolo in esame  di Valore iniziale= "nBase"
  2359.             dss.Vinc(dv(cv), 1) = nBase
  2360.             conta += 1
  2361.         Next cv
  2362.         conta = 1
  2363.         Dim vincolo As String
  2364.         'carica subvincoli da vincoli cella
  2365.         For i As Int32 = 1 To cToT
  2366.             conta = 1
  2367.             vincolo = dv.Keys(i - 1)
  2368.             For j As Int32 = 1 To cToT * nBase
  2369.                 If vincolo = dss.Cand(j, 2) Then
  2370.                     conta += 1
  2371.                     dss.Vinc(i, conta) = dc.Keys(j - 1)
  2372.                 End If
  2373.                 If conta = nBase + 1 Then
  2374.                     conta = 1
  2375.                     Exit For
  2376.                 End If
  2377.             Next j
  2378.             If Not conta = 1 Then
  2379.                 'Exit Sub
  2380.             End If
  2381.         Next i
  2382.         'carica subvincoli da vincoli riga
  2383.         For i As Int32 = (cToT + 1) To cToT * 2
  2384.             conta = 1
  2385.             vincolo = dv.Keys(i - 1)
  2386.             For j As Int32 = 1 To cToT * nBase
  2387.                 If vincolo = dss.Cand(j, 3) Then
  2388.                     conta += 1
  2389.                     dss.Vinc(i, conta) = dc.Keys(j - 1)
  2390.                 End If
  2391.                 If conta = nBase + 1 Then
  2392.                     conta = 1
  2393.                     Exit For
  2394.                 End If
  2395.             Next j
  2396.             If Not conta = 1 Then
  2397.                 'Exit Sub
  2398.             End If
  2399.         Next i
  2400.         'carica subvincoli da vincoli colonna
  2401.         For i As Int32 = (cToT * 2 + 1) To cToT * 3
  2402.             conta = 1
  2403.             vincolo = dv.Keys(i - 1)
  2404.             For j As Int32 = 1 To cToT * nBase
  2405.                 If vincolo = dss.Cand(j, 4) Then
  2406.                     conta += 1
  2407.                     dss.Vinc(i, conta) = dc.Keys(j - 1)
  2408.                 End If
  2409.                 If conta = nBase + 1 Then
  2410.                     conta = 1
  2411.                     Exit For
  2412.                 End If
  2413.             Next j
  2414.             If Not conta = 1 Then
  2415.                 'Exit Sub
  2416.             End If
  2417.         Next i
  2418.         'carica subvincoli da vincoli riquadro box
  2419.         For i As Int32 = (cToT * 3 + 1) To cToT * 4
  2420.             conta = 1
  2421.             vincolo = dv.Keys(i - 1)
  2422.             For j As Int32 = 1 To cToT * nBase
  2423.                 If vincolo = dss.Cand(j, 5) Then
  2424.                     conta += 1
  2425.                     dss.Vinc(i, conta) = dc.Keys(j - 1)
  2426.                 End If
  2427.                 If conta = nBase + 1 Then
  2428.                     conta = 1
  2429.                     Exit For
  2430.                 End If
  2431.             Next j
  2432.             If Not conta = 1 Then
  2433.                 'Exit Sub
  2434.             End If
  2435.         Next i
  2436.         'carica le potenze di 2 in ultima colonna matrice
  2437.         For i As Int32 = 1 To cToT * 4
  2438.             If nBase = 9 Then
  2439.                 dss.Vinc(i, 11) = SSq9
  2440.             Else
  2441.                 dss.Vinc(i, 18) = SSq16
  2442.             End If
  2443.         Next i
  2444.  
  2445.         'Inizzializza la Matrice dei Candidati Eliminati prima dei Tentativi.
  2446.         For i As Int32 = 1 To cToT * 4
  2447.             Matrice_Candidati_Eliminati(i, 1) = i
  2448.             For j As Int32 = 2 To nBase + 1
  2449.                 Matrice_Candidati_Eliminati(i, j) = j
  2450.             Next j
  2451.         Next i
  2452.  
  2453.         'Call Mostra_Log_Matrici()
  2454.  
  2455.     End Sub
  2456.  
  2457.     Public Function Mostra_Log_Matrici(ByRef nLog As Int32) As String()
  2458.  
  2459.  
  2460.         Dim riga As String = ""
  2461.  
  2462.  
  2463.         log_sequenza_Matrici.AppendLine(" Esposizione Matrice Candidati-vincolo |")
  2464.  
  2465.         For i As Int32 = 0 To cToT * nBase
  2466.             For j As Int32 = 0 To 11
  2467.  
  2468.                 Select Case j
  2469.                     Case 5
  2470.                         riga += (dss.Cand(i, j) + "   nCell:")
  2471.                     Case 6
  2472.                         riga += (dss.Cand(i, j) + "      nS:")
  2473.                     Case 7
  2474.                         riga += (dss.Cand(i, j) + "     col:")
  2475.                     Case 8
  2476.                         riga += (dss.Cand(i, j) + "     row:")
  2477.                     Case 9
  2478.                         riga += (dss.Cand(i, j) + "     Box:")
  2479.                     Case Else
  2480.                         riga += (dss.Cand(i, j) + "       ")
  2481.                 End Select
  2482.             Next j
  2483.             riga += "|"
  2484.             log_sequenza_Matrici.AppendLine(riga)
  2485.             riga = ""
  2486.         Next i
  2487.  
  2488.         log_sequenza_Matrici.AppendLine("  Esposizione Matrice Vincoli  |")
  2489.  
  2490.         For i As Int32 = 0 To cToT * 4
  2491.             For j As Int32 = 0 To nBase + 2
  2492.                 riga += (dss.Vinc(i, j) + "    ")
  2493.             Next j
  2494.             riga += "|"
  2495.             log_sequenza_Matrici.AppendLine(riga)
  2496.             riga = ""
  2497.         Next i
  2498.         log_sequenza_Matrici.AppendLine("***************     Fine Log by Tebaldo Ulleri. *********************|")
  2499.         log_sequenza_Matrici.AppendLine(";-)|")
  2500.  
  2501.         Dim Log() As String = Nothing
  2502.         If nLog = 1 Then
  2503.             Log = log_sequenza_Matrici.ToString.Split("|")
  2504.         ElseIf nLog = 2 Then
  2505.             Log = log_Dancing_Links.ToString.Split("|")
  2506.         End If
  2507.  
  2508.         Return Log
  2509.     End Function
  2510.  
  2511.     Const CostanteLimitativa = -2
  2512.  
  2513.     Public Sub QuickSortChiaviPerTentativi(ByRef MatriceDaOrdinare(,) As Int32, _
  2514.      Optional ByVal LimiteInf As Integer = CostanteLimitativa, _
  2515.      Optional ByVal LimiteSup As Integer = CostanteLimitativa)
  2516.  
  2517.         Dim Inf As Integer
  2518.         Dim Sup As Integer
  2519.         Dim ValoreTest As Object
  2520.         Dim PuntoMedioMatrice As Integer
  2521.  
  2522.         If LimiteInf = CostanteLimitativa Then LimiteInf = LBound(MatriceDaOrdinare) + 1
  2523.         If LimiteSup = CostanteLimitativa Then LimiteSup = UBound(MatriceDaOrdinare)
  2524.  
  2525.         If LimiteInf < LimiteSup Then
  2526.             PuntoMedioMatrice = (LimiteInf + LimiteSup) \ 2
  2527.             ValoreTest = MatriceDaOrdinare(PuntoMedioMatrice, 2) 'MatriceDaOrdinare(PuntoMedioMatrice)(1)
  2528.             Inf = LimiteInf
  2529.             Sup = LimiteSup
  2530.             Do
  2531.                 Do While MatriceDaOrdinare(Inf, 2) < ValoreTest   'MatriceDaOrdinare(Inf)(1)
  2532.                     Inf = Inf + 1
  2533.                 Loop
  2534.                 Do While MatriceDaOrdinare(Sup, 2) > ValoreTest   'MatriceDaOrdinare(Sup)(1)
  2535.                     Sup = Sup - 1
  2536.                 Loop
  2537.                 If Inf <= Sup Then
  2538.                     ScambiaElementi(MatriceDaOrdinare, Inf, Sup)
  2539.                     Inf = Inf + 1
  2540.                     Sup = Sup - 1
  2541.                 End If
  2542.             Loop Until Inf > Sup
  2543.             If Sup <= PuntoMedioMatrice Then
  2544.                 Call QuickSortChiaviPerTentativi(MatriceDaOrdinare, LimiteInf, Sup)
  2545.                 Call QuickSortChiaviPerTentativi(MatriceDaOrdinare, Inf, LimiteSup)
  2546.             Else
  2547.                 Call QuickSortChiaviPerTentativi(MatriceDaOrdinare, Inf, LimiteSup)
  2548.                 Call QuickSortChiaviPerTentativi(MatriceDaOrdinare, LimiteInf, Sup)
  2549.             End If
  2550.         End If
  2551.     End Sub
  2552.  
  2553.     Private Sub ScambiaElementi(ByRef varItemsMat1(,) As Int32, ByVal intItem1 As Integer, ByVal intItem2 As Integer)
  2554.  
  2555.         Dim varTemporanea As Integer
  2556.  
  2557.         varTemporanea = varItemsMat1(intItem2, 1)
  2558.         varItemsMat1(intItem2, 1) = varItemsMat1(intItem1, 1)
  2559.         varItemsMat1(intItem1, 1) = varTemporanea
  2560.  
  2561.         varTemporanea = varItemsMat1(intItem2, 2)
  2562.         varItemsMat1(intItem2, 2) = varItemsMat1(intItem1, 2)
  2563.         varItemsMat1(intItem1, 2) = varTemporanea
  2564.  
  2565.     End Sub
  2566.  
  2567.     ' Funzione che restituisce un seme (seed) , per i Random.
  2568.     Friend Function SemeRnd() As Long
  2569.         Return (My.Computer.Clock.TickCount * 2) + (Date.Now.Millisecond * 13719)
  2570.     End Function
  2571.     ' Effettua gli scambi in un Array o vettore o Lista.
  2572.     Friend Sub swap(ByRef v1, ByRef v2)
  2573.         Dim tmp
  2574.         tmp = v1
  2575.         v1 = v2
  2576.         v2 = tmp
  2577.     End Sub
  2578.     ' Funzione per il mescolamento Random di un array bidimensionale.
  2579.     Friend Sub Mischia(ByRef M(,) As Int32, ByVal n As Int32, Optional ByVal nMix As Int32 = 9)
  2580.         Dim i As Int32
  2581.         Dim j As Int32
  2582.         Dim x As Int16 = 1
  2583.         n = n / 2 + 1
  2584.         Dim NumVolte = New System.Random(Date.Now.Millisecond).Next(1, nMix + 1)
  2585.         Dim Rnd = New System.Random(SemeRnd)
  2586.  
  2587.         For s As Int32 = 1 To NumVolte
  2588.  
  2589.             Dim nx As Int32 = 0
  2590.             nx += Rnd.Next(0, n * 2)
  2591.             Do
  2592.                 If nx > n Then
  2593.                     nx -= n
  2594.                 End If
  2595.                 If nx = 0 Then
  2596.                     nx += Rnd.Next(0, n * 2)
  2597.                 End If
  2598.             Loop While (nx = 0) Or (nx > n)
  2599.  
  2600.             If x = 1 Then
  2601.                 For i = 1 To nx Step +1
  2602.                     j = Rnd.Next(1, n + nx + i)
  2603.                     Do
  2604.                         If j > n Then
  2605.                             j -= n
  2606.                         End If
  2607.                     Loop While j > n
  2608.                     If i <> j Then
  2609.                         swap(M(i, 1), M(j, 1))
  2610.                         swap(M(i, 2), M(j, 2))
  2611.                     End If
  2612.                 Next i
  2613.                 x = 2
  2614.             ElseIf x = 2 Then
  2615.                 For i = n To nx Step -1
  2616.                     j = Rnd.Next(1, n + nx + i)
  2617.                     Do
  2618.                         If j > n Then
  2619.                             j -= n
  2620.                         End If
  2621.                     Loop While j > n
  2622.                     If i <> j Then
  2623.                         swap(M(i, 1), M(j, 1))
  2624.                         swap(M(i, 2), M(j, 2))
  2625.                     End If
  2626.                 Next i
  2627.                 x = 1
  2628.             End If
  2629.         Next s
  2630.  
  2631.     End Sub
  2632.  
  2633.     Sub RilasciaCollectionMatrici()
  2634.  
  2635.         Lst_SAT.Clear()
  2636.  
  2637.     End Sub
  2638.  
  2639. #End Region
  2640.  
  2641. End Class