Beispiel #1
0
        /*
         * RILASSAMENTO
         * Da scrivere dopo aver completato Bisezione, PassoFisso e Grossolana
         */

        /*
         * STEEPEST
         * Da scrivere dopo aver completato Bisezione, PassoFisso e Grossolana
         */

        /*
         * PASSOFISSO
         * Analoga a Bisezione (stessi parametri o quasi...)
         * Usa pero` il gradiente come condizione di uscita al posto della distanza (oltre alla f)
         */

        /// <summary>
        /// Incrementa contatori
        /// </summary>
        /// <param name="contatori">Colonna (n,1) con i contatori</param>
        /// <param name="passi">Colonna (n,1) con i passi massimi</param>
        /// <param name="indIncrementato">Indice incrementato, oppure -1 se variato piu` di uno</param>
        /// <returns>true se ha incrementato un indice, false se era gia` l'ultimo passo</returns>
        public static bool Incrementa(ref MatrixBase <int> contatori,
                                      MatrixBase <int> passi,
                                      ref int indIncrementato)
        {
            bool fine = false;                                  // Flag finale
            int  n;                                             // Dimensione dei vettori

            n = contatori.Row;
            if ((passi.Row != n) || (passi.Col != 1) || (contatori.Col != 1))
            {
                return(fine);                                       // Verifica gli indici
            }

            int indice = 0;                                     // Inizia con il primo indice

            indIncrementato = 0;                                // Indice da ricalcolare (-1 se tutti)
            while (indice < n)
            {
                int c;
                c = contatori.Get(indice, 0) + 1;                   // Calcola indice incrementato
                if (c < passi.Get(indice, 0))                       // Se entro i limiti...
                {
                    contatori.Set(indice, 0, c);                    // Aggiorna indice
                    if (indIncrementato != -1)                      // Lo salva, per aggiornamento calcoli...
                    {
                        indIncrementato = indice;                   // ... ma solo se non erano gia` cambiati piu` indici
                    }
                    fine = true;                                    // Raggiunta uscita prima della fine
                    break;                                          // Esce dal ciclo while
                }
                else
                {                                                   // ...se superato i limiti
                    contatori.Set(indice, 0, 0);                    // Azzera contatore
                    indice         += 1;                            // Passa all'indice successivo
                    indIncrementato = -1;
                    continue;                                       // Continua il ciclo while
                }
            }                                                       // Se esce normalmente dal while, fine resta true
            if (indice >= n)
            {
                fine = false;                                       // Se superato ultimo indice: ultimo passo, false
            }
            return(fine);
        }
Beispiel #2
0
        /*
         *
         * NOTA GENERALE.
         *
         * I metodi precedenti, steepest descent, rilassamento (per la scelta delle direzioni) e
         * passo fisso e bisezione (per la ricerca del minimo (o del massimo)
         * non sono sufficienti da soli.
         *
         * E' ragionevole scrivere prima alcune funzioni che lavorino separatamente.
         * Tutte sono incluse nella classe Fmin e hanno gia` implicito il delegate alla funzione
         * Tutte devono prima verificare che il delegate non sia nullo.
         *
         */


        /// <summary>
        /// Ricerca per punti
        /// </summary>
        /// <param name="xk">Punto centrale</param>
        /// <param name="range">Meta` ampiezza di ricerca (ammessi valori nulli)</param>
        /// <param name="passiU">Numero di passi unilaterali (almeno 1)</param>
        /// <param name="xmin">Punto con il valore minore</param>
        /// <param name="cicli">Numero di punti calcolati</param>
        /// <returns></returns>
        public bool Campionamento(Matrix xk,
                                  Matrix range,
                                  MatrixBase <int> passiU,
                                  ref Matrix xmin,
                                  ref int cicli)
        {
            bool found = false;
            int  n;                                                                 // Dimensioni dei vettori
            int  i;                                                                 // Contatore

            n = xk.Row;
            if ((range.Row != n) || (passiU.Row != n) || (xmin.Row != n) || (xk.Col != 1) || (range.Col != 1) || (passiU.Col != 1) || (xmin.Col != 1))
            {
                return(found);                                                          // Verifica indici
            }
            for (i = 0; i < n; i++)                                                     // Verifica intervalli (ammessi valori nulli)
            {
                if (range.Get(i, 0) < 0.0)
                {
                    return(found);
                }
            }
            for (i = 0; i < n; i++)                                                     // Verifica passi (almeno 1 per lato)
            {
                if (passiU.Get(i, 0) < 1)
                {
                    return(found);
                }
            }
            MatrixBase <int> passi = new MatrixBase <int>(n, 1);                    // Matrice dei passi

            for (i = 0; i < n; i++)                                                 // Calcola i passi effettivi (segmenti, non punti)
            {
                passi.Set(i, 0, passiU.Get(i, 0) * 2);
            }
            Matrix step = new Matrix(n, 1);

            for (i = 0; i < n; i++)                                                     // Calcola i passi effettivi
            {
                step.Set(i, 0, range.Get(i, 0) / passi.Get(i, 0));
            }
            Matrix xo = new Matrix(n, 1);

            for (i = 0; i < n; i++)                                                     // Calcola i punti di partenza
            {
                xo.Set(i, 0, xk.Get(i, 0) - step.Get(i, 0) * passiU.Get(i, 0));
            }
            MatrixBase <int> contatori = new MatrixBase <int>(n, 1, 0);             // Vettore dei contatotri (tutti a 0)
            Matrix           x         = new Matrix(n, 1);                          // Vettore dei valori effettivi
            int    iinc   = -1;
            double minimo = double.MaxValue;
            double f;

            cicli = 0;
            bool fine = false;

            while (!fine)
            {
                if (iinc >= 0)                                                          // ricalcola nuovo vettore x
                {
                    x.Set(iinc, 0, xo.Get(iinc, 0) + step.Get(iinc, 0) * contatori.Get(iinc, 0));
                }
                else
                {
                    for (i = 0; i < n; i++)
                    {
                        x.Set(i, 0, xo.Get(i, 0) + step.Get(i, 0) * contatori.Get(i, 0));
                    }
                }
                f = Funzione(x);                                                        // Calcola la f del punto x attuale
                if (f < minimo)                                                         // Vede se e` minima (rispetto ai valori trovati finora)
                {
                    minimo = f;
                    xmin   = x.Copy();
                    found  = true;
                }
                fine = !Incrementa(ref contatori, passi, ref iinc);
                cicli++;
            }
            return(found);
        }