Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I would rather do it in a single loop. My produces a different result from yours. Yours scheduled 2/3 of all the jobs. Mine scheduled all. I will add explanations later. Going off for an appointment now.</p> <pre><code>public class Job { public static long Iterations; public int Id; public int Priority; public DateTime Begin; public DateTime End; public bool Overlaps(Job other) { Iterations++; return this.End &gt; other.Begin &amp;&amp; this.Begin &lt; other.End; } } public class Assignment : IComparable&lt;Assignment&gt; { public Job Job; public int Core; #region IComparable&lt;Assignment&gt; Members public int CompareTo(Assignment other) { return Job.Begin.CompareTo(other.Job.Begin); } #endregion } class Program { static void Main(string[] args) { const int Jobs = 1000; const int Cores = 2; const int ConcurrentJobs = Cores + 1; const int Priorities = Cores + 3; DateTime startTime = new DateTime(2011, 3, 1, 0, 0, 0, 0); Console.WriteLine(string.Format("{0} Jobs x {1} Cores", Jobs, Cores)); var timer = Stopwatch.StartNew(); Console.WriteLine("Populating data"); var jobs = new List&lt;Job&gt;(); for (int jobId = 0; jobId &lt; Jobs; jobId++) { var jobStart = startTime.AddHours(jobId / ConcurrentJobs).AddMinutes(jobId % ConcurrentJobs); jobs.Add(new Job() { Id = jobId, Priority = jobId % Priorities, Begin = jobStart, End = jobStart.AddHours(0.5) }); } Console.WriteLine(string.Format("Completed in {0:n}ms", timer.ElapsedMilliseconds)); timer.Reset(); Console.WriteLine("Assigning Jobs to Cores"); List&lt;Assignment&gt;[] assignments = new List&lt;Assignment&gt;[Cores]; for (int core = 0; core &lt; Cores; core++) assignments[core] = new List&lt;Assignment&gt;(); Job[] lastJobs = new Job[Cores]; foreach (Job j in jobs) { Job job = j; bool assigned = false; for (int core = 0; core &lt; Cores; core++) { if (lastJobs[core] == null || !lastJobs[core].Overlaps(job)) { // Assign directly if no last job or no overlap with last job lastJobs[core] = job; assignments[core].Add(new Assignment { Job = job, Core = core }); assigned = true; break; } else if (job.Priority &gt; lastJobs[core].Priority) { // Overlap and higher priority, so we replace Job temp = lastJobs[core]; lastJobs[core] = job; job = temp; // Will try to later assign to other core assignments[core].Add(new Assignment { Job = job, Core = core }); assigned = true; break; } } if (!assigned) { // TODO: What to do if not assigned? Your code seems to just ignore them } } List&lt;Assignment&gt; merged = new List&lt;Assignment&gt;(); for (int core = 0; core &lt; Cores; core++) merged.AddRange(assignments[core]); merged.Sort(); Console.WriteLine(string.Format("Completed in {0:n}ms", timer.ElapsedMilliseconds)); timer.Reset(); Console.WriteLine(string.Format("\nTotal Comparisons: {0:n}", Job.Iterations)); Job.Iterations = 0; // Reset to count again { IEnumerable&lt;Assignment&gt; assignments2 = null; for (int core = 0; core &lt; Cores; core++) { // avoid modified closures by creating local variables int localCore = core; var localAssignments = assignments2; // Step 1: Determine the remaining jobs var remainingJobs = localAssignments == null ? jobs : from j in jobs where !(from a in localAssignments select a.Job).Contains(j) select j; // Step 2: Assign the top priority job in any time-slot to the core var assignmentsForCore = from s1 in remainingJobs where (from s2 in remainingJobs where s1.Overlaps(s2) orderby s2.Priority select s2).First().Equals(s1) select new Assignment { Job = s1, Core = localCore }; // Step 3: Accumulate the results (unfortunately requires a .ToList() to avoid massive over-joins) assignments2 = assignments2 == null ? assignmentsForCore.ToList() : assignments2.Concat(assignmentsForCore.ToList()); } // This is where I'd like to Execute the query one single time across all cores, but have to do intermediate steps to avoid massive-over-joins assignments2 = assignments2.ToList(); Console.WriteLine(string.Format("Completed in {0:n}ms", timer.ElapsedMilliseconds)); Console.WriteLine("\nJobs:"); foreach (var job in jobs.Take(20)) { Console.WriteLine(string.Format("{0}-{1} Id {2} P{3}", job.Begin, job.End, job.Id, job.Priority)); } Console.WriteLine("\nAssignments:"); foreach (var assignment in assignments2.OrderBy(a =&gt; a.Job.Begin).Take(10)) { Console.WriteLine(string.Format("{0}-{1} Id {2} P{3} C{4}", assignment.Job.Begin, assignment.Job.End, assignment.Job.Id, assignment.Job.Priority, assignment.Core)); } if (merged.Count != assignments2.Count()) System.Console.WriteLine("Difference count {0}, {1}", merged.Count, assignments2.Count()); for (int i = 0; i &lt; merged.Count() &amp;&amp; i &lt; assignments2.Count(); i++) { var a2 = assignments2.ElementAt(i); var a = merged[i]; if (a.Job.Id != a2.Job.Id) System.Console.WriteLine("Difference at {0} {1} {2}", i, a.Job.Begin, a2.Job.Begin); if (i % 100 == 0) Console.ReadKey(); } } Console.WriteLine(string.Format("\nTotal Comparisons: {0:n}", Job.Iterations)); Console.WriteLine("Any key to continue"); Console.ReadKey(); } } </code></pre> <hr> <p>Removed due to major bug. Reworking on it.. :P</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload