/// <summary>
        /// Auxilia a acçáo em cadeia.
        /// </summary>
        /// <param name="startNode">O nó de início.</param>
        private void InnerChainReaction(TransportationMatrixTreeNode startNode)
        {
            var currentNode = startNode.Next;

            if (currentNode == null)
            {
                return;
            }

            var minimumAllocation = this.resultMatrix[currentNode.Line, currentNode.Column];
            var toRemoveNode      = currentNode;

            currentNode = currentNode.Next;
            bool status = false;

            while (currentNode != null)
            {
                if (status)
                {
                    var temp = resultMatrix[currentNode.Line, currentNode.Column];
                    if (temp < minimumAllocation)
                    {
                        minimumAllocation = temp;
                        toRemoveNode      = currentNode;
                    }
                }

                currentNode = currentNode.Next;
                status      = !status;
            }

            currentNode = startNode;
            while (currentNode != null)
            {
                resultMatrix[currentNode.Line, currentNode.Column] += minimumAllocation;
                currentNode = currentNode.Next;
                resultMatrix[currentNode.Line, currentNode.Column] -= minimumAllocation;
                currentNode = currentNode.Next;
            }

            resultMatrix[toRemoveNode.Line, toRemoveNode.Column] = -1;
            resultMatrix[startNode.Line, startNode.Column]       = minimumAllocation;
        }
        /// <summary>
        /// Aplica a acção em cadeia.
        /// </summary>
        /// <returns>Verdadeiro caso uma alteração tenha sido processada e falso caso contrário.</returns>
        /// <exception cref="MathematicsException">Em caso de erro interno.</exception>
        private bool ChainReaction()
        {
            double minimumCost  = 0;
            int    chosenLine   = -1;
            int    chosenColumn = -1;

            for (int i = 0; i < this.supplyNumber; ++i)
            {
                for (int j = 0; j < this.demandNumber; ++j)
                {
                    double temporary = this.transportationCost[i, j] - u[i] - v[j];
                    if (temporary < minimumCost)
                    {
                        minimumCost  = temporary;
                        chosenLine   = i;
                        chosenColumn = j;
                    }
                }
            }

            if (chosenLine == -1 || chosenColumn == -1)
            {
                return(false);
            }

            bool[] isRowEliminated    = new bool[this.supplyNumber];
            bool[] isColumnEliminated = new bool[this.demandNumber];
            Queue <TransportationMatrixTreeNode> nodeQueue = new Queue <TransportationMatrixTreeNode>();
            var startNode = new TransportationMatrixTreeNode()
            {
                Line   = chosenLine,
                Column = chosenColumn
            };

            for (int i = 0; i < this.demandNumber; ++i)
            {
                if (this.resultMatrix[chosenLine, i] != -1 && i != chosenColumn)
                {
                    nodeQueue.Enqueue(new TransportationMatrixTreeNode()
                    {
                        Line   = chosenLine,
                        Column = i,
                    });
                }
            }

            isRowEliminated[chosenLine] = true;

            while (nodeQueue.Count != 0)
            {
                var currentNode = nodeQueue.Dequeue();
                if (!isRowEliminated[currentNode.Line])
                {
                    for (int i = 0; i < this.demandNumber; ++i)
                    {
                        if (currentNode.Line == startNode.Line &&
                            i == startNode.Column)
                        {
                            startNode.Next = currentNode;
                            this.InnerChainReaction(startNode);
                            return(true);
                        }

                        if (this.resultMatrix[currentNode.Line, i] != -1 &&
                            i != currentNode.Column &&
                            !isColumnEliminated[i])
                        {
                            if (!nodeQueue.Any(n => n.Line == currentNode.Line &&
                                               n.Column == i))
                            {
                                nodeQueue.Enqueue(new TransportationMatrixTreeNode()
                                {
                                    Line   = currentNode.Line,
                                    Column = i,
                                    Next   = currentNode
                                });
                            }
                        }
                    }

                    isRowEliminated[currentNode.Line] = true;
                }

                if (!isColumnEliminated[currentNode.Column])
                {
                    for (int i = 0; i < this.supplyNumber; ++i)
                    {
                        if (i == startNode.Line &&
                            currentNode.Column == startNode.Column)
                        {
                            startNode.Next = currentNode;
                            this.InnerChainReaction(startNode);
                            return(true);
                        }

                        if (this.resultMatrix[i, currentNode.Column] != -1 &&
                            i != currentNode.Line &&
                            !isRowEliminated[i])
                        {
                            if (!nodeQueue.Any(n => n.Line == i &&
                                               n.Column == currentNode.Column))
                            {
                                nodeQueue.Enqueue(new TransportationMatrixTreeNode()
                                {
                                    Line   = i,
                                    Column = currentNode.Column,
                                    Next   = currentNode
                                });
                            }
                        }
                    }

                    isColumnEliminated[currentNode.Column] = true;
                }
            }

            throw new MathematicsException("An error occured while processing chain reacion.");
        }