func applyBloodBankDiscipline(sys *BloodBankSystem, queue *qsim.Queue, trashProcessor, transfusionProcessor *qsim.Processor) { // Assigns the youngest unit to the processor assigner := func(cbProc *qsim.Processor, cbJob *qsim.Job) { var i, iYoungest int var j *qsim.Job if queue.Length() == 0 { qsim.D("Aborted after Job", cbJob) if sys.statsStarted { sys.NumAborted++ } // Give the processor a dummy job until the next transfusion j = qsim.NewJob(-1) cbProc.Start(j) return } for i, j = range queue.Jobs { if j.ArrTime > queue.Jobs[iYoungest].ArrTime { iYoungest = i } } j = queue.Jobs[iYoungest] queue.Remove(j) cbProc.Start(j) qsim.D("Started Job", j) } transfusionProcessor.AfterFinish(assigner) }
// Occupancy returns the total number of Jobs in the system. func (sys *PortaPottySystem) Occupancy() (occ int) { var p *qsim.Processor var q *qsim.Queue for _, p = range sys.processors { if !p.IsIdle() { occ++ } } for _, q = range sys.queues { occ += q.Length() } return }
// strategicAssignment returns an Assignment corresponding to the following // wait-time reduction strategy: // // – Look for the shortest queue first. If there are multiple queues of the // same short length, then // – Pick the queue with the highest male-to-female ratio. If there are // multiple short queues with the same male-to-female ratio, then // – Pick a random one. func (sys *PortaPottySystem) strategicAssignment() *qsim.Assignment { var p *qsim.Processor var q *qsim.Queue var shortQueues, dudefulQueues []*qsim.Queue var j *qsim.Job var shortestLen, maleCount, highestMaleCount int shortestLen = 9999 // If there's an idle porta-potty, obviously just walk in for _, p = range sys.processors { if p.IsIdle() { return nil } } for _, q = range sys.queues { if q.Length() < shortestLen { shortQueues = []*qsim.Queue{q} shortestLen = q.Length() } else if q.Length() == shortestLen { shortQueues = append(shortQueues, q) } } for _, q = range shortQueues { maleCount = 0 for _, j = range q.Jobs { if j.StrAttrs["sex"] == "male" { maleCount++ } } if maleCount > highestMaleCount { dudefulQueues = []*qsim.Queue{q} highestMaleCount = maleCount } else if maleCount == highestMaleCount { dudefulQueues = append(dudefulQueues, q) } } return &qsim.Assignment{ Type: "Queue", Queue: dudefulQueues[rand.Intn(len(dudefulQueues))], } }