Vogel's Approximation Method (VAM) is a technique for finding a good initial feasible solution to an allocation problem.

The powers that be have identified 5 tasks that need to be solved urgently. Being imaginative chaps, they have called them “A”, “B”, “C”, “D”, and “E”. They estimate that:

 A will require 30 hours of work,
 B will require 20 hours of work,
 C will require 70 hours of work,
 D will require 30 hours of work, and
 E will require 60 hours of work.
They have identified 4 contractors willing to do the work, called “W”, “X”, “Y”, and “Z”.

 W has 50 hours available to commit to working,
 X has 60 hours available,
 Y has 50 hours available, and
 Z has 50 hours available.
The cost per hour for each contractor for each task is summarized by the following table:

   A  B  C  D  E
W 16 16 13 22 17
X 14 14 13 19 15
Y 19 19 20 23 50
Z 50 12 50 15 11

The task is to use VAM to allocate contractors to tasks. It scales to large problems, so ideally keep sorts out of the iterative cycle. It works as follows:

Step 1: Balance the given transportation problem if either (total supply>total demand) or (total supply<total demand)
Step 2: Determine the penalty cost for each row and column by subtracting the lowest cell cost in the row or column from the next lowest cell cost in the same row or column.
Step 3: Select the row or column with the highest penalty cost (breaking ties arbitrarily or choosing the lowest-cost cell).
Step 4: Allocate as much as possible to the feasible cell with the lowest transportation cost in the row or column with the highest penalty cost.
Step 5: Repeat steps 2, 3 and 4 until all requirements have been meet.
Step 6: Compute total transportation cost for the feasible allocations.
For this task assume that the model is balanced.

For each task and contractor (row and column above) calculating the difference between the smallest two values produces:

        A       B       C       D       E       W       X       Y       Z
1       2       2       0       4       4       3       1       0       1   E-Z(50)

Determine the largest difference (D or E above). In the case of ties I shall choose the one with the lowest price (in this case E because the lowest price for D is Z=15, whereas for E it is Z=11). For your choice determine the minimum cost (chosen E above so Z=11 is chosen now). Allocate as much as possible from Z to E (50 in this case limited by Z's supply).
Adjust the supply and demand accordingly. If demand or supply becomes 0 for a given task or contractor it plays no further part. In this case Z is out of it. If you choose arbitrarily, and chose D see here for the working.

Repeat until all supply and demand is met:

2       2       2       0       3       2       3       1       0       -   C-W(50)
3       5       5       7       4      35       -       1       0       -   E-X(10)
4       5       5       7       4       -       -       1       0       -   C-X(20)
5       5       5       -       4       -       -       0       0       -   A-X(30)
6       -      19       -      23       -       -       -       4       -   D-Y(30)
        -       -       -       -       -       -       -       -       -   B-Y(20)

Finally calculate the cost of your solution. In the example given it is £3100:

   A  B  C  D  E
W       50
X 30    20    10
Y    20    30
Z             50

The optimal solution determined by GLPK is £3100:

   A  B  C  D  E
W       50
X 10 20 20    10
Y 20       30
Z             50

Cf.
 Transportation problem
 
N_ROWS = 4 : N_COLS = 5
 
dim supply(N_ROWS)
dim demand(N_COLS)
 
restore sup
for n = 0 to N_ROWS - 1
	read supply(n)
next n
 
restore dem
for n = 0 to N_COLS - 1
	read demand(n)
next n
 
label sup
data 50, 60, 50, 50
 
label dem
data 30, 20, 70, 30, 60
 
dim costs(N_ROWS, N_COLS)
 
label cost
data 16, 16, 13, 22, 17
data 14, 14, 13, 19, 15
data 19, 19, 20, 23, 50
data 50, 12, 50, 15, 11
 
restore cost
for i = 0 to N_ROWS - 1
	for j = 0 to N_COLS - 1
		read costs(i, j)
	next j
next i
 
dim row_done(N_ROWS)
dim col_done(N_COLS)
 
sub diff(j, leng, is_row, res())
    local i, c, min1, min2, min_p, test
 
    min1 = 10e300 : min2 = min1 : min_p = -1
 
    for i = 0 to leng - 1
    	if is_row then
    		test = col_done(i)
    	else
    		test = row_done(i)
    	end if
    	if test continue
    	if is_row then
    		c = costs(j, i)
    	else
    		c = costs(i, j)
    	end if
        if c < min1 then
            min2 = min1
            min1 = c
            min_p = i
        elseif c < min2 then
        	min2 = c
        end if
    next i
    res(0) = min2 - min1
    res(1) = min1
    res(2) = min_p
end sub
 
sub max_penalty(len1, len2, is_row, res())
    local i, pc, pm, mc, md, res2(3), test
 
    pc = -1 : pm = -1 : mc = -1 : md = -10e300
 
    for i = 0 to len1 - 1
        if is_row then
    		test = row_done(i)
    	else
    		test = col_done(i)
    	end if
        if test continue
       	diff(i, len2, is_row, res2())
        if res2(0) > md then
            md = res2(0)  //* max diff */
            pm = i        //* pos of max diff */
            mc = res2(1)  //* min cost */
            pc = res2(2)  //* pos of min cost */
        end if
    next i
 
    if is_row then
        res(0) = pm : res(1) = pc
    else
        res(0) = pc : res(1) = pm
    end if
    res(2) = mc : res(3) = md
end sub
 
sub next_cell(res())
    local i, res1(4), res2(4)
 
    max_penalty(N_ROWS, N_COLS, TRUE, res1())
    max_penalty(N_COLS, N_ROWS, FALSE, res2())
 
    if res1(3) = res2(3) then
        if res1(2) < res2(2) then
            for i = 0 to 3 : res(i) = res1(i) : next i
        else
            for i = 0 to 3 : res(i) = res2(i) : next i
        end if
        return
    end if
    if res1(3) > res2(3) then
        for i = 0 to 3 : res(i) = res2(i) : next i
    else
        for i = 0 to 3 : res(i) = res1(i) : next i
    end if
end sub
 
supply_left = 0 : total_cost = 0 : dim cell(4)
 
dim results(N_ROWS, N_COLS)
 
for i = 0 to N_ROWS - 1 : supply_left = supply_left + supply(i) : next i
 
while(supply_left > 0)
    next_cell(cell())
    r = cell(0)
    c = cell(1)
    q = min(demand(c), supply(r)) 
    demand(c) = demand(c) - q
    if not demand(c) col_done(c) = TRUE
    supply(r) = supply(r) - q
    if not supply(r) row_done(r) = TRUE
    results(r, c) = q
    supply_left = supply_left - q
    total_cost = total_cost + q * costs(r, c)
wend
 
print "    A   B   C   D   E\n"
for i = 0 to N_ROWS - 1
    print chr$(asc("W") + i), " ";
    for j = 0 to N_COLS - 1
    	print results(i, j) using "###";
    next j
    print
next i
print "\nTotal cost = ", total_cost