Open In App

Transportation Problem | Set 4 (Vogel’s Approximation Method)

The North-West Corner method and the Least Cost Cell method has been discussed in the previous articles. In this article, the Vogel’s Approximation method will be discussed. Solution:

Below is the implementation for the approach discussed above




#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
const int INF = 1000;
 
// Function to find differences in rows and columns
pair<vector<int>, vector<int>> findDiff(vector<vector<int>>& grid) {
    vector<int> rowDiff;
    vector<int> colDiff;
 
    for (int i = 0; i < grid.size(); i++) {
        vector<int> arr = grid[i];
        sort(arr.begin(), arr.end());
        rowDiff.push_back(arr[1] - arr[0]);
    }
 
    for (int col = 0; col < grid[0].size(); col++) {
        vector<int> arr;
        for (int i = 0; i < grid.size(); i++) {
            arr.push_back(grid[i][col]);
        }
        sort(arr.begin(), arr.end());
        colDiff.push_back(arr[1] - arr[0]);
    }
 
    return make_pair(rowDiff, colDiff);
}
 
int main() {
    vector<vector<int>> grid = {
        {3, 1, 7, 4},
        {2, 6, 5, 9},
        {8, 3, 3, 2}
    };
    vector<int> supply = {300, 400, 500};
    vector<int> demand = {250, 350, 400, 200};
    int n = grid.size();
    int m = grid[0].size();
    int ans = 0;
 
    while (*max_element(supply.begin(), supply.end()) != 0 || *max_element(demand.begin(), demand.end()) != 0) {
        pair<vector<int>, vector<int>> diffs = findDiff(grid);
        vector<int> row = diffs.first;
        vector<int> col = diffs.second;
 
        int maxi1 = *max_element(row.begin(), row.end());
        int maxi2 = *max_element(col.begin(), col.end());
 
        if (maxi1 >= maxi2) {
            for (int ind = 0; ind < row.size(); ind++) {
                if (row[ind] == maxi1) {
                    int mini1 = *min_element(grid[ind].begin(), grid[ind].end());
                    for (int ind2 = 0; ind2 < grid[ind].size(); ind2++) {
                        if (grid[ind][ind2] == mini1) {
                            int mini2 = min(supply[ind], demand[ind2]);
                            ans += mini2 * mini1;
                            supply[ind] -= mini2;
                            demand[ind2] -= mini2;
 
                            if (demand[ind2] == 0) {
                                for (int r = 0; r < n; r++) {
                                    grid[r][ind2] = INF;
                                }
                            } else {
                                fill(grid[ind].begin(), grid[ind].end(), INF);
                            }
                            break;
                        }
                    }
                    break;
                }
            }
        } else {
            for (int ind = 0; ind < col.size(); ind++) {
                if (col[ind] == maxi2) {
                    int mini1 = INF;
                    for (int j = 0; j < n; j++) {
                        mini1 = min(mini1, grid[j][ind]);
                    }
 
                    for (int ind2 = 0; ind2 < n; ind2++) {
                        if (grid[ind2][ind] == mini1) {
                            int mini2 = min(supply[ind2], demand[ind]);
                            ans += mini2 * mini1;
                            supply[ind2] -= mini2;
                            demand[ind] -= mini2;
 
                            if (demand[ind] == 0) {
                                for (int r = 0; r < n; r++) {
                                    grid[r][ind] = INF;
                                }
                            } else {
                                fill(grid[ind2].begin(), grid[ind2].end(), INF);
                            }
                            break;
                        }
                    }
                    break;
                }
            }
        }
    }
 
    cout << "The basic feasible solution is " << ans << endl;
    return 0;
}




import java.util.Arrays;
 
public class TransportationProblem {
 
    static int INF = 1000;
 
    public static void main(String[] args) {
        // Input data: grid, supply, and demand
        int[][] grid = {{3, 1, 7, 4}, {2, 6, 5, 9}, {8, 3, 3, 2}};
        int[] supply = {300, 400, 500};
        int[] demand = {250, 350, 400, 200};
 
        // Solve the transportation problem and print the result
        int ans = solveTransportationProblem(grid, supply, demand);
        System.out.println("The basic feasible solution is " + ans);
    }
 
    // Function to solve the transportation problem
    public static int solveTransportationProblem(int[][] grid, int[] supply, int[] demand) {
        int n = grid.length;  // Number of rows
        int m = grid[0].length;  // Number of columns
        int ans = 0// Initialize the answer
 
        // Loop until supply and demand are exhausted
        while (!isEmpty(supply) && !isEmpty(demand)) {
            int[] rowDiff = new int[n];  // Array to store row differences
            int[] colDiff = new int[m];  // Array to store column differences
 
            // Calculate row and column differences
            findDiff(grid, rowDiff, colDiff);
 
            // Find maximum differences in rows and columns
            int maxi1 = Arrays.stream(rowDiff).max().getAsInt();
            int maxi2 = Arrays.stream(colDiff).max().getAsInt();
 
            // Check whether the maximum row difference is greater than or equal to the maximum column difference
            if (maxi1 >= maxi2) {
                for (int i = 0; i < n; i++) {
                    if (rowDiff[i] == maxi1) {
                        int mini1 = Arrays.stream(grid[i]).min().getAsInt();  // Find minimum element in the row
                        for (int j = 0; j < m; j++) {
                            if (grid[i][j] == mini1) {
                                int mini2 = Math.min(supply[i], demand[j]);  // Calculate the minimum of supply and demand
                                ans += mini2 * mini1;  // Update the answer
                                supply[i] -= mini2;  // Adjust supply and demand
                                demand[j] -= mini2;
                                if (demand[j] == 0) {
                                    for (int r = 0; r < n; r++) {
                                        grid[r][j] = INF;  // Mark the entire column as exhausted
                                    }
                                } else {
                                    Arrays.fill(grid[i], INF);  // Mark the entire row as exhausted
                                }
                                break;
                            }
                        }
                        break;
                    }
                }
            } else {
                // If the maximum column difference is greater
                for (int j = 0; j < m; j++) {
                    if (colDiff[j] == maxi2) {
                        int mini1 = INF;
                        for (int[] ints : grid) {
                            mini1 = Math.min(mini1, ints[j]);  // Find the minimum element in the column
                        }
 
                        for (int i = 0; i < n; i++) {
                            int val2 = grid[i][j];
                            if (val2 == mini1) {
                                int mini2 = Math.min(supply[i], demand[j]);  // Calculate the minimum of supply and demand
                                ans += mini2 * mini1;  // Update the answer
                                supply[i] -= mini2;  // Adjust supply and demand
                                demand[j] -= mini2;
                                if (demand[j] == 0) {
                                    for (int r = 0; r < n; r++) {
                                        grid[r][j] = INF;  // Mark the entire column as exhausted
                                    }
                                } else {
                                    Arrays.fill(grid[i], INF);  // Mark the entire row as exhausted
                                }
                                break;
                            }
                        }
                        break;
                    }
                }
            }
        }
        return ans;  // Return the final answer
    }
 
    // Function to check if an array is empty
    public static boolean isEmpty(int[] array) {
        for (int value : array) {
            if (value != 0) {
                return false;
            }
        }
        return true;
    }
 
    // Function to calculate row and column differences in the grid
    public static void findDiff(int[][] grid, int[] rowDiff, int[] colDiff) {
        for (int i = 0; i < grid.length; i++) {
            int[] arr = Arrays.copyOf(grid[i], grid[i].length);  // Copy the row
            Arrays.sort(arr);  // Sort the row
            rowDiff[i] = arr[1] - arr[0];  // Calculate row difference
        }
 
        for (int col = 0; col < grid[0].length; col++) {
            int[] arr = new int[grid.length];
            for (int i = 0; i < grid.length; i++) {
                arr[i] = grid[i][col];  // Collect elements from the column
            }
            Arrays.sort(arr);  // Sort the column elements
            colDiff[col] = arr[1] - arr[0];  // Calculate column difference
        }
    }
}




grid = [[3, 1, 7, 4], [2, 6, 5, 9], [8, 3, 3, 2]]  # table
supply = [300, 400, 500# supply
demand = [250, 350, 400, 200# demand
INF = 10**3
n = len(grid)
m = len(grid[0])
ans = 0
 
# hepler function for finding the row difference and the column difference
def findDiff(grid):
    rowDiff = []
    colDiff = []
    for i in range(len(grid)):
        arr = grid[i][:]
        arr.sort()
        rowDiff.append(arr[1]-arr[0])
    col = 0
    while col < len(grid[0]):
        arr = []
        for i in range(len(grid)):
            arr.append(grid[i][col])
        arr.sort()
        col += 1
        colDiff.append(arr[1]-arr[0])
    return rowDiff, colDiff
 
 
# loop runs until both the demand and the supply is exhausted
while max(supply) != 0 or max(demand) != 0:
    # finding the row and col difference
    row, col = findDiff(grid)
    # finding the maxiumum element in row difference array
    maxi1 = max(row)
    # finding the maxiumum element in col difference array
    maxi2 = max(col)
 
    # if the row diff max element is greater than or equal to col diff max element
    if(maxi1 >= maxi2):
        for ind, val in enumerate(row):
            if(val == maxi1):
                # finding the minimum element in grid index where the maximum was found in the row difference
                mini1 = min(grid[ind])
                for ind2, val2 in enumerate(grid[ind]):
                    if(val2 == mini1):
                        # calculating the min of supply and demand in that row and col
                        mini2 = min(supply[ind], demand[ind2])
                        ans += mini2 * mini1
                        # subtracting the min from the supply and demand
                        supply[ind] -= mini2
                        demand[ind2] -= mini2
                        # if demand is smaller then the entire col is assigned max value so that the col is eliminated for the next iteration
                        if(demand[ind2] == 0):
                            for r in range(n):
                                grid[r][ind2] = INF
                        # if supply is smaller then the entire row is assigned max value so that the row is eliminated for the next iteration
                        else:
                            grid[ind] = [INF for i in range(m)]
                        break
                break
    # if the row diff max element is greater than col diff max element
    else:
        for ind, val in enumerate(col):
            if(val == maxi2):
                # finding the minimum element in grid index where the maximum was found in the col difference
                mini1 = INF
                for j in range(n):
                    mini1 = min(mini1, grid[j][ind])
 
                for ind2 in range(n):
                    val2 = grid[ind2][ind]
                    if val2 == mini1:
                        # calculating the min of supply and demand in that row and col
                        mini2 = min(supply[ind2], demand[ind])
                        ans += mini2 * mini1
                        # subtracting the min from the supply and demand
                        supply[ind2] -= mini2
                        demand[ind] -= mini2
                        # if demand is smaller then the entire col is assigned max value so that the col is eliminated for the next iteration
                        if(demand[ind] == 0):
                            for r in range(n):
                                grid[r][ind] = INF
                        # if supply is smaller then the entire row is assigned max value so that the row is eliminated for the next iteration
                        else:
                            grid[ind2] = [INF for i in range(m)]
                        break
                break
 
print("The basic feasible solution is ", ans)




using System;
using System.Collections.Generic;
using System.Linq;
 
class Program
{
    const int INF = 1000;
 
    static Tuple<List<int>, List<int>> FindDiff(List<List<int>> grid)
    {
        List<int> rowDiff = new List<int>();
        List<int> colDiff = new List<int>();
 
        for (int i = 0; i < grid.Count; i++)
        {
            List<int> arr = grid[i].OrderBy(x => x).ToList();
            rowDiff.Add(arr[1] - arr[0]);
        }
 
        for (int col = 0; col < grid[0].Count; col++)
        {
            List<int> arr = new List<int>();
            for (int i = 0; i < grid.Count; i++)
            {
                arr.Add(grid[i][col]);
            }
            arr.Sort();
            colDiff.Add(arr[1] - arr[0]);
        }
 
        return Tuple.Create(rowDiff, colDiff);
    }
 
    static void Main()
    {
        List<List<int>> grid = new List<List<int>>
        {
            new List<int> {3, 1, 7, 4},
            new List<int> {2, 6, 5, 9},
            new List<int> {8, 3, 3, 2}
        };
        List<int> supply = new List<int> { 300, 400, 500 };
        List<int> demand = new List<int> { 250, 350, 400, 200 };
        int n = grid.Count;
        int m = grid[0].Count;
        int ans = 0;
 
        while (supply.Any(s => s > 0) && demand.Any(d => d > 0))
        {
            Tuple<List<int>, List<int>> diffs = FindDiff(grid);
            List<int> row = diffs.Item1;
            List<int> col = diffs.Item2;
 
            int maxi1 = row.Max();
            int maxi2 = col.Max();
 
            if (maxi1 >= maxi2)
            {
                int ind = row.FindIndex(r => r == maxi1);
                int ind2 = grid[ind].IndexOf(grid[ind].Min());
 
                int mini2 = Math.Min(supply[ind], demand[ind2]);
                ans += mini2 * grid[ind][ind2];
                supply[ind] -= mini2;
                demand[ind2] -= mini2;
 
                if (demand[ind2] == 0)
                {
                    grid.ForEach(r => r[ind2] = INF);
                }
                else
                {
                    grid[ind].Fill(INF);
                }
            }
            else
            {
                int ind = col.FindIndex(c => c == maxi2);
                int mini1 = grid.Min(r => r[ind]);
 
                int ind2 = grid.FindIndex(r => r[ind] == mini1);
 
                int mini2 = Math.Min(supply[ind2], demand[ind]);
                ans += mini2 * mini1;
                supply[ind2] -= mini2;
                demand[ind] -= mini2;
 
                if (demand[ind] == 0)
                {
                    grid.ForEach(r => r[ind] = INF);
                }
                else
                {
                    grid[ind2].Fill(INF);
                }
            }
        }
 
        Console.WriteLine("The basic feasible solution is " + ans);
    }
}
 
public static class Extensions
{
    public static void Fill<T>(this List<T> list, T value)
    {
        for (int i = 0; i < list.Count; i++)
        {
            list[i] = value;
        }
    }
}




let grid = [
  [3, 1, 7, 4],
  [2, 6, 5, 9],
  [8, 3, 3, 2]
]; // table
let supply = [300, 400, 500]; // supply
let demand = [250, 350, 400, 200]; // demand
const INF = 10 ** 3;
let n = grid.length;
let m = grid[0].length;
let ans = 0;
 
// Helper function for finding the row difference and the column difference
function findDiff(grid) {
  let rowDiff = [];
  let colDiff = [];
  for (let i = 0; i < grid.length; i++) {
    let arr = [...grid[i]];
    arr.sort((a, b) => a - b);
    rowDiff.push(arr[1] - arr[0]);
  }
 
  for (let col = 0; col < grid[0].length; col++) {
    let arr = [];
    for (let i = 0; i < grid.length; i++) {
      arr.push(grid[i][col]);
    }
    arr.sort((a, b) => a - b);
    colDiff.push(arr[1] - arr[0]);
  }
 
  return [rowDiff, colDiff];
}
 
// Loop runs until both the demand and the supply are exhausted
while (Math.max(...supply) !== 0 || Math.max(...demand) !== 0) {
  // Finding the row and col difference
  let [row, col] = findDiff(grid);
 
  // Finding the maximum element in row difference array
  let maxi1 = Math.max(...row);
 
  // Finding the maximum element in col difference array
  let maxi2 = Math.max(...col);
 
  // If the row diff max element is greater than or equal to col diff max element
  if (maxi1 >= maxi2) {
    for (let ind = 0; ind < row.length; ind++) {
      if (row[ind] === maxi1) {
        let mini1 = Math.min(...grid[ind]);
        for (let ind2 = 0; ind2 < grid[ind].length; ind2++) {
          if (grid[ind][ind2] === mini1) {
            let mini2 = Math.min(supply[ind], demand[ind2]);
            ans += mini2 * mini1;
            supply[ind] -= mini2;
            demand[ind2] -= mini2;
 
            if (demand[ind2] === 0) {
              for (let r = 0; r < n; r++) {
                grid[r][ind2] = INF;
              }
            } else {
              grid[ind] = new Array(m).fill(INF);
            }
            break;
          }
        }
        break;
      }
    }
  } else {
    for (let ind = 0; ind < col.length; ind++) {
      if (col[ind] === maxi2) {
        let mini1 = INF;
        for (let j = 0; j < n; j++) {
          mini1 = Math.min(mini1, grid[j][ind]);
        }
 
        for (let ind2 = 0; ind2 < n; ind2++) {
          if (grid[ind2][ind] === mini1) {
            let mini2 = Math.min(supply[ind2], demand[ind]);
            ans += mini2 * mini1;
            supply[ind2] -= mini2;
            demand[ind] -= mini2;
 
            if (demand[ind] === 0) {
              for (let r = 0; r < n; r++) {
                grid[r][ind] = INF;
              }
            } else {
              grid[ind2] = new Array(m).fill(INF);
            }
            break;
          }
        }
        break;
      }
    }
  }
}
 
console.log("The basic feasible solution is ", ans);

Output
The basic feasible solution is 2850

Article Tags :