internal bool ValidDispatches(ref List<Preference> prefs, Schedule jssp) { if (prefs.Count > jssp.ReadyJobs.Count) { prefs = prefs .GroupBy(x => x.Dispatch.Name) .Select(group => group.First()).ToList(); } if (prefs.Count == 0 && jssp.Sequence.Count >= NumDimension - 1) return true; if (prefs.Count != jssp.ReadyJobs.Count) return false; if (prefs.Any(p => p.Dispatch.Mac < 0)) return false; if (prefs.Count(p => p.Followed) == 1) return true; foreach (Preference pref in prefs) { jssp.FindDispatch(pref.Dispatch.Job, out pref.Dispatch); } return false; }
internal int UpdateFeatures(int pid, int step, Schedule jssp) { LinearModel dummy = new LinearModel(); foreach (var p in Preferences[pid - 1, step]) { var lookahead = jssp.Clone(); p.Feature = lookahead.Dispatch1(p.Dispatch.Job, FeatureMode, dummy); } return Preferences[pid - 1, step].Count; }
public string Optimise(int pid) { int opt; bool solved; int simplexIterations; string name = GetName(pid); ProblemInstance prob = GetProblem(name); if (prob == null) return String.Format("{0}:{1} doen't exist!", FileInfo.Name, pid); int[,] xTimeJob; if (prob.Dimension < 1000) // Gurobi cannot deal with instance hel1: Heller 100x10 { // INTENSE WORK xTimeJob = prob.Optimize(name, out opt, out solved, out simplexIterations, TimeLimit); Schedule jssp = new Schedule(prob); jssp.SetCompleteSchedule(xTimeJob, opt); string errorMsg; if (!jssp.Validate(out errorMsg, true)) { return String.Format("Error {0}", errorMsg); } } else { // too intense work opt = -1; solved = false; xTimeJob = null; simplexIterations = -1; } AddOptMakespan(name, opt, solved, xTimeJob, simplexIterations); return String.Format("{0}:{1} {2}{3}", FileInfo.Name, pid, opt, (solved ? "" : "*")); }
public Schedule Clone() { Schedule clone = new Schedule(_prob, _random); foreach (Dispatch disp in Sequence) clone.Sequence.Add(disp); clone.ReadyJobs = ReadyJobs.ToList(); clone.Makespan = Makespan; for (int job = 0; job < _prob.NumJobs; job++) clone._jobs[job] = _jobs[job].Clone(); for (int mac = 0; mac < _prob.NumMachines; mac++) clone._macs[mac] = _macs[mac].Clone(); return clone; }
public void GetLocalPhi(Schedule.Jobs job, Schedule.Macs mac, int proc, int wrmTotal, int slotsTotal, int makespan, int step, int startTime, int arrivalTime, int reduced, int totProcTime) { #region job related PhiLocal[(int) Local.proc] = proc; PhiLocal[(int) Local.startTime] = startTime; PhiLocal[(int) Local.endTime] = startTime + proc; PhiLocal[(int) Local.jobOps] = job.MacCount; PhiLocal[(int) Local.arrival] = arrivalTime; PhiLocal[(int) Local.wait] = startTime - arrivalTime; #endregion #region machine related PhiLocal[(int) Local.macFree] = mac.Makespan; PhiLocal[(int) Local.macOps] = mac.JobCount; #endregion #region explanatory for features, static per step XiExplanatory[(int) Explanatory.totProcTime] = totProcTime; PhiLocal[(int) Local.macTotProcTime] = mac.TotProcTime; PhiLocal[(int) Local.jobTotProcTime] = job.TotProcTime; XiExplanatory[(int) Explanatory.step] = step; #endregion #region schedule related PhiLocal[(int) Local.makespan] = makespan; #endregion #region work remaining /* add current processing time in order for <w,phi> can be equivalent to MWR/LWR * (otherwise it would find the job with most/least work remaining in the next step, * i.e. after the one-step lookahead */ PhiLocal[(int) Local.macWrm] = mac.WorkRemaining + proc; PhiLocal[(int) Local.jobWrm] = job.WorkRemaining + proc; XiExplanatory[(int) Explanatory.totWrm] = wrmTotal + proc; #endregion #region flow related PhiLocal[(int) Local.reducedSlack] = reduced; PhiLocal[(int) Local.macSlack] = mac.TotSlack; PhiLocal[(int) Local.allSlack] = slotsTotal; #endregion }
public void GetGlobalPhi(Schedule current, LinearModel model) { Schedule lookahead; for (int i = 0; i < SDRData.SDRCount; i++) { SDRData.SDR sdr = (SDRData.SDR) i; if (!(Math.Abs(model.GlobalWeights[(int) sdr][0]) > LinearModel.WEIGHT_TOLERANCE)) continue; lookahead = current.Clone(); lookahead.ApplySDR(sdr); PhiGlobal[(int) (Global) (sdr)] = lookahead.Makespan; } if ((Math.Abs(model.GlobalWeights[(int) Global.RNDmin][0]) < LinearModel.WEIGHT_TOLERANCE) && (Math.Abs(model.GlobalWeights[(int) Global.RNDmax][0]) < LinearModel.WEIGHT_TOLERANCE) && (Math.Abs(model.GlobalWeights[(int) Global.RNDstd][0]) < LinearModel.WEIGHT_TOLERANCE) && (Math.Abs(model.GlobalWeights[(int) Global.RNDmean][0]) < LinearModel.WEIGHT_TOLERANCE)) return; for (int i = 0; i < RND.Length; i++) { lookahead = current.Clone(); lookahead.ApplySDR(SDRData.SDR.RND); RND[i] = lookahead.Makespan; } PhiGlobal[(int) Global.RNDmin] = RND.Min(); PhiGlobal[(int) Global.RNDmax] = RND.Max(); PhiGlobal[(int) Global.RNDmean] = RND.Average(); PhiGlobal[(int) Global.RNDstd] = StandardDev(RND, PhiGlobal[(int) Global.RNDmean]); }
public void GetEquivPhi(int job, Schedule current) { for (int i = 0; i < SDRData.SDRCount; i++) Equiv[i] = job == current.JobChosenBySDR((SDRData.SDR) i); }
internal string CollectAndLabel(int pid) { string name = GetName(pid); DataRow instance = Data.Rows.Find(name); ProblemInstance prob = (ProblemInstance) instance["Problem"]; GurobiJspModel gurobiModel = new GurobiJspModel(prob, name, TMLIM_STEP); Schedule jssp = new Schedule(prob); int currentNumFeatures = 0; for (int step = 0; step < prob.Dimension; step++) { Preferences[pid - 1, step] = FindFeaturesForAllJobs(jssp, gurobiModel); int dispatchedJob = _trajectory(jssp, Preferences[pid - 1, step]); jssp.Dispatch1(dispatchedJob); gurobiModel.CommitConstraint(jssp.Sequence[step], step); Preferences[pid - 1, step].Find(x => x.Dispatch.Job == dispatchedJob).Followed = true; currentNumFeatures += Preferences[pid - 1, step].Count; } NumFeatures += currentNumFeatures; gurobiModel.Dispose(); RankPreferences(pid); return String.Format("{0}:{1} #{2} phi", FileInfo.Name, pid, currentNumFeatures); }
public Preference(Schedule.Dispatch dispatch, Features features) { Dispatch = dispatch; Feature = features; }
private int UseImitationLearning(Schedule jssp, List<Preference> prefs) { // pi_i = beta_i*pi_star + (1-beta_i)*pi_i^hat // i: ith iteration of imitation learning // pi_star is expert policy (i.e. optimal) // pi_i^hat: is pref model from prev. iteration double pr = Random.NextDouble(); return Model != null && pr >= _beta ? ChooseWeightedJob(jssp, prefs) : ChooseOptJob(jssp, prefs); }
private List<Preference> FindFeaturesForAllJobs(Schedule jssp, GurobiJspModel gurobiModel) { Preference[] prefs = new Preference[jssp.ReadyJobs.Count]; for (int r = 0; r < jssp.ReadyJobs.Count; r++) { Schedule lookahead = jssp.Clone(); Features phi = lookahead.Dispatch1(jssp.ReadyJobs[r], FeatureMode, null); // commit the lookahead prefs[r] = new Preference(lookahead.Sequence[lookahead.Sequence.Count - 1], phi); // need to optimize to label featuers correctly -- this is computationally intensive gurobiModel.Lookahead(prefs[r].Dispatch, out prefs[r].ResultingOptMakespan); prefs[r].SimplexIterations = gurobiModel.SimplexIterations; } return prefs.ToList(); }
private int ChooseWeightedJob(Schedule jssp, List<Preference> prefs) { List<double> priority = new List<double>(jssp.ReadyJobs.Count); for (int r = 0; r < jssp.ReadyJobs.Count; r++) priority.Add(Model.PriorityIndex(prefs[r].Feature)); return jssp.ReadyJobs[priority.FindIndex(p => Math.Abs(p - priority.Max()) < 0.001)]; }
private int ChooseSDRJob(Schedule jssp, List<Preference> prefs = null) { return jssp.JobChosenBySDR((SDRData.SDR) Track); }
private int ChooseOptJob(Schedule jssp, List<Preference> prefs) { int minMakespan = prefs.Min(p => p.ResultingOptMakespan); List<Preference> optimums = prefs.Where(p => p.ResultingOptMakespan == minMakespan).ToList(); return optimums.Count == 1 ? optimums[0].Dispatch.Job : optimums[Random.Next(0, optimums.Count)].Dispatch.Job; }
private int ChooseLocalOptJob(Schedule jssp, List<Preference> prefs) { const double EPSILON = 0.1; if (Random.NextDouble() > EPSILON) return ChooseOptJob(jssp, prefs); int minMakespan = prefs.Min(p => p.ResultingOptMakespan); List<Preference> epsGreedy = prefs.Where(p => p.ResultingOptMakespan > minMakespan).ToList(); if (epsGreedy.Count == 0) return ChooseOptJob(jssp, prefs); int nextBest = epsGreedy.Min(p => p.ResultingOptMakespan); epsGreedy = epsGreedy.Where(p => p.ResultingOptMakespan == nextBest).ToList(); return epsGreedy.Count == 1 ? epsGreedy[0].Dispatch.Job : epsGreedy[Random.Next(0, epsGreedy.Count)].Dispatch.Job; }
public void CommitConstraint(Schedule.Dispatch dispatch, int step) { _model.AddConstr(_x[dispatch.Job, dispatch.Mac] == dispatch.StartTime, String.Format("Step{0}.{1}", step, dispatch.Name)); }
public int[,] Lookahead(Schedule.Dispatch dispatch, out int optimum) { return Lookahead(new List<Schedule.Dispatch> {dispatch}, out optimum); }
public Preference(Schedule.Dispatch dispatch, bool followed, int resultingOptMakespan, int rank) { Dispatch = dispatch; Followed = followed; ResultingOptMakespan = resultingOptMakespan; Rank = rank; }