module Weight

Public Class Methods

gridLimits(row, rowLength) click to toggle source
# File lib/gthc/olson/weight.rb, line 48
def self.gridLimits(row, rowLength)
  return row - 1 < 0,
         row + 1 > rowLength - 1
end
weightBalance(people, slots) click to toggle source

Weight Balance - prioritize people with fewer scheduled shifts

# File lib/gthc/olson/weight.rb, line 15
def self.weightBalance(people, slots)

  slots.each do | currentSlot |

    # Establish variables.
    currentPersonID = currentSlot.col
    dayScheduled = people[currentPersonID].dayScheduled
    nightScheduled = people[currentPersonID].nightScheduled
    night = currentSlot.isNight;

    nightMulti = 1;
    dayMulti = 1;

    # Set multipliers.
    if nightScheduled != 0
      nightMulti = 1.0 / (nightScheduled + 1)
    end

    if dayScheduled != 0
      dayMulti = 1.0 / (dayScheduled + 1)
    end

    #Adjust weights with multipliers.
    if night
      currentSlot.weight = currentSlot.weight * nightMulti
    else
      currentSlot.weight = currentSlot.weight * dayMulti
    end

  end
  return people, slots
end
weightContiguous(slots, scheduleGrid) click to toggle source

Weight Contiguous - prioritize people to stay in the tent more time at once.

# File lib/gthc/olson/weight.rb, line 54
def self.weightContiguous(slots, scheduleGrid)

  i = 0
  while i < slots.length
    # Establish Variables
    currentRow = slots[i].row
    currentCol = slots[i].col

    aboveRow = currentRow-1
    belowRow = currentRow+1

    # grab all slots under the same col as the inspected slot in order
    # to get the slots above and below
    allSlots = scheduleGrid[currentCol]
    slotsLength = allSlots.length

    # find what to skip
    skipAboveRow, skipBelowRow = gridLimits(currentRow, slotsLength)

    currentIsNight = slots[i].isNight
    aboveIsNight = !skipAboveRow && allSlots[aboveRow].isNight
    belowIsNight = !skipBelowRow && allSlots[belowRow].isNight

    aboveTent = !skipAboveRow && allSlots[aboveRow].status == "Scheduled"
    belowTent = !skipBelowRow && allSlots[belowRow].status == "Scheduled"
    aboveSome = !skipAboveRow && allSlots[aboveRow].status == "Somewhat"
    belowSome = !skipBelowRow && allSlots[belowRow].status == "Somewhat"
    aboveFree = !skipAboveRow && allSlots[aboveRow].status == "Available"
    belowFree = !skipBelowRow && allSlots[belowRow].status == "Available"

    multi = 1

    # Both are scheduled.
    if aboveTent && belowTent
      multi = 100
    end

    # Both are not free
    if !belowTent && !belowFree && !aboveSome && !belowSome && !aboveTent && !aboveFree
      multi *= 0.25
    end

    # Above is scheduled, below is free.
    if aboveTent && !belowTent && belowFree
      multi = 3.25
    end

    # Below is scheduled, above is free.
    if belowTent && !aboveTent && aboveFree
      multi = 3.25
    end

    # Above is scheduled, below is not free.
    if aboveTent && !belowTent && !belowFree
      multi = 3
    end

    # Below is scheduled, above is not free.
    if belowTent && !aboveTent && !aboveFree
      multi = 3
    end

    # Both are free
    if belowFree && aboveFree
      multi = 2.75
    end

    # Above is free, below is not free
    if aboveFree && !belowTent && !belowFree
      multi = 1
    end

    # Below is free, above is not free
    if(belowFree && !aboveTent && !aboveFree)
      multi = 1
    end

    # Night Multi
    if aboveIsNight || belowIsNight || currentIsNight
      multi *= 1.25
    end

    # Occurance of Somewhat Available
    if slots[i].status == "Somewhat"
      multi *= 0.5
    end

    slots[i].weight = slots[i].weight*multi
    i += 1

  end

  return slots, scheduleGrid
end
weightPick(people, slots, graveyard, scheduleGrid) click to toggle source

Update people, spreadsheet, and remove slots.

# File lib/gthc/olson/weight.rb, line 175
def self.weightPick(people, slots, graveyard, scheduleGrid)

  # Remove winner from list.
  winner = slots.shift;

  # Update person information.
  currentPersonID = winner.col;
  currentTime = winner.isNight;

  if currentTime
    people[currentPersonID].nightScheduled += 1
    people[currentPersonID].nightFree -= 1
   else
    people[currentPersonID].dayScheduled += 1
    people[currentPersonID].dayFree -= 1
  end

  # Establish Variables
  currentRow = winner.row
  currentCol = winner.col
  tentCounter = 0

  # Update Data
  scheduleGrid[currentCol][currentRow].status = "Scheduled";

  # Count number of scheduled tenters during winner slot.
  i = 0
  while i < scheduleGrid.length
    if scheduleGrid[i][currentRow].status == "Scheduled"
      tentCounter = tentCounter + 1
    end
    i += 1
  end

  # Determine how many people are needed.
  peopleNeeded = Helpers.calculatePeopleNeeded(currentTime, winner.phase)

  # Update Slots and Graveyard
  if tentCounter >= peopleNeeded
    graveyard[currentRow] = 1
    j = 0
    tempSlots = []
    while j < slots.length
      tempRow = slots[j].row
      if tempRow != currentRow
        tempSlots.push slots[j]
      end
      j += 1
    end
    slots = tempSlots
  end

  return people, slots, graveyard, scheduleGrid
end
weightReset(slots) click to toggle source

Weight Reset - set all weights to 1.

# File lib/gthc/olson/weight.rb, line 7
def self.weightReset(slots)
  slots.each do | currentSlot |
    currentSlot.weight = 1;
  end
  slots
end
weightToughTime(slots, scheduleLength) click to toggle source

Weight Tough Time - prioritize time slots with few people available. */

# File lib/gthc/olson/weight.rb, line 150
def self.weightToughTime(slots, scheduleLength)

  # Set up counterArray (Rows that are filled).
  counterArray = Array.new(scheduleLength + 1, 0)

  # Fill counterArray.
  slots.each do | currentSlot |
    currentRow = currentSlot.row
    counterArray[currentRow] = counterArray[currentRow] + 1
  end

  # Update Weights.
  slots.each do | currentSlot |
    currentRow = currentSlot.row
    currentPhase = currentSlot.phase
    nightBoolean = currentSlot.isNight
    peopleNeeded = Helpers.calculatePeopleNeeded(nightBoolean, currentPhase)
    numFreePeople = counterArray[currentRow]
    currentSlot.weight = currentSlot.weight*(12/numFreePeople)*peopleNeeded
  end

  return slots
end