Open In App

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

Improve
Improve
Like Article
Like
Save
Share
Report

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:

  • For each row find the least value and then the second least value and take the absolute difference of these two least values and write it in the corresponding row difference as shown in the image below. In row O1, 1 is the least value and 3 is the second least value and their absolute difference is 2. Similarly, for row O2 and O3, the absolute differences are 3 and 1 respectively.
  • For each column find the least value and then the second least value and take the absolute difference of these two least values then write it in the corresponding column difference as shown in the figure. In column D1, 2 is the least value and 3 is the second least value and their absolute difference is 1. Similarly, for column D2, D3 and D3, the absolute differences are 2, 2 and 2 respectively.
  • These value of row difference and column difference are also called as penalty. Now select the maximum penalty. The maximum penalty is 3 i.e. row O2. Now find the cell with the least cost in row O2 and allocate the minimum among the supply of the respective row and the demand of the respective column. Demand is smaller than the supply so allocate the column’s demand i.e. 250 to the cell. Then cancel the column D1.
  • From the remaining cells, find out the row difference and column difference.
  • Again select the maximum penalty which is 3 corresponding to row O1. The least-cost cell in row O1 is (O1, D2) with cost 1. Allocate the minimum among supply and demand from the respective row and column to the cell. Cancel the row or column with zero value.
  • Now find the row difference and column difference from the remaining cells.
  • Now select the maximum penalty which is 7 corresponding to column D4. The least cost cell in column D4 is (O3, D4) with cost 2. The demand is smaller than the supply for cell (O3, D4). Allocate 200 to the cell and cancel the column.
  • Find the row difference and the column difference from the remaining cells.
  • Now the maximum penalty is 3 corresponding to the column D2. The cell with the least value in D2 is (O3, D2). Allocate the minimum of supply and demand and cancel the column.
  • Now there is only one column so select the cell with the least cost and allocate the value.
  • Now there is only one cell so allocate the remaining demand or supply to the cell
  • No balance remains. So multiply the allocated value of the cells with their corresponding cell cost and add all to get the final cost i.e. (300 * 1) + (250 * 2) + (50 * 3) + (250 * 3) + (200 * 2) + (150 * 5) = 2850

Below is the implementation for the approach discussed above

C++




#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;
}


Java




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
        }
    }
}


Python3




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)


C#




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;
        }
    }
}


Javascript




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


Last Updated : 21 Dec, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads