private int calculaDiferenca(List<VerticeTsp> caminho, GrafoTsp grafo, VerticeTsp a, VerticeTsp b, VerticeTsp c, VerticeTsp d) { int diferenca = ( grafo.MatrizDistancias[a.Id, b.Id] + grafo.MatrizDistancias[c.Id, d.Id] - grafo.MatrizDistancias[a.Id, c.Id] - grafo.MatrizDistancias[b.Id, d.Id]); return diferenca; }
public List<VerticeTsp> ExecutarTspNn(GrafoTsp grafo) { VerticeTsp proximo = null; int chave = 0; int tamanho = grafo.Vertices.Count; List<VerticeTsp> caminho = new List<VerticeTsp>(); VerticeTsp inicial = grafo.Vertices.First().Value; inicial.Auxiliar = false; int linha = inicial.Id; caminho.Add(inicial); while (caminho.Count < tamanho) { int menorDistancia = grafo.MatrizDistancias[linha, linha]; for (int coluna = 1; coluna <= tamanho; coluna++) { int distancia = grafo.MatrizDistancias[linha, coluna]; if ((distancia < menorDistancia) && (grafo.Vertices[coluna].Auxiliar)) { menorDistancia = distancia; chave = coluna; } } proximo = grafo.Vertices[chave]; proximo.Auxiliar = false; caminho.Add(proximo); linha = proximo.Id; } caminho.Add(inicial); return caminho; }
public static IEnumerable<string> GerarRetornoTsp(List<VerticeTsp> caminho, GrafoTsp grafo) { var retorno = new List<string>(); int distancia = 0; int tamanho = (caminho.Count - 1); for (int i = 0; i < tamanho; i++) distancia += grafo.MatrizDistancias[caminho[i].Id, caminho[i + 1].Id]; retorno.Add(distancia.ToString()); foreach (var item in caminho) retorno.Add(item.Id.ToString()); return retorno; }
public List<VerticeTsp> opt2(List<VerticeTsp> caminho, GrafoTsp grafo) { int tamanho = caminho.Count - 1; while (true) { int max = 0; Tuple<VerticeTsp, VerticeTsp, VerticeTsp, VerticeTsp> best = null; var n = caminho.Count; for (var i = 0; i < n - 3; i++) { var a = caminho[i]; var b = caminho[i + 1]; for (var j = i + 2; j < n - 1; j++) { var c = caminho[j]; var d = caminho[j + 1]; var difenca = calculaDiferenca(caminho, grafo, a, b, c, d); if (difenca > max) { max = difenca; best = new Tuple<VerticeTsp, VerticeTsp, VerticeTsp, VerticeTsp>(a, b, c, d); } } } if (max != 0) { var bi = caminho.IndexOf(best.Item2); var ci = caminho.IndexOf(best.Item3); caminho.RemoveAt(bi); caminho.Insert(bi, best.Item3); caminho.RemoveAt(ci); caminho.Insert(ci, best.Item2); } else { break; } } return caminho; }
public static GrafoTsp LerTsp(string caminhoArquivo) { var arquivo = File.ReadAllLines(caminhoArquivo); var retorno = new GrafoTsp(arquivo.Length); foreach (var linha in arquivo) { try { var split = linha.Trim().Split(' '); var ponto = new Ponto(Convert.ToDouble(split[1]), Convert.ToDouble(split[2])); var vertice = new VerticeTsp(Convert.ToInt32(split[0]), ponto); retorno.Vertices.Add(Convert.ToInt32(split[0]), vertice); } catch (Exception e) { throw new Exception(String.Format("Erro ao tratar linha: '{0}' . Mensagem de erro: {1}", linha, e.Message)); } } return retorno; }