Пример #1
0
        public override void ExecutarMetaheuristica()
        {
            //return Task.Factory.StartNew(() =>
            //{
            int iterAtual = 0, melhor_i = -1, melhor_j = -1, foMenorCutwidthSolucaoAtual = 0, foMenorSomaCutwidthSolucaoAtual = 0, foMenorQuantidadeVerticesMaiorCutwidthSolucaoAtual = 0;

            var estruturaTabu = new EstruturaTabu(base.NumeroVertices, this.NumeroIteracoesProibicaoLista, this.NumeroMaximoIteracoesProibicaoLista, this.IncrementoTamanhoListaTabu);

            var solucaoAtual = GerarSolucaoLiteraturaC1(); // GerarSolucaoAleatoria(); // GerarSolucaoInicial(); // GerarSolucaoLiteraturaC1() // new List<int> { 1, 15, 6, 2, 5, 9, 8, 13, 11, 3, 10, 7, 4, 12, 19, 17, 16, 14, 18 };

            MelhorSolucao = new List <int>(solucaoAtual);

            ExecutarFuncaoAvaliacao(solucaoAtual);
            foMenorCutwidthSolucaoAtual     = FOMenorCutwidthMelhorSolucao = CutwidthGrafo.Max(x => x.Value);
            foMenorSomaCutwidthSolucaoAtual = FOMenorSomaCutwidthMelhorSolucao = CutwidthGrafo.Sum(x => x.Value);
            foMenorQuantidadeVerticesMaiorCutwidthSolucaoAtual = FOMenorQuantidadeVerticesMaiorCutwidthMelhorSolucao = CutwidthGrafo.Where(x => x.Value == foMenorCutwidthSolucaoAtual).Count();

            GravarLogDuranteExecucao($"{ melhor_i }; { melhor_j }; { foMenorCutwidthSolucaoAtual }; {  string.Join(" | ", solucaoAtual.Select(x => x.ToString().PadLeft(2, '0'))) }\n");

            Cronometro.Start();

            while (iterAtual - this.MelhorIteracao < this.NumeroMaximoIteracoesSemMelhora)
            {
                iterAtual++;

                melhor_i = melhor_j = -1;
                CalcularMelhorVizinhoBestImprovementTroca(solucaoAtual, iterAtual, estruturaTabu, ref melhor_i, ref melhor_j, ref foMenorCutwidthSolucaoAtual, ref foMenorSomaCutwidthSolucaoAtual);

                if (melhor_i >= 0 && melhor_j >= 0)
                {
                    CutwidthGrafo = ExecutarFuncaoAvaliacaoMovimentoTroca(solucaoAtual, melhor_i, melhor_j);

                    // Troca os elementos de acordo com a melhor vizinhança retornada
                    int aux = solucaoAtual[melhor_i];
                    solucaoAtual[melhor_i] = solucaoAtual[melhor_j];
                    solucaoAtual[melhor_j] = aux;

                    GravarLogDuranteExecucao($"{ melhor_i.ToString().PadLeft(2, '0') }; { melhor_j.ToString().PadLeft(2, '0') }; { foMenorCutwidthSolucaoAtual.ToString().PadLeft(2, '0') }; {  string.Join(" | ", solucaoAtual.Select(x => x.ToString().PadLeft(2, '0'))) }");

                    estruturaTabu.DefinirTabu(melhor_i, melhor_j, iterAtual);

                    if (foMenorCutwidthSolucaoAtual < FOMenorCutwidthMelhorSolucao ||
                        (foMenorCutwidthSolucaoAtual == FOMenorCutwidthMelhorSolucao && foMenorSomaCutwidthSolucaoAtual < FOMenorSomaCutwidthMelhorSolucao))
                    {
                        this.MelhorIteracao              = iterAtual;
                        FOMenorCutwidthMelhorSolucao     = foMenorCutwidthSolucaoAtual;
                        FOMenorSomaCutwidthMelhorSolucao = foMenorSomaCutwidthSolucaoAtual;

                        MelhorSolucao = new List <int>(solucaoAtual);

                        this.IteracoesMelhoraSolucaoGlobal.Add(iterAtual);

                        estruturaTabu.ResetarTamanhoLista();
                    }
                    else
                    {
                        if ((iterAtual - this.MelhorIteracao) % this.ModuloIteracaoSemMelhoraIncrementoListaTabu == 0)
                        {
                            estruturaTabu.IncrementarTamanhoLista();
                        }
                    }
                }
                else
                {
                    estruturaTabu.DecrementarTamanhoLista();
                }
            }

            Cronometro.Stop();

            ExecutarFuncaoAvaliacao(MelhorSolucao);

            GravarLogDuranteExecucao($"\n\nMelhorias solução global: {string.Join(" | ", base.IteracoesMelhoraSolucaoGlobal) }");
            GravarLogDuranteExecucao($"Cutdwidth: { base.FOMenorCutwidthMelhorSolucao }");
            GravarLogDuranteExecucao($"Solução Final: {  string.Join(" | ", MelhorSolucao.Select(x => x.ToString().PadLeft(2, '0'))) }");

            //Console.WriteLine(estruturaTabu.QuantidadeIteracoesProibicao);
            //estruturaTabu.ImprimirTrocasListaTabu(base.Instancia);
            //estruturaTabu.ImprimirQuantidadeIteracoesProibicaoListaTabu(base.Instancia);
            //});
        }
Пример #2
0
        // NÃO ESTÁ PRONTO
        private void CalcularMelhorVizinhoBestImprovementInsercao(List <int> solucaoAtual, int iteracaoAtual, EstruturaTabu estruturaTabu, ref int melhor_i, ref int melhor_j, ref int foMenorCutwidthSolucaoAtual, ref int foMenorSomaCutwidthSolucaoAtual)
        {
            int difGrauI, difGrauJ;
            int foMenorCutwidthVizinho = 0, foMenorCutwidthSomaVizinho = 0;

            Dictionary <string, int> cutwidthAposTroca = null;
            var listaCandidatos = new List <Tuple <int, int> >();

            //ExecutarFuncaoAvaliacao(solucaoAtual);
            var informacoesPosicoesSolucaoAtual        = RetornarGrauVerticesPosicoes(solucaoAtual);

            foMenorCutwidthSolucaoAtual     = int.MaxValue;
            foMenorSomaCutwidthSolucaoAtual = int.MaxValue;

            for (int i = 0; i < solucaoAtual.Count; i++)
            {
                for (int j = 0; j < solucaoAtual.Count; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }

                    // Se o grau do vértice i for maior à esquerda do que à direita, não se deve movê-lo para ainda mais a direita
                    difGrauI = informacoesPosicoesSolucaoAtual[i].GrauVerticeEsquerda - informacoesPosicoesSolucaoAtual[i].GrauVerticeDireita;
                    if (difGrauI > 0)
                    {
                        continue;
                    }

                    // Se o grau do vértice j for maior à direita do que à esquerda, não se deve movê-lo para ainda mais a esquerda
                    difGrauJ = informacoesPosicoesSolucaoAtual[j].GrauVerticeDireita - informacoesPosicoesSolucaoAtual[j].GrauVerticeEsquerda;
                    if (difGrauJ > 0)
                    {
                        continue;
                    }



                    ExecutarFuncaoAvaliacao(solucaoAtual);
                    int elementoInsercao = solucaoAtual[i];
                    solucaoAtual.Remove(elementoInsercao);
                    solucaoAtual.Insert(j, elementoInsercao);

                    ExecutarFuncaoAvaliacao(solucaoAtual);
                    int cutwidthFuncaoAntiga     = CutwidthGrafo.Max(x => x.Value);
                    int somaCutwidthFuncaoAntiga = CutwidthGrafo.Sum(x => x.Value);

                    solucaoAtual.Remove(elementoInsercao);
                    solucaoAtual.Insert(i, elementoInsercao);
                    ExecutarFuncaoAvaliacao(solucaoAtual);

                    cutwidthAposTroca          = ExecutarFuncaoAvaliacaoMovimentoInsercao(solucaoAtual, i, j);
                    foMenorCutwidthVizinho     = cutwidthAposTroca.Max(x => x.Value);
                    foMenorCutwidthSomaVizinho = cutwidthAposTroca.Sum(x => x.Value);



                    if (cutwidthFuncaoAntiga != foMenorCutwidthVizinho || somaCutwidthFuncaoAntiga != foMenorCutwidthSomaVizinho)
                    {
                    }



                    // se a lista tabu não restringe o elemento ou, mesmo que haja restrição, o resultado da função objetivo encontrado no momento é melhor que a melhor solução (fo_star)
                    if (foMenorCutwidthVizinho < this.FOMenorCutwidthMelhorSolucao ||
                        (foMenorCutwidthVizinho == this.FOMenorCutwidthMelhorSolucao && foMenorCutwidthSomaVizinho < this.FOMenorSomaCutwidthMelhorSolucao) ||
                        (!estruturaTabu.ElementoProibido(i, j, iteracaoAtual)))
                    {
                        // Caso seja o melhor vizinho encontrado
                        if (foMenorCutwidthVizinho < foMenorCutwidthSolucaoAtual || (foMenorCutwidthVizinho == foMenorCutwidthSolucaoAtual && foMenorCutwidthSomaVizinho <= foMenorSomaCutwidthSolucaoAtual))
                        {
                            if (foMenorCutwidthVizinho < foMenorCutwidthSolucaoAtual || foMenorCutwidthSomaVizinho < foMenorSomaCutwidthSolucaoAtual) // cria uma nova lista se o cutwidth diminuiu
                            {
                                listaCandidatos = new List <Tuple <int, int> >();
                            }

                            listaCandidatos.Add(Tuple.Create <int, int>(i, j));
                            foMenorCutwidthSolucaoAtual     = foMenorCutwidthVizinho;
                            foMenorSomaCutwidthSolucaoAtual = foMenorCutwidthSomaVizinho;

                            melhor_i = i;
                            melhor_j = j;
                        }
                        // Caso a nova solução melhore a solução atual ou seja igual à solução atual mas tenham sido feitas menos trocas
                        else if (foMenorCutwidthVizinho == foMenorCutwidthSolucaoAtual && foMenorCutwidthSomaVizinho == foMenorSomaCutwidthSolucaoAtual && estruturaTabu.QuantidadeTrocas(i, j) < estruturaTabu.QuantidadeTrocas(melhor_i, melhor_j))
                        {
                            listaCandidatos.Add(Tuple.Create <int, int>(i, j));
                        }
                    }
                }
            }

            // Dentre os melhores candidatos disponíveis, escolhe-se aleatoriamente algum deles
            int escolhaAleatoria = new Random().Next(0, listaCandidatos.Count);

            melhor_i = listaCandidatos[escolhaAleatoria].Item1;
            melhor_j = listaCandidatos[escolhaAleatoria].Item2;
        }