Exemplo n.º 1
0
        /// <summary>
        /// Obtém o valor da estimativa a ser adicionada a cada um dos nós durante o algoritmo.
        /// </summary>
        /// <param name="input">Os dados de entrada.</param>
        /// <param name="line">A linha correspondente ao nó de cobertura.</param>
        /// <param name="component">A matriz dos custos.</param>
        /// <returns>O valor da estimativa.</returns>
        private ElementType GetBigDelta(
            DualHeuristicAlgInput <ElementType> input,
            KeyValuePair <int, ILongSparseMatrixLine <ElementType> > line,
            SparseDictionaryMathMatrix <ElementType> component)
        {
            var result = this.ring.Add(input.Gamma, this.ring.AdditiveInverse(input.Taus[line.Key]));

            foreach (var otherLine in component.GetLines())
            {
                if (otherLine.Key != line.Key)
                {
                    if (otherLine.Value.ContainsColumn(line.Key))
                    {
                        var currentCost   = otherLine.Value[line.Key];
                        var currentLambda = input.Lambdas[line.Key];
                        if (this.comparer.Compare(currentLambda, currentCost) >= 0)
                        {
                            var difference = this.ring.Add(
                                input.Gamma,
                                this.ring.AdditiveInverse(input.Taus[otherLine.Key]));
                            if (this.comparer.Compare(difference, result) < 0)
                            {
                                result = difference;
                            }
                        }
                    }
                }
            }

            return(result);
        }
Exemplo n.º 2
0
 /// <summary>
 /// Aplica o algoritmo dual aos dados de entrada para um determinado número de referências.
 /// </summary>
 /// <remarks>
 /// Os dados de entrada são alterados pelo algoritmo e podem ser reutilizados em fases posteriores.
 /// O valor de gama tem de ser previamente estimado.
 /// </remarks>
 /// <param name="refsNumber">O número de referências.</param>
 /// <param name="matrix">A matriz com os custos.</param>
 /// <param name="input">Os dados de entrada.</param>
 /// <returns>O custo aproximado pela heurística.</returns>
 public ElementType Run(
     int refsNumber,
     SparseDictionaryMathMatrix <ElementType> matrix,
     DualHeuristicAlgInput <ElementType> input)
 {
     if (refsNumber < 1)
     {
         throw new ArgumentException("The number of references must be at least one.");
     }
     else if (matrix == null)
     {
         throw new ArgumentNullException("matrix");
     }
     else if (input == null)
     {
         throw new ArgumentNullException("input");
     }
     else
     {
         this.dualGammaEstimAlgorithm.Run(matrix, input);
         return(this.Process(refsNumber, matrix, input));
     }
 }
Exemplo n.º 3
0
        /// <summary>
        /// Obtém os valores iniciais das variáveis lambda.
        /// </summary>
        /// <param name="matrix">A matriz dos custos.</param>
        /// <param name="greedySolution">A solução do algoritmo guloso.</param>
        /// <param name="dualInput">A entrada para o algoritmo dual propriamente dito.</param>
        /// <returns>Verdadeiro caso o algoritmo seja bem sucedido e falso caso contrário.</returns>
        public bool Run(
            SparseDictionaryMathMatrix <ElementType> matrix,
            GreedyAlgSolution <ElementType> greedySolution,
            DualHeuristicAlgInput <ElementType> dualInput)
        {
            if (matrix == null)
            {
                throw new ArgumentNullException("matrix");
            }
            else if (greedySolution == null)
            {
                throw new ArgumentNullException("greedySolution");
            }
            else if (dualInput == null)
            {
                throw new ArgumentNullException("dualInput");
            }
            else
            {
                dualInput.Lambdas.Clear();
                var componentEnum = matrix.GetLines().GetEnumerator();
                if (componentEnum.MoveNext())
                {
                    dualInput.Lambdas.Add(componentEnum.Current.Key, this.ring.AdditiveUnity);
                    foreach (var column in componentEnum.Current.Value.GetColumns())
                    {
                        if (column.Key != componentEnum.Current.Key)
                        {
                            if (greedySolution.Chosen.Contains(column.Key))
                            {
                                dualInput.Lambdas.Add(column.Key, this.ring.AdditiveUnity);
                            }
                            else
                            {
                                dualInput.Lambdas.Add(column.Key, column.Value);
                            }
                        }
                    }

                    while (componentEnum.MoveNext())
                    {
                        if (greedySolution.Chosen.Contains(componentEnum.Current.Key))
                        {
                            foreach (var column in componentEnum.Current.Value.GetColumns())
                            {
                                if (column.Key != componentEnum.Current.Key)
                                {
                                    var forComponentValue = this.ring.AdditiveUnity;
                                    if (dualInput.Lambdas.TryGetValue(column.Key, out forComponentValue))
                                    {
                                        if (this.comparer.Compare(column.Value, forComponentValue) < 0)
                                        {
                                            dualInput.Lambdas[column.Key] = column.Value;
                                        }
                                    }
                                    else
                                    {
                                        dualInput.Lambdas.Add(column.Key, this.ring.AdditiveUnity);
                                    }
                                }
                            }
                        }
                    }
                }

                return(true);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Realiza as iterações de melhoramento sobre os dados aproximados inicialmente.
        /// </summary>
        /// <param name="refsNumber">O número de referências.</param>
        /// <param name="matrix">A matriz dos custos.</param>
        /// <param name="input">Os dados de entrada.</param>
        /// <returns>O valor do custo dual.</returns>
        private ElementType Process(
            int refsNumber,
            SparseDictionaryMathMatrix <ElementType> matrix,
            DualHeuristicAlgInput <ElementType> input)
        {
            var multiplicativeSymmetric = this.ring.AdditiveInverse(this.ring.MultiplicativeUnity);
            var delta = this.ring.AdditiveUnity;

            while (!this.ring.IsMultiplicativeUnity(delta))
            {
                foreach (var line in matrix.GetLines())
                {
                    var bigDelta = this.GetBigDelta(
                        input,
                        line,
                        matrix);

                    var currentLambda = input.Lambdas[line.Key];
                    if (input.Cbar.ContainsKey(line.Key))
                    {
                        var value = this.ring.Add(
                            input.Cbar[line.Key],
                            this.ring.AdditiveInverse(currentLambda));
                        if (this.comparer.Compare(value, bigDelta) < 0)
                        {
                            bigDelta = value;
                            delta    = this.ring.MultiplicativeUnity;
                            input.Cbar.Remove(line.Key);

                            // TODO: cbar = min(u que cobre line tal que o custo é maior que lambda[line]
                            foreach (var coverLine in matrix.GetLines())
                            {
                                if (coverLine.Key != line.Key)
                                {
                                    if (coverLine.Value.ContainsColumn(line.Key))
                                    {
                                        var currentCost = coverLine.Value[line.Key];
                                        var compareCost = this.ring.Add(currentLambda, bigDelta);
                                        if (this.comparer.Compare(compareCost, currentCost) < 0)
                                        {
                                            var currentCbar = this.ring.AdditiveUnity;
                                            if (input.Cbar.TryGetValue(line.Key, out currentCbar))
                                            {
                                                if (this.comparer.Compare(currentCost, currentCbar) < 0)
                                                {
                                                    input.Cbar[line.Key] = currentCost;
                                                }
                                            }
                                            else
                                            {
                                                input.Cbar.Add(line.Key, currentCost);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if (this.comparer.Compare(this.ring.AdditiveUnity, bigDelta) < 0)
                    {
                        foreach (var coveringLine in matrix.GetLines())
                        {
                            if (coveringLine.Key != line.Key)
                            {
                                if (coveringLine.Value.ContainsColumn(line.Key))
                                {
                                    if (this.comparer.Compare(coveringLine.Value[line.Key], currentLambda) <= 0)
                                    {
                                        input.Taus[coveringLine.Key] = this.ring.Add(
                                            input.Taus[coveringLine.Key],
                                            bigDelta);
                                    }
                                }
                            }
                        }

                        input.Lambdas[line.Key] = this.ring.Add(input.Lambdas[line.Key], bigDelta);
                        input.Taus[line.Key]    = this.ring.Add(input.Taus[line.Key], bigDelta);
                    }
                }
            }

            var result = this.ring.AdditiveUnity;
            var prod   = this.ring.AddRepeated(input.Gamma, refsNumber);

            foreach (var line in matrix.GetLines())
            {
                result = this.ring.Add(result, input.Lambdas[line.Key]);
            }

            result = this.ring.Add(result, this.ring.AdditiveInverse(prod));
            return(result);
        }
Exemplo n.º 5
0
        public ElementType Run(
            SparseDictionaryMathMatrix <ElementType> matrix,
            DualHeuristicAlgInput <ElementType> input)
        {
            if (matrix == null)
            {
                throw new ArgumentNullException("matrix");
            }
            else if (input == null)
            {
                throw new ArgumentNullException("input");
            }
            else
            {
                input.Taus.Clear();
                var result = new Dictionary <int, ElementType>();
                input.Gamma = this.ring.AdditiveUnity;
                var currentGamma = this.ring.AdditiveUnity;
                foreach (var line in matrix.GetLines())
                {
                    // Setup the tau and cbar values
                    var tempTau = input.Lambdas[line.Key];
                    foreach (var coveredLine in line.Value.GetColumns())
                    {
                        if (coveredLine.Key != line.Key)
                        {
                            var difference = this.ring.Add(
                                input.Lambdas[coveredLine.Key],
                                this.ring.AdditiveInverse(coveredLine.Value));
                            if (this.comparer.Compare(difference, this.ring.AdditiveUnity) < 0)
                            {
                                tempTau = this.ring.Add(tempTau, difference);
                            }
                        }
                    }

                    if (this.comparer.Compare(input.Gamma, tempTau) < 0)
                    {
                        input.Gamma = tempTau;
                    }

                    if (this.comparer.Compare(currentGamma, tempTau) < 0)
                    {
                        currentGamma = tempTau;
                    }

                    input.Taus.Add(line.Key, tempTau);
                }

                foreach (var line in matrix.GetLines())
                {
                    foreach (var coveredLine in line.Value.GetColumns())
                    {
                        if (coveredLine.Key != line.Key)
                        {
                            var tempCbarValue = this.ring.Add(
                                coveredLine.Value,
                                this.ring.AdditiveInverse(input.Lambdas[coveredLine.Key]));
                            if (this.comparer.Compare(this.ring.AdditiveUnity, tempCbarValue) < 0)
                            {
                                var currentCbarInCoveredVertice = this.ring.AdditiveUnity;
                                if (input.Cbar.TryGetValue(coveredLine.Key, out currentCbarInCoveredVertice))
                                {
                                    if (this.comparer.Compare(tempCbarValue, currentCbarInCoveredVertice) < 0)
                                    {
                                        input.Cbar[coveredLine.Key] = coveredLine.Value;
                                    }
                                }
                                else
                                {
                                    input.Cbar.Add(coveredLine.Key, coveredLine.Value);
                                }
                            }
                        }
                    }
                }

                return(currentGamma);
            }
        }