示例#1
0
        private static FractionedNumber[,] VogelFirstPart(FractionedNumber[,] costs, FractionedNumber[] demand, FractionedNumber[] supply)
        {
            verifyVogel(demand, supply, costs);
            Functions.result += "Matriz de custos de entrada:\n";
            Functions.result += printMatrix(costs);
            Functions.result += "Supply de entrada:\n";
            for(int i = 0;i < supply.Length;i++) {
                Functions.result += supply[i] + (i+1<supply.Length?", ":"");
            }
            Functions.result += "\nDemand de entrada:\n";
            for(int i = 0;i < demand.Length;i++) {
                Functions.result += demand[i] + (i + 1 < demand.Length ? ", " : "");
            }
            Functions.result += "\n----------------------------\n";
            FractionedNumber[] demandRemaining = new FractionedNumber[demand.Length];
            FractionedNumber[] supplyRemaining = new FractionedNumber[supply.Length];
            FractionedNumber[,] result = new FractionedNumber[costs.GetLength(0), costs.GetLength(1)];
            List<VogelPos> taxaDegeneracao = new List<VogelPos>();

            Array.Copy(demand, demandRemaining, demand.Length);
            Array.Copy(supply, supplyRemaining, supply.Length);

            List<VogelPos> temp = new List<VogelPos>();

            for (int l = 0; l < costs.GetLength(0); l++) {
                temp.Clear();
                for (int c = 0; c < costs.GetLength(1); c++) {
                    temp.Add(new VogelPos(l,c, costs[l, c],true));
                }
                var n = temp.OrderBy(x => x.number);

                if(costs[n.ElementAt(0).x, n.ElementAt(0).y] < costs[n.ElementAt(1).x, n.ElementAt(1).y]) {
                    taxaDegeneracao.Add(new VogelPos(n.ElementAt(0).x, n.ElementAt(0).y, n.ElementAt(1).number - n.ElementAt(0).number,true));
                } else {
                    taxaDegeneracao.Add(new VogelPos(n.ElementAt(1).x, n.ElementAt(1).y, n.ElementAt(0).number - n.ElementAt(1).number,true));
                }
            }

            for(int c = 0;c < costs.GetLength(1);c++) {
                temp.Clear();
                for(int l = 0;l < costs.GetLength(0);l++) {
                    temp.Add(new VogelPos(l, c, costs[l, c],false));
                }
                temp = temp.OrderBy(x => x.number).ToList();

                if(costs[temp.ElementAt(0).x, temp.ElementAt(0).y] < costs[temp.ElementAt(1).x, temp.ElementAt(1).y]) {
                    taxaDegeneracao.Add(new VogelPos(temp.ElementAt(0).x, temp.ElementAt(0).y,  temp.ElementAt(1).number - temp.ElementAt(0).number,false));
                } else {
                    taxaDegeneracao.Add(new VogelPos(temp.ElementAt(1).x, temp.ElementAt(1).y, temp.ElementAt(0).number - temp.ElementAt(1).number,false));
                }
            }
            Functions.result += "Taxa de degeneração: \n";
            for(int i = 0;i < taxaDegeneracao.Count;i++) {
                Functions.result += taxaDegeneracao[i].number + " @ " + (taxaDegeneracao[i].x + 1) + "," + (taxaDegeneracao[i].y + 1) + (taxaDegeneracao[i].line?" linha ":" coluna ") + "\n";
            }
            Functions.result += "---------- \n";

            taxaDegeneracao = taxaDegeneracao.OrderBy(x => 0-x.number).ThenBy(x=>costs[x.x,x.y]).ToList();

            Functions.result += "Taxa de degeneração ordenada: \n";
            for(int i = 0;i < taxaDegeneracao.Count;i++) {
                Functions.result += taxaDegeneracao[i].number + " @ " + (taxaDegeneracao[i].x + 1) + "," + (taxaDegeneracao[i].y + 1) + (taxaDegeneracao[i].line ? " linha " : " coluna ") + "\n";
            }
            Functions.result += "---------- \n";

            //Respeita a ordem da taxa de degeneracao
            for(int i = 0;i < taxaDegeneracao.Count;i++) {
                int l = taxaDegeneracao[i].x;
                int c = taxaDegeneracao[i].y;
                FractionedNumber min = long.MaxValue;
                FractionedNumber minSupplyDemand;

                if(taxaDegeneracao[i].line) {
                    for(int j = 0;j < costs.GetLength(1);j++) {
                        if(costs[l, j] < min) {
                            if(supply[l] > 0 && demand[j] > 0) {
                                min = costs[l, j];
                                c = j;
                            }
                        }
                    }
                } else {
                    for(int j = 0;j < costs.GetLength(0);j++) {
                        if(costs[j, c] < min) {
                            if(supply[j] > 0 && demand[c] > 0) {
                                min = costs[j, c];
                                l = j;
                            }
                        }
                    }
                }
                if(supply[l] == 0 || demand[c] == 0)
                    continue;
                minSupplyDemand = FractionedNumber.Min(supply[l], demand[c]);
                supply.SetValue(supply.ElementAt(l) - minSupplyDemand, l);
                demand.SetValue(demand.ElementAt(c) - minSupplyDemand, c);
                result[l, c] = minSupplyDemand;
            }

            temp.Clear();
            for(int l = 0;l < costs.GetLength(0);l++) {
                for(int c = 0;c < costs.GetLength(1);c++) {
                    temp.Add(new VogelPos(l, c, costs[l, c],false));
                }
            }
            temp = temp.OrderBy(x => x.number).ToList();

            for(int i = 0;i < temp.Count;i++) {
                if(supply[temp[i].x] > 0) {
                    if(demand[temp[i].y] > 0){
                        FractionedNumber min = FractionedNumber.Min(supply[temp[i].x], demand[temp[i].y]);
                            result[temp[i].x, temp[i].y] = min;
                            supply[temp[i].x] -= min;
                            demand[temp[i].y] -= min;
                    }
                }
            }
            Functions.result += "Matriz antes de fazer a segunda parte:\n";
            Functions.result += printMatrix(result);
            Functions.result += "-------------------------------\n";

            return result;
        }
示例#2
0
        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;
        }
示例#3
0
        private static void verifyVogel(FractionedNumber[] demand, FractionedNumber[] supply, FractionedNumber[,] matrix)
        {
            if(matrix.GetLength(1) != demand.Length || matrix.GetLength(0) != supply.Length) {
                string msg = "The demand and supply array doesn't have the same size of the matix\n";
                msg += "demand["+demand.Length+"], supply["+supply.Length+"], costs["+matrix.GetLength(0)+","+matrix.GetLength(1)+"]";
                throw new Exception(msg);
            }

            FractionedNumber sumSupply = SumNumbers(supply);
            FractionedNumber sumDemand = SumNumbers(demand);
            if(sumSupply != sumDemand) {
                string msg = "The sums of the supply and demand are differents!\n";
                msg += "Supply sum: " + sumSupply + ", Demand sum: " + sumDemand+"\n";
                msg += "You need to insert a new ";
                if(sumSupply > sumDemand)
                    msg += "demand (row bellow)";
                else
                    msg += "supply (colum on right)";
                msg += " with the value " + (FractionedNumber.Max(sumDemand, sumSupply) - FractionedNumber.Min(sumDemand, sumSupply));
                throw new Exception(msg);
            }
        }
示例#4
0
 private static FractionedNumber VogelCalculateTotalCost(FractionedNumber[,] matrix, FractionedNumber[,] costs)
 {
     result += "Total cost: ";
     FractionedNumber sum = 0;
     for(int l = 0;l < matrix.GetLength(0);l++) {
         for(int c = 0;c < matrix.GetLength(1);c++) {
             sum += matrix[l, c] * costs[l, c];
         }
     }
     result += sum;
     result += "\n";
     return sum;
 }
示例#5
0
 private static string printMatrix(FractionedNumber[,] m)
 {
     string s = "";
     for(int l = 0;l < m.GetLength(0);l++) {
         for(int c = 0;c < m.GetLength(1);c++) {
             s += (m[l, c] + "\t|");
         }
         s += "\n";
     }
     return s;
 }
示例#6
0
 private static void sumOut(FractionedNumber[] lines, FractionedNumber[] colums, bool[,] usedMatrix, FractionedNumber[,] costs, FractionedNumber[,] tempMatrix)
 {
     for(int l = 0;l < tempMatrix.GetLength(0);l++) {
         for(int c = 0;c < tempMatrix.GetLength(1);c++) {
             if(!usedMatrix[l, c]) {
                 tempMatrix[l, c] = costs[l, c] - lines[l] - colums[c];
             } else {
                 tempMatrix[l, c] = null;
             }
         }
     }
 }
示例#7
0
        private static FractionedNumber[,] NorthWestFirstPart(FractionedNumber[,] costs, FractionedNumber[] demand, FractionedNumber[] supply)
        {
            verifyVogel(demand, supply, costs);
            Functions.result += "Matriz de custos de entrada:\n";
            Functions.result += printMatrix(costs);
            Functions.result += "Supply de entrada:\n";
            for(int i = 0;i < supply.Length;i++) {
                Functions.result += supply[i] + (i + 1 < supply.Length ? ", " : "");
            }
            Functions.result += "\nDemand de entrada:\n";
            for(int i = 0;i < demand.Length;i++) {
                Functions.result += demand[i] + (i + 1 < demand.Length ? ", " : "");
            }
            Functions.result += "\n----------------------------\n";

            FractionedNumber[] demandRemaining = new FractionedNumber[demand.Length];
            FractionedNumber[] supplyRemaining = new FractionedNumber[supply.Length];
            FractionedNumber[,] result = new FractionedNumber[costs.GetLength(0), costs.GetLength(1)];

            Array.Copy(demand, demandRemaining, demand.Length);
            Array.Copy(supply, supplyRemaining, supply.Length);

            int posL = 0;
            int posC = 0;
            while(demandRemaining[posC]!=0 && supplyRemaining[posL]!=0) {
                FractionedNumber min = FractionedNumber.Min(demandRemaining[posC], supplyRemaining[posL]);
                result[posL, posC] = min;
                demandRemaining[posC] -= min;
                supplyRemaining[posL] -= min;
                if(supplyRemaining[posL] == 0) {
                    if(supplyRemaining.Length!=posL+1)
                        posL++;
                }
                if(demandRemaining[posC] == 0) {
                    if(demandRemaining.Length != posC + 1)
                        posC++;
                }

            }
            Functions.result += "Matriz antes de fazer a segunda parte:\n";
            Functions.result += printMatrix(result);
            Functions.result += "-------------------------------\n";
            return result;
        }
示例#8
0
        private static void goLine(int x, int y, FractionedNumber v, FractionedNumber[,] m, FractionedNumber[,] costs, bool[,] usedMatrix, FractionedNumber[] lines, FractionedNumber[] colums)
        {
            if(x == -1 && y == -1) {
                lines[0] = 0;
            }
            for(int i = 0;i < m.GetLength(1);i++) {
                if(i == y)
                    continue;

                if((x == -1 && y == -1) || usedMatrix[x,i]) {
                    if(x == -1 && y == -1) {
                        if(usedMatrix[0, i]) {
                            m[0, i] = 0 - v + costs[0, i];
                            if(colums[i] == null)
                                colums[i] = m[0, i];
                            usedMatrix[0, i] = false;
                            goColum(0, i, m[0, i], m, costs, usedMatrix, lines, colums);
                        }
                    } else {
                        m[x, i] = 0 - v + costs[x, i];
                        if(colums[i] == null)
                            colums[i] = m[x, i];
                        usedMatrix[x, i] = false;
                        goColum(x, i, m[x, i], m, costs, usedMatrix, lines, colums);
                    }
                }
            }
        }
示例#9
0
 private static void goColum(int x, int y, FractionedNumber v, FractionedNumber[,] m, FractionedNumber[,] costs, bool[,] usedMatrix, FractionedNumber[] lines, FractionedNumber[] colums)
 {
     for(int i = 0;i < m.GetLength(0);i++) {
         if(i == x)
             continue;
         if(usedMatrix[i,y]) {
             m[i,y] = 0 - v + costs[i,y];
             if(lines[i] == null)
                 lines[i] = m[i, y];
             usedMatrix[i,y] = false;
             goLine(i,y, m[i,y], m, costs, usedMatrix, lines, colums);
         }
     }
 }
示例#10
0
 private static bool[,] GetMatrixInsideVogel(FractionedNumber[,] matrix)
 {
     bool[,] res = new bool[matrix.GetLength(0), matrix.GetLength(1)];
     for (int l = 0; l < matrix.GetLength(0); l++) {
         for (int c = 0; c < matrix.GetLength(1); c++) {
             if (matrix[l, c] != null)
                 res[l, c] = true;
             else
                 res[l, c] = false;
         }
     }
     return res;
 }
示例#11
0
 public static FractionedNumber[,] VogelInverseMatrix(FractionedNumber[,] matrix)
 {
     FractionedNumber max = long.MinValue;
     FractionedNumber[,] newMatrix = new FractionedNumber[matrix.GetLength(0), matrix.GetLength(1)];
     for(int l = 0;l < matrix.GetLength(0);l++) {
         for(int c = 0;c < matrix.GetLength(1);c++) {
             max = FractionedNumber.Max(max, matrix[l, c]);
         }
     }
     for(int l = 0;l < matrix.GetLength(0);l++) {
         for(int c = 0;c < matrix.GetLength(1);c++) {
             newMatrix[l, c] = max - matrix[l, c];
         }
     }
     return newMatrix;
 }