public override void ExecutarMetaheuristica() { //return Task.Factory.StartNew(() => //{ int iterAtual = 1, melhorIter = 0, nivelAtual = 1, iterMesmoNivel = 1, foMenorCutwidthSolucaoAtual = 0, foMenorSomaCutwidthSolucaoAtual = 0, foMenorCutwidthSolucaoPerturbadaAposDescida = 0, foMenorSomaCutwidthSolucaoPerturbadaAposDescida; List <int> solucaoPerturbada; var solucaoAtual = GerarSolucaoAleatoria(); ExecutarFuncaoAvaliacao(solucaoAtual); foMenorCutwidthSolucaoAtual = CutwidthGrafo.Max(x => x.Value); foMenorSomaCutwidthSolucaoAtual = CutwidthGrafo.Sum(x => x.Value); while (iterAtual - melhorIter < this.NumeroMaximoIteracoesSemMelhora) { solucaoPerturbada = PerturbarVetor(solucaoAtual, nivelAtual); ExecutarDescidaFistImprovement(solucaoPerturbada); ExecutarFuncaoAvaliacao(solucaoPerturbada); foMenorCutwidthSolucaoPerturbadaAposDescida = CutwidthGrafo.Max(x => x.Value); foMenorSomaCutwidthSolucaoPerturbadaAposDescida = CutwidthGrafo.Sum(x => x.Value); GravarLogDuranteExecucao($"{ iterAtual }; {nivelAtual}; {foMenorCutwidthSolucaoAtual}; { foMenorCutwidthSolucaoPerturbadaAposDescida }; { string.Join(" | ", solucaoAtual.Select(x => x.ToString().PadLeft(2, '0'))) }"); if (foMenorCutwidthSolucaoPerturbadaAposDescida < foMenorCutwidthSolucaoAtual || (foMenorCutwidthSolucaoPerturbadaAposDescida == foMenorCutwidthSolucaoAtual && foMenorSomaCutwidthSolucaoPerturbadaAposDescida < foMenorSomaCutwidthSolucaoAtual)) { solucaoAtual = new List <int>(solucaoPerturbada); foMenorCutwidthSolucaoAtual = foMenorCutwidthSolucaoPerturbadaAposDescida; foMenorSomaCutwidthSolucaoAtual = foMenorSomaCutwidthSolucaoPerturbadaAposDescida; melhorIter = iterAtual; nivelAtual = 1; iterMesmoNivel = 1; this.IteracoesMelhoraSolucaoGlobal.Add(iterAtual); } else { if (iterMesmoNivel > NumeroMaximoIteracoesMesmoNivel) { nivelAtual++; iterMesmoNivel = 1; } else { iterMesmoNivel++; } } iterAtual++; } MelhorSolucao = new List <int>(solucaoAtual); FOMenorCutwidthMelhorSolucao = foMenorCutwidthSolucaoAtual; 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'))) }"); //}); }
private Tuple <int, int> CalcularPrimeiroMelhorVizinho(List <int> solucaoAtual, int foMenorCutwidthSolucaoAtual, int foMenorSomaCutwidthSolucaoAtual, ref int melhor_i, ref int melhor_j) { int aux, foMenorCutwidthVizinho, foMenorSomaCutwidthVizinho, foMenorCutwidthMelhorVizinho = foMenorCutwidthSolucaoAtual, foMenorSomaCutwidthMelhorVizinho = foMenorSomaCutwidthSolucaoAtual; bool encontrou = false; for (int i = 0; i < solucaoAtual.Count - 1 && !encontrou; i++) { for (int j = i + 1; j < solucaoAtual.Count && !encontrou; j++) { aux = solucaoAtual[j]; solucaoAtual[j] = solucaoAtual[i]; solucaoAtual[i] = aux; ExecutarFuncaoAvaliacao(solucaoAtual); foMenorCutwidthVizinho = CutwidthGrafo.Max(x => x.Value); foMenorSomaCutwidthVizinho = CutwidthGrafo.Sum(x => x.Value); if (foMenorCutwidthVizinho < foMenorCutwidthSolucaoAtual || (foMenorCutwidthVizinho == foMenorCutwidthSolucaoAtual && foMenorSomaCutwidthVizinho < foMenorSomaCutwidthSolucaoAtual)) { melhor_i = i; melhor_j = j; foMenorCutwidthMelhorVizinho = foMenorCutwidthVizinho; foMenorSomaCutwidthMelhorVizinho = foMenorSomaCutwidthVizinho; encontrou = true; } aux = solucaoAtual[j]; solucaoAtual[j] = solucaoAtual[i]; solucaoAtual[i] = aux; } } return(Tuple.Create <int, int>(foMenorCutwidthMelhorVizinho, foMenorSomaCutwidthMelhorVizinho)); }
private void ExecutarDescidaFistImprovement(List <int> solucaoPerturbada) { int foMenorCutwidthSolucaoAtual = 0, foMenorSomaCutwidthSolucaoAtual = 0, foMenorCutwidthPrimeiroMelhorVizinho = 0, foMenorSomaCutwidthPrimeiroMelhorVizinho = 0, melhor_i = -1, melhor_j = -1, aux = -1; bool melhorou; ExecutarFuncaoAvaliacao(solucaoPerturbada); foMenorCutwidthSolucaoAtual = CutwidthGrafo.Max(x => x.Value); foMenorSomaCutwidthSolucaoAtual = CutwidthGrafo.Sum(x => x.Value); do { melhorou = false; var resultadoBuscaLocal = CalcularPrimeiroMelhorVizinho(solucaoPerturbada, foMenorCutwidthSolucaoAtual, foMenorSomaCutwidthSolucaoAtual, ref melhor_i, ref melhor_j); foMenorCutwidthPrimeiroMelhorVizinho = resultadoBuscaLocal.Item1; foMenorSomaCutwidthPrimeiroMelhorVizinho = resultadoBuscaLocal.Item2; if (foMenorCutwidthPrimeiroMelhorVizinho < foMenorCutwidthSolucaoAtual || (foMenorCutwidthPrimeiroMelhorVizinho == foMenorCutwidthSolucaoAtual && foMenorSomaCutwidthPrimeiroMelhorVizinho < foMenorSomaCutwidthSolucaoAtual)) { aux = solucaoPerturbada[melhor_j]; solucaoPerturbada[melhor_j] = solucaoPerturbada[melhor_i]; solucaoPerturbada[melhor_i] = aux; foMenorCutwidthSolucaoAtual = foMenorCutwidthPrimeiroMelhorVizinho; foMenorSomaCutwidthSolucaoAtual = foMenorSomaCutwidthPrimeiroMelhorVizinho; melhorou = true; } } while (melhorou); }
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); //}); }
// 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; }
// Scatter search for the Cutwidth Minimization Problem (C1) protected List <int> GerarSolucaoLiteraturaC1() { Random random = new Random(); int primeiroVertice, menorGrau = -1, posicaoSelecionada = -1, minCutwidth = int.MaxValue, minSomaCutwidth = int.MaxValue, maxCutwidth = int.MinValue, maxSomaCutwidth = int.MinValue, cutwidthSolucao = 0, menorCutwidthSolucao = int.MaxValue; double limiarRLC = 0, cutwidthLimite = 0, cutwidthSomaLimite = 0; List <int> melhorSolucao = null; var solucao = new List <int>(NumeroVertices); var cutwidthListaVerticesCandidatos = new List <int>(); var somaCutwidthListaVerticesCandidatos = new List <int>(); var listaVerticesCandidatosRLC = new List <int>(); var listaVerticesCandidatos = new List <int>(); var listaVerticesNaoInseridos = new List <int>(); int tentativas = 0; while (tentativas < 10) { solucao = new List <int>(NumeroVertices); for (int i = 1; i <= this.NumeroVertices; i++) { listaVerticesNaoInseridos.Add(i); } PosicaoSolucao[] informacoesPosicoesOriginal = RetornarGrauVerticesPosicoes(listaVerticesNaoInseridos).OrderBy(x => x.GrauVertice).ToArray(); PosicaoSolucao[] informacoesPosicoesAtualizado = null; // definição da primeira posição menorGrau = informacoesPosicoesOriginal.Min(x => x.GrauVertice); informacoesPosicoesAtualizado = informacoesPosicoesOriginal.Where(x => x.GrauVertice == menorGrau).ToArray(); posicaoSelecionada = random.Next(0, informacoesPosicoesAtualizado.Length); primeiroVertice = informacoesPosicoesAtualizado[posicaoSelecionada].Vertice; solucao.Add(primeiroVertice); listaVerticesNaoInseridos.Remove(primeiroVertice); do { // Reinicialização de variáveis cutwidthListaVerticesCandidatos = new List <int>(); somaCutwidthListaVerticesCandidatos = new List <int>(); listaVerticesCandidatos = new List <int>(); listaVerticesCandidatosRLC = new List <int>(); minCutwidth = int.MaxValue; maxCutwidth = int.MinValue; for (int i = 0; i < solucao.Count; i++) { var verticesAdjacentes = Grafo[solucao[i]]; foreach (var vertice in verticesAdjacentes) { if (!listaVerticesCandidatos.Contains(vertice) && !solucao.Contains(vertice)) { listaVerticesCandidatos.Add(vertice); } } } for (int i = 0; i < listaVerticesCandidatos.Count; i++) { int verticeCandidato = listaVerticesCandidatos[i]; solucao.Add(verticeCandidato); ExecutarFuncaoAvaliacao(solucao); cutwidthListaVerticesCandidatos.Add(CutwidthGrafo.Max(x => x.Value)); somaCutwidthListaVerticesCandidatos.Add(CutwidthGrafo.Sum(x => x.Value)); if (cutwidthListaVerticesCandidatos[i] < minCutwidth || (cutwidthListaVerticesCandidatos[i] == minCutwidth && somaCutwidthListaVerticesCandidatos[i] < minSomaCutwidth)) { minCutwidth = cutwidthListaVerticesCandidatos[i]; minSomaCutwidth = somaCutwidthListaVerticesCandidatos[i]; } if (cutwidthListaVerticesCandidatos[i] > maxCutwidth || (cutwidthListaVerticesCandidatos[i] == minCutwidth && somaCutwidthListaVerticesCandidatos[i] > minSomaCutwidth)) { maxCutwidth = cutwidthListaVerticesCandidatos[i]; maxSomaCutwidth = somaCutwidthListaVerticesCandidatos[i]; } solucao.Remove(verticeCandidato); } limiarRLC = random.NextDouble(); cutwidthLimite = minCutwidth + (limiarRLC * (maxCutwidth - minCutwidth)); cutwidthSomaLimite = minSomaCutwidth + (limiarRLC * (maxSomaCutwidth - minSomaCutwidth)); for (int i = 0; i < listaVerticesCandidatos.Count; i++) { if (cutwidthListaVerticesCandidatos[i] <= cutwidthLimite || somaCutwidthListaVerticesCandidatos[i] <= cutwidthSomaLimite) { listaVerticesCandidatosRLC.Add(listaVerticesCandidatos[i]); } } int elementoEscolhido = listaVerticesCandidatosRLC[random.Next(0, listaVerticesCandidatosRLC.Count)]; solucao.Add(elementoEscolhido); listaVerticesNaoInseridos.Remove(elementoEscolhido); } while (listaVerticesNaoInseridos.Any()); ExecutarFuncaoAvaliacao(solucao); cutwidthSolucao = CutwidthGrafo.Max(x => x.Value); if (cutwidthSolucao < menorCutwidthSolucao) { melhorSolucao = new List <int>(solucao); menorCutwidthSolucao = cutwidthSolucao; } tentativas++; } ExecutarFuncaoAvaliacao(melhorSolucao); menorCutwidthSolucao = CutwidthGrafo.Max(x => x.Value); return(solucao); }