//
// LocalSolver Model for Example 6.5
//

use io;

function input() {
  usage = "\nUsage: localsolver example6.5.lsp "
        + "fileName=dataFile [lsTimeLimit=timeLimit]\n";

  if (fileName == nil) error(usage);
  dataFile = io.openRead(fileName + ".dat");
  nJobs = dataFile.readInt();
  setup[0..nJobs][0..nJobs] = dataFile.readInt();
  ptime[0..nJobs-1] = dataFile.readInt();
  penalty[0..nJobs-1] = dataFile.readInt();
  dataFile.close();
}

function model() {
  // Define a list variable where jobs[i] is the index of the ith job in the sequence
  jobs <- list(nJobs);

  // All jobs must be in the sequence
  constraint count(jobs) == nJobs;
  
  // Calculate delay cost
  delay[1] <- ptime[jobs[0]];
  delay[j in 2..nJobs-1] <- delay[j-1] + ptime[jobs[j-1]];
  delayCost <- sum[j in 1..nJobs-1] (delay[j]*penalty[jobs[j]]);   

  // Calculate setup cost
  setupCost <- setup[0][jobs[0]] + setup[jobs[nJobs-1]+1][nJobs];
  setupCost <- setupCost + sum[i in 1..nJobs-1] (setup[jobs[i-1]+1][jobs[i]]);

  // Calculate objective function
  obj <- delayCost + setupCost;
  minimize obj;
}

function output() {
  println("Delay Cost: " + getValue(delayCost));
  println("Setup Cost: " + getValue(setupCost));
  println("Obj: " + getValue(obj));
  outputFile = io.openWrite(fileName + ".out");
  for[i in jobs.value] outputFile.print(i + 1, " ");
  outputFile.close();
}
