/* nag_transport (h03abc) Example Program.
 *
 * Copyright 2017 Numerical Algorithms Group.
 *
 * Mark 26.1, 2017.
 *
 *
 */

#include <nag.h>
#include <stdio.h>
#include <nag_stdlib.h>
#include <nagh03.h>

#define COST(I, J) cost[(I) *tdcost + J]
int main(void)
{

  Integer *dest = 0, exit_status = 0, i, m, maxit, navail, nreq, numit;
  Integer *source = 0;
  Integer tdcost;
  NagError fail;
  double *avail = 0, *cost = 0, optcost, *optq = 0, *req = 0, *unitcost = 0;

  INIT_FAIL(fail);

  printf("nag_transport (h03abc) Example Program Results\n");
  navail = 3;
  nreq = 3;
  m = navail + nreq;

  if (!(cost = NAG_ALLOC(navail * nreq, double)) ||
      !(avail = NAG_ALLOC(navail, double)) ||
      !(req = NAG_ALLOC(nreq, double)) ||
      !(optq = NAG_ALLOC(navail + nreq, double)) ||
      !(unitcost = NAG_ALLOC(navail + nreq, double)) ||
      !(source = NAG_ALLOC(navail + nreq, Integer)) ||
      !(dest = NAG_ALLOC(navail + nreq, Integer)))
  {
    printf("Allocation failure\n");
    exit_status = -1;
    goto END;
  }
  tdcost = nreq;

  COST(0, 0) = 8.0;
  COST(0, 1) = 8.0;
  COST(0, 2) = 11.0;
  COST(1, 0) = 5.0;
  COST(1, 1) = 8.0;
  COST(1, 2) = 14.0;
  COST(2, 0) = 4.0;
  COST(2, 1) = 3.0;
  COST(2, 2) = 10.0;

  avail[0] = 1.0;
  avail[1] = 5.0;
  avail[2] = 6.0;

  req[0] = 4.0;
  req[1] = 4.0;
  req[2] = 4.0;

  maxit = 200;

  /* nag_transport (h03abc).
   * Classical transportation algorithm
   */
  nag_transport(cost, tdcost, avail, navail, req, nreq, maxit, &numit,
                optq, source, dest, &optcost, unitcost, &fail);
  if (fail.code != NE_NOERROR) {
    printf("Error from nag_transport (h03abc).\n%s\n", fail.message);
    exit_status = 1;
    goto END;
  }

  printf("\nGoods From     To      Number        Cost per Unit\n");
  for (i = 0; i < m - 1; i++)
    printf("   %" NAG_IFMT "            %" NAG_IFMT
           "    %8.3f         %8.3f\n", source[i], dest[i], optq[i],
           unitcost[i]);
  printf("\nTotal Cost %8.4f\n", optcost);
END:
  NAG_FREE(cost);
  NAG_FREE(avail);
  NAG_FREE(req);
  NAG_FREE(optq);
  NAG_FREE(unitcost);
  NAG_FREE(source);
  NAG_FREE(dest);
  return exit_status;
}