Task: Vogel's approximation method




Go: #include <stdio.h>
#include <limits.h>
 
#define TRUE 1
#define FALSE 0
#define N_ROWS 5
#define N_COLS 5
 
typedef int bool;
 
int supply[N_ROWS] = { 461, 277, 356, 488,  393 };
int demand[N_COLS] = { 278,  60, 461, 116, 1060 };
 
int costs[N_ROWS][N_COLS] = {
    { 46,  74,  9, 28, 99 },
    { 12,  75,  6, 36, 48 },
    { 35, 199,  4,  5, 71 },
    { 61,  81, 44, 88,  9 },
    { 85,  60, 14, 25, 79 }
};


 
int main() {
    

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


Java: import java.util.Arrays;
import static java.util.Arrays.stream;
import java.util.concurrent.*;

public class VogelsApproximationMethod {

    final static int[] demand = {30, 20, 70, 30, 60};
    final static int[] supply = {50, 60, 50, 50};
    final static int[][] costs = {{16, 16, 13, 22, 17}, {14, 14, 13, 19, 15},
    {19, 19, 20, 23, 50}, {50, 12, 50, 15, 11}};

    final static int nRows = supply.length;
    final static int nCols = demand.length;

    static boolean[] rowDone = new boolean[nRows];
    static boolean[] colDone = new boolean[nCols];
    static int[][] result = new int[nRows][nCols];

    static ExecutorService es = Executors.newFixedThreadPool(2);

    public static void main(String[] args) throws Exception {
        int supplyLeft = stream(supply).sum();
        int totalCost = 0;

        while (supplyLeft > 0) {
            int[] cell = nextCell();
            int r = cell[0];
            int c = cell[1];

            int quantity = Math.min(demand[c], supply[r]);
            demand[c] -= quantity;
            if (demand[c] == 0)
                colDone[c] = true;

            supply[r] -= quantity;
            if (supply[r] == 0)
                rowDone[r] = true;

            result[r][c] = quantity;
            supplyLeft -= quantity;

            totalCost += quantity * costs[r][c];
        }

        stream(result).forEach(a -> System.out.println(Arrays.toString(a)));
        System.out.println("Total cost: " + totalCost);

        es.shutdown();
    }

    static int[] nextCell() throws Exception {
        Future<int[]> f1 = es.submit(() -> maxPenalty(nRows, nCols, true));
        Future<int[]> f2 = es.submit(() -> maxPenalty(nCols, nRows, false));

        int[] res1 = f1.get();
        int[] res2 = f2.get();

        if (res1[3] == res2[3])
            return res1[2] < res2[2] ? res1 : res2;

        return (res1[3] > res2[3]) ? res2 : res1;
    }

    static int[] diff(int j, int len, boolean isRow) {
        int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
        int minP = -1;
        for (int i = 0; i < len; i++) {
            if (isRow ? colDone[i] : rowDone[i])
                continue;
            int c = isRow ? costs[j][i] : costs[i][j];
            if (c < min1) {
                min2 = min1;
                min1 = c;
                minP = i;
            } else if (c < min2)
                min2 = c;
        }
        return new int[]{min2 - min1, min1, minP};
    }

    static int[] maxPenalty(int len1, int len2, boolean isRow) {
        int md = Integer.MIN_VALUE;
        int pc = -1, pm = -1, mc = -1;
        for (int i = 0; i < len1; i++) {
            if (isRow ? rowDone[i] : colDone[i])
                continue;
            int[] res = diff(i, len2, isRow);
            if (res[0] > md) {
                md = res[0];  
                pm = i;       
                mc = res[1];  
                pc = res[2];  
            }
        }
        return isRow ? new int[]{pm, pc, mc, md} : new int[]{pc, pm, mc, md};
    }
}