Exemple #1
0
        /// <summary>
        /// Calcule et stockage des itérations
        /// </summary>
        private static void Compute()
        {
            //--- Parallélisation du calcul
            //Parallel.ForEach<Vecteur>(Vecteurs, vecteur =>
            for (int m = 0; m < Vecteurs.Count; m++)
            {
                Vecteur vecteur = Vecteurs[m];

                //--- Exclusion du calcul si la moyenne déterminée est 255
                if (vecteur.Moyenne < 255 && vecteur.Iterations[0].Elements.Length > 1)
                {
                    byte nbElement = (byte)vecteur.Iterations[0].Elements.Length;

                    bool ecart = true;
                    int i = 0;
                    short[] ecartMoyenneElements = new short[nbElement];

                    //--- Evaluation de la distance à la moyenne pour chaque élément
                    for (byte j = 0; j < nbElement; j++)
                    {
                        ecartMoyenneElements[j] = (Int16)(vecteur.Moyenne - vecteur.Iterations[0].Elements[j]);
                    }

                    //---
                    int delta = 0;
                    int[] left = new int[nbElement];
                    int[] right = new int[nbElement];
                    int maxshifts = 0;

                    for (int l = 0; l < nbElement; l++)
                    {
                        left[l] = delta < 0 ? -delta : 0;
                        delta +=  vecteur.Iterations[0].Elements[l] - vecteur.Moyenne;
                        right[l] = delta > 0 ? delta : 0;
                        if (left[l] + right[l] > maxshifts)
                            maxshifts = left[l] + right[l];
                    }
                    //----

                    //--- Tant que l'écart maximum pour un élement est différent de zéro, on fait une nouvelle itération
                    //while (ecart)
                    for (int o = 0; o < maxshifts; o++)
                    {
                        Iteration nouvelleIteration = new Iteration();
                        nouvelleIteration.Elements = new byte[nbElement];
                        vecteur.Iterations.Add(nouvelleIteration);

                        //---> le tableau membre[] contient la somme des écarts à la moyenne à gauche et à droite
                        //      de l'élément courant et du voisin de gauche de l'élément courant
                        short[,] membres = new short[2, 2];

                        //---> Optimisation : Seule le premier élémént calcul la somme de tous les éléments à sa droite
                        //     les autres éléments s'appuiront toujours sur les membres de leur voisin de gauche
                        membres[1, 0] = (short)(ecartMoyenneElements.Sum(ecartMoyenne => (short)ecartMoyenne) - ecartMoyenneElements[0]);
                        membres[1, 1] = membres[1, 0];

                        byte borneGauche = 0;
                        byte borneDroite = nbElement;

                        for (byte j = borneGauche; j < borneDroite; j++)
                        {
                            //---> Calcul la valeur du membre gauche de l'élément selon son voisin de gauche
                            if (j > 0)
                                membres[0, 1] = (short)(membres[0, 0] + ecartMoyenneElements[j - 1]);

                            //---> Calcul la valeur du membre droite selon son voisin de gauche
                            if (j > 0 && j < nbElement - 1)
                                membres[1, 1] = (short)(membres[1, 0] - ecartMoyenneElements[j]);
                            else if (j == nbElement - 1)
                                membres[1, 1] = 0;

                            //---> Si le membre gauche ou le membre de droite a besoin de valeurs
                            //     et que l'élément courant peut donner un de ses éléments
                            if ((membres[0, 1] > 0 || membres[1, 1] > 0) && vecteur.Iterations[i].Elements[j] > 0)
                            {
                                //---> Détermine si la distribution doit se faire à gauche ou à droite
                                int indexDistribution = membres[0, 1] >= membres[1, 1] ? -1 : 1;

                                //---> Décrémente la valeur de l'élément courant pour l'itération actuelle
                                nouvelleIteration.Elements[j] += (byte)(vecteur.Iterations[i].Elements[j] - 1);
                                //---> L'écart à la moyenne pour l'élément courant est incrémenté
                                ecartMoyenneElements[j] += 1;
                                //---> Incrémente la valeur de l'élément à gauche ou à droite de l'élément courant
                                nouvelleIteration.Elements[j + indexDistribution] += 1;
                                //---> L'écart à la moyenne pour l'élément à gauche ou à droite de l'élément courant est décrémente
                                ecartMoyenneElements[j + indexDistribution] -= 1;

                                //---> Décrémente le membre gauche ou droite de l'élément courant
                                if (indexDistribution == -1)
                                    membres[0, 1] -= 1;
                                if (indexDistribution == 1)
                                    membres[1, 1] -= 1;
                            }
                            else
                            {
                                nouvelleIteration.Elements[j] += vecteur.Iterations[i].Elements[j];
                            }

                            membres[0, 0] = membres[0, 1];
                            membres[1, 0] = membres[1, 1];

                            if (membres[0, 1] == 0)
                                borneGauche = j;

                            if (membres[1, 1] == 0)
                                borneDroite = j;

                        }

                        //ecart = ecartMoyenneElements.Sum(ecartMoyenne => (short)Math.Abs(ecartMoyenne)) > 0;

                        i++;
                    }
                }
            }
            //);
        }
Exemple #2
0
        /// <summary>
        /// Lecture du fichier input.txt et stockage des vecteur dans une structure en mémoire
        /// </summary>
        private static void ReadInputFile()
        {
            Vecteurs = new List<Vecteur>();

            string fileName = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "input.txt");

            string[] fileContent = File.ReadAllLines(fileName);

            for (int i = 0; i < fileContent.Length - 1; i += 3)
            {
                Vecteur vecteur = new Vecteur();

                vecteur.Iterations = new List<Iteration>();

                Iteration iterationInitiale = new Iteration();
                iterationInitiale.Elements = new byte[int.Parse(fileContent[i])];

                string[] elements = fileContent[i + 1].Split(new String[] { " " }, StringSplitOptions.RemoveEmptyEntries);

                int sommeElements = 0;
                for (int j = 0; j < elements.Length; j++)
                {
                    iterationInitiale.Elements[j] = byte.Parse(elements[j]);

                    //---> Somme des valeurs pour le calcul de la moyenne à atteindre
                    //     Cette somme est calculée ici afin de ne pas boucler de nouveau plus tard
                    sommeElements += iterationInitiale.Elements[j];
                }

                //--- Calcul de la moyenne des éléments
                //    Si la moyenne ne peut être atteindre pour tous les éléments
                //    alors la propriété moyenne est fixée à 255 pour l'exclusion du calcul (la moyenne max théorique étant 99)
                if (sommeElements % iterationInitiale.Elements.Length != 0)
                {
                    vecteur.Moyenne = 255;
                }
                else
                {
                    //---> Optimisation : L'itération initiale est gardée en mémoire
                    //                    uniquement si une solution est possible
                    vecteur.Iterations.Add(iterationInitiale);
                    vecteur.Moyenne = (byte)(sommeElements / iterationInitiale.Elements.Length);
                }
                //---

                Vecteurs.Add(vecteur);
            }
        }