/*
DplyTrackside: Use of binary variables to assign sensors.
Given a fixed train speed and a relationship between probability of successful
communications between sensors and trackside readers the objective here is to
place readers trackside, and determine optimal sensor transmission ranges and
sensor read times, and to assign sensors to containers on a train such that the
cargo monitoring cost metric (which includes the rate of theft, probability of
detection, successful communications and false alarm.) is minimized. The
constraints capture valid sensor placements.
*/

set UNIT;	# Railcars
set CNTNR;	# Containers
set COMMDEV;	# Sensors
set SLOT;	# Slots

param len {CNTNR} >= 0 ;		# Length of container in metres
param UnitLen {UNIT} >= 0 ;		# Length of railcars in metres
param lambda {COMMDEV} >=0 ;		# Msg generation rate for comms device in msgs/hour
param sav {CNTNR} >= 0;			# Savings when event is detected & reported at container j
param RptDeadline {CNTNR} >=0;		# Deadline in seconds for repoorting events at container
param prTimely {CNTNR} >=0, <=1;	# Prob. of timely report of event at container
param prDetect {CNTNR} >=0, <=1;	# Prob. of detecting an event at container
param FlsAlrm {CNTNR} >=0, <=1;		# Max. tolerable rate of false alarm at container
param y {CNTNR, SLOT, UNIT} >=0, <=1;	# Binary parameter specifying container locations
param DotX>= 30, <= 90;                 # Average train speed in km/h
param MaxSpeed >=40, <=360;		# Maximum train speed for sensor to be read
param cAlph >=0;			# Cost of false alarm per incident
param cCell >=0;			# Cost of transmitting one byte by cellular
param cInSnsr >=0;			# Cost of installing sensor in dollars
param cRptr >= 0;			# Cost of repeater in dollars
param cTrackRptr >= 0;			# Cost of installing trackside repeater in dollars
param cTrackCell >=0;			# Cost of installing trackside cellular modem in dollars
param cBackCell >=0;			# Cost of installing cellular backhaul communications device in dollars
param trips >=0;			# Number of trips per locomotive per yr
param ReaderPasses >=0;			# Number of trains passing trackside reader per year
param LTcell >=0;			# Mean time in weeks to replace cellular comms. device
param LTreader >=0;			# Mean time in weeks to replace trackside reader
param msgLen >=0;			# Average message length in bytes
param EvtRate >=0, <=1;			# Event occurence rate
param RTT >=0;				# Round trip time from reader to operations center in hours
param TripLen >=0;			# Trip length in kilometers
param FixedCost >= 0;                   # Fixed portion of sensor cost
param FP2       >= 0;                   # Multiplier for probability of detection
param FP3       >= 0;                   # Multiplier for probability of successful communications
param FP4       >= 0;                   # Multiplier for probability of false alarm
param FP5	>= 0;			# Multiplier for sensor transmission range
param FP6	>= 0;			# Multiplier for inverse of sensor read time
param minDedln;				# Minimum event reporting deadline

var S {i in COMMDEV, j in CNTNR, q in SLOT, k in UNIT} binary, := y [j,q,k];
var theta >= 0.02, <= 0.06;             # Transmission range for device in km
var TmRead >=1/3600, <= 10/3600;        # Time taken for reader to interrogate sensor in hours
var FA  >= 5.00E-4, <= 1.00E-0;	        # False alarm probability for device
var PD  >= 5.00E-4, <= 9.50E-1;         # Prob. of detection for device
var rho >= 5.00E-4, <= 9.50E-1;         # Prob. of successful comms from sensor to trackside reader
var Eta >= 1.0E-2, <= 1.0E-1;		# Prob. of unsuccessful comms when sensor & reader are stationary
var beta >= 1.0E-4, <= 5.0E-3;		# Rate of change of prob. of unsuccessful comms with speed
var cSnsr >= 1.0, <= 90.0;              # Cost of sensor in dollars
var AvRdrSep >= 0.05, <=40;              	# Average reader separation in km
var NumReaders integer;			# Number of readers needed along route

var fac {k in UNIT};			# False alarm cost per unit
var TotSavings {k in UNIT};		# 
var missedDet {k in UNIT};		# Cost of missed detection
var LateRpt {k in UNIT};		# Cost of trackside reader not reading sensor
var Costmsg {k in UNIT};		# Cost of reporting events
var CostSnsr {k in UNIT};		# Cost of installing and acquiring sensors

# Objective function 
minimize costMetric:
   sum {k in UNIT} (fac[k] + missedDet[k] + LateRpt[k] +
		Costmsg[k] + CostSnsr[k])
   + ((cRptr+cTrackRptr)/(ReaderPasses*LTreader)
       +(cBackCell+cTrackCell)/(ReaderPasses*LTreader))
       *NumReaders;

# False alarm cost for unit k
subject to FACost {k in UNIT}:
   fac[k] = cAlph*sum {i in COMMDEV, j in CNTNR, q in SLOT}
		(FA*y[j,q,k]*S[i,j,q,k]);

#
subject to SavingsSum {k in UNIT}:
   TotSavings[k] = EvtRate*sum {j in CNTNR, q in SLOT} (sav[j]*y[j,q,k]);

#Cost of missed detection
subject to costMissedDet {k in UNIT}:
   missedDet[k] = TotSavings[k]
		  - EvtRate*sum {i in COMMDEV, j in CNTNR, q in SLOT}
		   (PD*sav[j]*y[j,q,k]*S[i,j,q,k]) ;

#Cost of unsuccessful communications
subject to costNoComms {k in UNIT}:
   LateRpt[k] = TotSavings[k]
		- EvtRate*sum {i in COMMDEV, j in CNTNR, q in SLOT}
		   (rho*sav[j]*y[j,q,k]*S[i,j,q,k]) ;

#Cost of reporting events during rail trip
subject to msgCosts {k in UNIT}:
   Costmsg[k] = (TripLen/DotX)*msgLen*cCell*sum {i in COMMDEV, j in CNTNR, q in SLOT}
		 (lambda[i]*S[i,j,q,k]);

subject to ItemCostSnsr :
   cSnsr = FixedCost + FP2*PD + FP3*rho + FP4*(1-FA) + FP5*theta + (FP6/TmRead);

#Cost of acquiring and installing sensors
subject to SnsrCosts {k in UNIT}:
   CostSnsr[k] = sum {i in COMMDEV, j in CNTNR, q in SLOT}
                    (S[i,j,q,k]*(cSnsr+cInSnsr)) ;

# Constraint requiring each container to have no more than one sensor
subject to SnsrLimit {j in CNTNR}:
   sum {i in COMMDEV, q in SLOT, k in UNIT} y[j,q,k]*S[i,j,q,k] <= 1 ;

# Constraint requiring that each sensor can be used exactly once
subject to UniqSnsr {i in COMMDEV}:
   sum {j in CNTNR, q in SLOT, k in UNIT} y[j,q,k]*S[i,j,q,k] <=1 ;

# Constraint requiring that detection prob. for assigned sensor meets visibility
subject to VisDtct {j in CNTNR}:
   sum {i in COMMDEV, q in SLOT, k in UNIT} PD*y[j,q,k]*S[i,j,q,k] >= prDetect[j];

# Constraint on false alarm rate of each sensor
subject to VisFlsA {j in CNTNR}:
   sum {i in COMMDEV, q in SLOT, k in UNIT} FA*y[j,q,k]*S[i,j,q,k] <= FlsAlrm[j];

# Constraint on train speed
subject to ReadTime:
   TmRead <= 2*theta / DotX ;

# Constraint on read time given train speed
subject to ReadTime2:
   (2*theta - MaxSpeed*TmRead) <= 0;

# Constraint to define relationship between rho and train speed
subject to RhoVariationEqn:
   rho = 1 - (Eta + beta*DotX);

# Constraint to calculate average reader separation for a given train speed
#  and probability of successful communications from sensor to reader
subject to ReaderSep:
   AvRdrSep <= 2*DotX*rho*(minDedln - RTT)/(2-rho);

# Constraints to implement the floor function and calculate the number of
#  readers needed along a route
subject to nbrReaders1:
   NumReaders <= TripLen/AvRdrSep;

subject to nbrReaders2:
   NumReaders >= (TripLen/AvRdrSep) - (1-1.00E-7);