Task: Vogel's approximation method

C: #include <stdio.h>
#include <limits.h>

#define TRUE 1
#define FALSE 0
#define N_ROWS 4
#define N_COLS 5

typedef int bool;

int supply[N_ROWS] = { 50, 60, 50, 50 };
int demand[N_COLS] = { 30, 20, 70, 30, 60 };

int costs[N_ROWS][N_COLS] = {
    { 16, 16, 13, 22, 17 },
    { 14, 14, 13, 19, 15 },
    { 19, 19, 20, 23, 50 },
    { 50, 12, 50, 15, 11 }
};

bool row_done[N_ROWS] = { FALSE };
bool col_done[N_COLS] = { FALSE };

void diff(int j, int len, bool is_row, int res[3]) {
    int i, c, min1 = INT_MAX, min2 = min1, min_p = -1;
    for (i = 0; i < len; ++i) {
        if((is_row) ? col_done[i] : row_done[i]) continue;
        c = (is_row) ? costs[j][i] : costs[i][j];
        if (c < min1) {
            min2 = min1;
            min1 = c;
            min_p = i;
        }
        else if (c < min2) min2 = c;
    }
    res[0] = min2 - min1; res[1] = min1; res[2] = min_p;
}

void max_penalty(int len1, int len2, bool is_row, int res[4]) {
    int i, pc = -1, pm = -1, mc = -1, md = INT_MIN;
    int res2[3];

    for (i = 0; i < len1; ++i) {
        if((is_row) ? row_done[i] : col_done[i]) continue;
        diff(i, len2, is_row, res2);
        if (res2[0] > md) {
            md = res2[0];  
            pm = i;        
            mc = res2[1];  
            pc = res2[2];  
        }
    }

    if (is_row) {
        res[0] = pm; res[1] = pc;
    }
    else {
        res[0] = pc; res[1] = pm;
    }
    res[2] = mc; res[3] = md;
}

void next_cell(int res[4]) {
    int 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]) {
        if (res1[2] < res2[2])
            for (i = 0; i < 4; ++i) res[i] = res1[i];
        else
            for (i = 0; i < 4; ++i) res[i] = res2[i];
        return;
    }
    if (res1[3] > res2[3])
        for (i = 0; i < 4; ++i) res[i] = res2[i];
    else
        for (i = 0; i < 4; ++i) res[i] = res1[i];
}

int main() {
    int i, j, r, c, q, supply_left = 0, total_cost = 0, cell[4];
    int results[N_ROWS][N_COLS] = { 0 };

    for (i = 0; i < N_ROWS; ++i) supply_left += supply[i];
    while (supply_left > 0) {
        next_cell(cell);
        r = cell[0];
        c = cell[1];
        q = (demand[c] <= supply[r]) ? demand[c] : supply[r];
        demand[c] -= q;
        if (!demand[c]) col_done[c] = TRUE;
        supply[r] -= q;
        if (!supply[r]) row_done[r] = TRUE;
        results[r][c] = q;
        supply_left -= q;
        total_cost += q * costs[r][c];
    }

    printf("    A   B   C   D   E\n");
    for (i = 0; i < N_ROWS; ++i) {
        printf("%c", 'W' + i);
        for (j = 0; j < N_COLS; ++j) printf("  %2d", results[i][j]);
        printf("\n");
    }
    printf("\nTotal cost = %d\n", total_cost);
    return 0;
}







Python: from collections import defaultdict

costs  = {'W': {'A': 16, 'B': 16, 'C': 13, 'D': 22, 'E': 17},
          'X': {'A': 14, 'B': 14, 'C': 13, 'D': 19, 'E': 15},
          'Y': {'A': 19, 'B': 19, 'C': 20, 'D': 23, 'E': 50},
          'Z': {'A': 50, 'B': 12, 'C': 50, 'D': 15, 'E': 11}}
demand = {'A': 30, 'B': 20, 'C': 70, 'D': 30, 'E': 60}
cols = sorted(demand.iterkeys())
supply = {'W': 50, 'X': 60, 'Y': 50, 'Z': 50}
res = dict((k, defaultdict(int)) for k in costs)
g = {}
for x in supply:
    g[x] = sorted(costs[x].iterkeys(), key=lambda g: costs[x][g])
for x in demand:
    g[x] = sorted(costs.iterkeys(), key=lambda g: costs[g][x])

while g:
    d = {}
    for x in demand:
        d[x] = (costs[g[x][1]][x] - costs[g[x][0]][x]) if len(g[x]) > 1 else costs[g[x][0]][x]
    s = {}
    for x in supply:
        s[x] = (costs[x][g[x][1]] - costs[x][g[x][0]]) if len(g[x]) > 1 else costs[x][g[x][0]]
    f = max(d, key=lambda n: d[n])
    t = max(s, key=lambda n: s[n])
    t, f = (f, g[f][0]) if d[f] > s[t] else (g[t][0], t)
    v = min(supply[f], demand[t])
    res[f][t] += v
    demand[t] -= v
    if demand[t] == 0:
        for k, n in supply.iteritems():
            if n != 0:
                g[k].remove(t)
        del g[t]
        del demand[t]
    supply[f] -= v
    if supply[f] == 0:
        for k, n in demand.iteritems():
            if n != 0:
                g[k].remove(f)
        del g[f]
        del supply[f]

for n in cols:
    print "\t", n,
print
cost = 0
for g in sorted(costs):
    print g, "\t",
    for n in cols:
        y = res[g][n]
        if y != 0:
            print y,
        cost += y * costs[g][n]
        print "\t",
    print
print "\n\nTotal Cost = ", cost