private static FractionedNumber[,] VogelSecondPart(FractionedNumber[,] costs, FractionedNumber[] demand, FractionedNumber[] supply, FractionedNumber[,] matrix) { VogelPos min; int count = 1; do { min = new VogelPos(-1, -1, long.MaxValue, false); FractionedNumber[,] res = new FractionedNumber[matrix.GetLength(0), matrix.GetLength(1)]; bool[,] usedMatrix = GetMatrixInsideVogel(matrix); bool[,] usedMatrix2 = new bool[usedMatrix.GetLength(0), usedMatrix.GetLength(1)]; System.Array.Copy(usedMatrix, usedMatrix2, usedMatrix.Length); FractionedNumber[,] tempMatrix = new FractionedNumber[matrix.GetLength(0), matrix.GetLength(1)]; Functions.result += "=============================\n"; Functions.result += "Iteração "+count+"\n"; Functions.result += "=============================\n"; FractionedNumber[] lines = new FractionedNumber[matrix.GetLength(0)]; FractionedNumber[] colums = new FractionedNumber[matrix.GetLength(1)]; goLine(-1, -1, 0, tempMatrix, costs, usedMatrix2, lines, colums); bool erroL = false; bool erroC = false; for(int i = 0;i < lines.Length;i++) { if(lines[i] == null) erroL = true; } for(int i = 0;i < colums.Length;i++) { if(colums[i] == null) erroC = true; } if(erroL || erroC) { min.number = -1; Functions.result += "=============================\n"; Functions.result += "Não foi possível colocar valores em todas as linhas e colunas.\n"; Functions.result += "Deve-se criar uma variável artificial.\n"; int posX = -1; int posY = -1; if(erroL){ for(int i = 0;i < lines.Length;i++) { if(lines[i] == null) { for(int j = 0;j < matrix.GetLength(1);j++) { if(matrix[i, j] == null) { posX = i; posY = j; break; } } break; } } } else { for(int i = 0;i < colums.Length;i++) { if(colums[i] == null) { for(int j = 0;j < matrix.GetLength(0);j++) { if(matrix[j, i] == null) { posX = i; posY = j; break; } } break; } } } matrix[posX, posY] = 0; Functions.result += "Ela foi colocada em: L"+(posX+1)+", C"+(posY+1)+"\n"; Functions.result += "=============================\n"; continue; } for(int i = 0;i < lines.Length;i++) { Functions.result += "L" + (i + 1) + ":" + lines[i] + ", \t"; } Functions.result += "\n"; for(int i = 0;i < colums.Length;i++) { Functions.result += "C" + (i + 1) + ":" + colums[i] + ", \t"; ; } Functions.result += "\n\n"; Functions.result += "Matriz dentro:\n"; Functions.result += printMatrix(tempMatrix); Functions.result += "-------------------------\n"; sumOut(lines, colums, usedMatrix, costs, tempMatrix); Functions.result += "Matriz fora:\n"; Functions.result += printMatrix(tempMatrix); Functions.result += "-------------------------\n"; for(int l = 0;l < tempMatrix.GetLength(0);l++) { for(int c = 0;c < tempMatrix.GetLength(1);c++) { if(tempMatrix[l, c] != null) { if(tempMatrix[l, c] < min.number) { min.y = c; min.x = l; min.number = tempMatrix[l, c]; } } } } Functions.result += "Valor mínimo: "+min.number+" na linha "+(min.x+1)+" e coluna "+(min.y+1)+"\n"; if(min.number < 0) { List<VogelPos> list = VogelFindWay(min, usedMatrix, matrix); if(list == null) break; FractionedNumber min2 = FractionedNumber.Min(list[0].number, list[list.Count - 1].number); Functions.result += "Minimo: " + min2 + "\n"; bool soma = false; for(int i = 0;i < list.Count;i++) { if(matrix[list[i].x, list[i].y] == null) matrix[list[i].x, list[i].y] = 0; if(soma) { matrix[list[i].x, list[i].y] += min2; } else { matrix[list[i].x, list[i].y] -= min2; } if(matrix[list[i].x, list[i].y] == 0) matrix[list[i].x, list[i].y] = null; soma = !soma; } matrix[min.x, min.y] += min2; Functions.result += "Fez a troca\n"; } Functions.result += "-------------------------\n"; Functions.result += "Matriz: \n"; Functions.result += "-------------------------\n"; Functions.result += printMatrix(matrix); Functions.result += "-------------------------\n"; count++; } while(min.number<0 && count <= 25); if(count > 20) { Functions.result += "***********************\n"; Functions.result += "Houve muitas iterações, algo está errado!\n"; Functions.result += "***********************\n"; } bool tirouArt = false; for(int l = 0;l < matrix.GetLength(0);l++) { for(int c = 0;c < matrix.GetLength(1);c++) { if(matrix[l, c] == 0) { matrix[l, c] = null; tirouArt = true; } } } if(tirouArt) { Functions.result += "Foram tiradas as variáveis artificiais, ficando assim:\n"; Functions.result += printMatrix(matrix); Functions.result += "-------------------------\n"; } return matrix; }
private static bool VogelFindWayColum(List<VogelPos> list, VogelPos destiny, bool[,] usedMatrix, VogelPos now, FractionedNumber[,] matrix) { for(int x = 0;x < usedMatrix.GetLength(0);x++) { if(x == destiny.x && usedMatrix[x, now.y]) { return true; } if(usedMatrix[x, now.y]) { VogelPos v = new VogelPos(x, now.y, matrix[x, now.y], true); usedMatrix[v.x, v.y] = false; list.Add(v); if(VogelFindWayLine(list, destiny, usedMatrix, v, matrix)) { return true; } list.Remove(v); } } return false; }
private static bool VogelFindWayLine(List<VogelPos> list, VogelPos destiny, bool[,] usedMatrix, VogelPos now, FractionedNumber[,] matrix) { for(int y = 0;y < usedMatrix.GetLength(1);y++) { if(y == destiny.y && usedMatrix[now.x,y]) { VogelPos v = new VogelPos(now.x, y, matrix[now.x, y], true); usedMatrix[v.x, v.y] = false; list.Add(v); return true; } if(usedMatrix[now.x, y]) { VogelPos v = new VogelPos(now.x, y, matrix[now.x,y], true); usedMatrix[v.x, v.y] = false; list.Add(v); if(VogelFindWayColum(list,destiny,usedMatrix,v,matrix)){ return true; } list.Remove(v); } } return false; }
private static List<VogelPos> VogelFindWay(VogelPos destiny, bool[,] usedMatrix, FractionedNumber[,] matrix) { bool[,] usedMatrixTemp = new bool[usedMatrix.GetLength(0),usedMatrix.GetLength(1)]; Array.Copy(usedMatrix, usedMatrixTemp, usedMatrix.Length); List<VogelPos> list = new List<VogelPos>(); if(VogelFindWayLine(list, destiny, usedMatrixTemp, destiny, matrix)) { Functions.result += "Caminho encontrado:\n"; for(int i = 0;i < list.Count;i++) { Functions.result += "[" + (list[i].x + 1) + ", " + (list[i].y + 1) + "] "; } Functions.result += "\n"; return list; } else { Functions.result += "++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"; Functions.result += "Não encontrou caminho. ERRO!\n"; Functions.result += "++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"; } return null; }