param nBlocks;
param nLoads;
param nDests;
param nNodes;

set Blocks, default{1.. nBlocks};
set Loads, default{1.. nLoads};
set Dests, default{1.. nDests};
set Nodes, default{1.. nNodes};

param Block_ID{b in Blocks}, symbolic;
param Block_Node{b in Blocks}, symbolic;
param Block_VC{b in Blocks}, default 0;

param Load_ID{l in Loads}, symbolic;

set BlockLoads, within Blocks cross Loads;
param LoadVol{(b,l) in BlockLoads}, default 0;

param Dest_ID{d in Dests}, symbolic;
param Dest_Node{d in Dests}, symbolic;

param Node_ID{n in Nodes}, symbolic;

set DestLoads, within Dests cross Loads;
param DL_Rev{(d,l) in DestLoads}, default 0;

set TransNet, within Nodes cross Nodes;
set TransNetLoads, within Nodes cross Nodes cross Loads;

param Trans_Cost{(n1,n2) in TransNet}, default 0;

set BlockNodeLoads:=setof{b in Blocks, n in Nodes, l in Loads: (Node_ID[n]=Block_Node[b])} (b,n,l);
set DestNodeLoads:=setof{d in Dests, n in Nodes, l in Loads: (Node_ID[n]=Dest_Node[d])} (d,n,l);
set DestNodes:= setof{(d,n,l) in DestNodeLoads} (d,n);

var Qbn{(b,n,l) in BlockNodeLoads}, >=0;
var Qbu{(b,l) in BlockLoads}, >=0;
var Qnn{(n1,n2,l) in TransNetLoads}, >=0;
var Qnd{(d,n,l) in DestNodeLoads}, >=0;
var Qdl{(d,l) in DestLoads}, >=0;
var Qd{d in Dests}, >=0;

var ProductRev, >=0;
var VarCost, >=0;
var TranCost, >=0;
var NetIncome;

table tab_blocks IN "CSV" "Blocks.csv" :
  Blocks <- [Block_ID], Block_Node ~ Node_ID, Block_VC ~ Block_VC;
  
table tab_loads IN "CSV" "Loads.csv" :
  Loads <- [Load_ID];

table tab_blockloads IN "CSV" "BlockLoads.csv" :
  BlockLoads <- [Block_ID, Load_ID], LoadVol ~ Volume;

table tab_dests IN "CSV" "Dests.csv" :
  Dests <- [Dest_ID], Dest_Node ~ Node_ID;
  
table tab_nodes IN "CSV" "Nodes.csv" :
  Nodes <- [Node_ID];

table tab_destloads IN "CSV" "DestLoads.csv" :
  DestLoads <- [Dest_ID, Load_ID], DL_Rev ~ Rev;

table tab_transnetwork IN "CSV" "TransNetwork.csv" :
  TransNet <- [From_ID, To_ID], Trans_Cost ~ Cost;

table tab_transnetworkLoads IN "CSV" "TransNetworkLoads.csv" :
  TransNetLoads <- [From_ID, To_ID, Load_ID];

maximize obj: NetIncome;

s.t. NetIncomeCalc: NetIncome = ProductRev - VarCost - TranCost;

s.t. ProdRev: sum{d in Dests} sum{l in Loads:(d,l) in DestLoads} DL_Rev[d,l] * Qdl[d,l] = ProductRev;

s.t. TransportCost: sum{(n1,n2,l) in TransNetLoads} Trans_Cost[n1,n2] * Qnn[n1,n2,l] = TranCost; 

s.t. CostVar: sum{(b,n,l) in BlockNodeLoads} Qbn[b,n,l] * Block_VC[b] + sum{(b,l) in BlockLoads} Qbu[b,l] * Block_VC[b] = VarCost; 

s.t. MatchVol{(b,l) in BlockLoads}: sum{n in Nodes: (b,n,l) in BlockNodeLoads} Qbn[b,n,l] + Qbu[b,l] =  LoadVol[b,l]; 

s.t. NodeInOut{n in Nodes, l in Loads}: sum{b in Blocks: (b,n,l) in BlockNodeLoads} Qbn[b,n,l] + sum{n1 in Nodes: (n1,n,l) in TransNetLoads} Qnn[n1,n,l] - sum{n2 in Nodes: (n,n2,l) in TransNetLoads} Qnn[n,n2,l] - sum{d in Dests: (d,n,l) in DestNodeLoads} Qnd[d,n,l] = 0;

s.t. DestLoadNode{(d,l) in DestLoads}: sum{n in Nodes: (d,n) in DestNodes} Qnd[d,n,l] = Qdl[d,l];

s.t. DestLoadNode2{d in Dests}: sum{n in Nodes: (d,n) in DestNodes} sum{l in Loads} Qnd[d,n,l] = Qd[d]; 

solve;

printf """ "",""%s"",""%s"",%f\n","","Manuf. Var.",ProductRev;
printf "\n";

printf """Qbn""\n";
printf{(b,n,l) in BlockNodeLoads: Qbn[b,n,l]!=0} """%d"", ""%d"",""%d"",%f\n", Block_ID[b], Node_ID[n], Load_ID[l], Qbn[b,n,l];

printf """Qnn""\n";
printf{(n1,n2,l) in TransNetLoads: Qnn[n1,n2,l]!=0} """%d"", ""%d"",""%d"",%f\n", Node_ID[n1], Node_ID[n2], Load_ID[l],Qnn[n1,n2,l];

printf """Qnd""\n";
printf{(d,n) in DestNodes, l in Loads: Qnd[d,n,l]!=0} """%d"", ""%d"",""%d"",%f\n", Dest_ID[d], Node_ID[n], Load_ID[l], Qnd[d,n,l];

end;
