示例#1
0
 public static List<LaneSchedulerAction> GetActions(LaneSchedulerState state, List<LaneSchedulerReservation> reservations)
 {
     List<LaneSchedulerAction> actions = new List<LaneSchedulerAction>();
     foreach (LaneSchedulerReservation reservation in reservations)
     {
         foreach (LaneSchedulerAction action in Expand(state, reservation))
         {
             actions.Add(action); // add at the end of list, so they are in order
         }
     }
     return actions;
 }
示例#2
0
        public static List<LaneSchedulerReservation> GetAlternativeReservations(LaneSchedulerState state, LaneSchedulerReservation reservation)
        {
            List<LaneSchedulerReservation> reservations = new List<LaneSchedulerReservation>();

            if (reservation.StartTimeSlot - 1 > 0)
            {
                LaneSchedulerReservation altReservation1 = new LaneSchedulerReservation(reservation.Id, reservation.NumberOfLanes, reservation.NumberOfTimeSlots, reservation.StartTimeSlot - 1);
                List<LaneSchedulerAction> actions = LaneScheduler.Expand(state, altReservation1);
                if (actions.Count > 0)
                {
                    reservations.Add(altReservation1);
                }
                int numTimeSlots = reservation.NumberOfTimeSlots - 1;
                while (numTimeSlots > 0)
                {
                    LaneSchedulerReservation altReservation2 = new LaneSchedulerReservation(reservation.Id, reservation.NumberOfLanes, numTimeSlots, reservation.StartTimeSlot - 1);
                    List<LaneSchedulerAction> actions2 = LaneScheduler.Expand(state, altReservation2);
                    if (actions2.Count > 0)
                    {
                        reservations.Add(altReservation2);
                    }
                    numTimeSlots--;
                }
            }

            if (reservation.StartTimeSlot + 1 < state.numberOfTimeSlots)
            {
                LaneSchedulerReservation altReservation1 = new LaneSchedulerReservation(reservation.Id, reservation.NumberOfLanes, reservation.NumberOfTimeSlots, reservation.StartTimeSlot + 1);
                List<LaneSchedulerAction> actions = LaneScheduler.Expand(state, altReservation1);
                if (actions.Count > 0)
                {
                    reservations.Add(altReservation1);
                }
                int numTimeSlots = reservation.NumberOfTimeSlots - 1;
                while (numTimeSlots > 0)
                {
                    LaneSchedulerReservation altReservation2 = new LaneSchedulerReservation(reservation.Id, reservation.NumberOfLanes, numTimeSlots, reservation.StartTimeSlot + 1);
                    List<LaneSchedulerAction> actions2 = LaneScheduler.Expand(state, altReservation2);
                    if (actions2.Count > 0)
                    {
                        reservations.Add(altReservation2);
                    }
                    numTimeSlots--;
                }
            }

            return reservations;
        }
示例#3
0
 public static List<LaneSchedulerAction> Expand(LaneSchedulerState state, LaneSchedulerReservation reservation)
 {
     List<LaneSchedulerAction> actions = new List<LaneSchedulerAction>();
     if (state.IsPossible(reservation))
     {
         for (int lane = 0; lane < state.numberOfLanes; lane++)
         {
             AppWeightPair appWeightPair = state.IsApplicable(lane, reservation.NumberOfLanes, reservation.NumberOfTimeSlots, reservation.StartTimeSlot);
             if (appWeightPair.applicable)
             {
                 actions.Add(new LaneSchedulerAction(lane, reservation, appWeightPair.weight));
             }
         }
     }
     return actions;
 }
        public LaneSchedulerState Convert(IList<Reservation> reservations, out List<LaneSchedulerReservation> schedulerReservations)
        {
            schedulerReservations = (from y in reservations
                                         select new LaneSchedulerReservation()
                                         {
                                             Id = y.Id,
                                             NumberOfLanes = (int)Math.Ceiling(y.NumberOfPlayers / 6.0m),
                                             NumberOfTimeSlots = y.TimeSlots.Count,
                                             StartTimeSlot = y.TimeSlots[0].Id -1
                                         }).ToList();

            var state =  new LaneSchedulerState(
                this.laneRepos.GetAll().Count(),
                this.timeSlotRepos.GetAll().Count(),
                schedulerReservations);
            // iterate all of the reservations in order to put them into the internal state array of the sched.
            int[,] internalState = state.State;
            int laneId = 0;
            int slotId = 0;
            foreach (var resv in reservations)
            {
                foreach (var lane in resv.Lanes)
                {
                    foreach (var slot in resv.TimeSlots)
                    {
                        laneId = lane.Id-1;
                        slotId = slot.Id-1;
                        if (internalState[slotId, laneId] != 0)
                        {
                            throw new InvalidOperationException(String.Format("The scheduler state at position  {0}, {1} is already taken. This means that one or more reservations have been allocated to the same lane and slot. Not so good"));
                        }
                        internalState[slotId, laneId] = resv.Id;
                    }
                }
            }
            state.State = internalState;

            return state;
        }
示例#5
0
        public static bool Test_n_reservations(int numberOfLanes, int numberOfTimeSlots, int numberOfVisitors, int runLimit)
        {
            Debug.WriteLine("Testing scheduling of " + numberOfVisitors + " visitors in " + numberOfLanes + " lanes and " + numberOfTimeSlots + " timeslots");
            LaneWearData.Populate(numberOfLanes);
            List<LaneSchedulerReservation> reservations = new List<LaneSchedulerReservation>();
            // Reservation(int id, int numLanes, int numTimeSlots, int startTimeSlot)
            bool run = true;
            //State emptyState = new State(numberOfLanes, numberOfTimeSlots, reservations);
            LaneSchedulerState state = new LaneSchedulerState(numberOfLanes, numberOfTimeSlots, reservations);
            LaneSchedulerState newState = null;
            int i = 0;
            int visitors = 0;
            int runs = 0;
            long timeSpent = 0;
            Random random = new Random();
            while (run)
            {
                int numVisitors = 4;

                int numTimeSlots = random.Next(1, 3);
                int startTimeSlot = 6; //  random.Next(0, numberOfTimeSlots);
                if (random.Next(0, 100) < 10)
                { // 10 percent will be parties and outings
                    numVisitors = random.Next(5, 41);
                }
                else
                {
                    numVisitors = random.Next(3, 7);
                }

                if (random.Next(0, 100) < 15)
                {
                    startTimeSlot = random.Next(0, numberOfTimeSlots);
                }
                else
                {
                    startTimeSlot = random.Next(2, numberOfTimeSlots - 2);
                }
                int numLanes = 0;
                if (numVisitors % 6 == 0)
                {
                    numLanes = numVisitors / 6;
                }
                else
                {
                    numLanes = (numVisitors / 6) + 1;
                }

                long time1 = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
                int id = i + 1;
                LaneSchedulerReservation reservation = new LaneSchedulerReservation(id, numLanes, numTimeSlots, startTimeSlot);
                Debug.WriteLine("Making reservation id: " + id + " of " + numLanes + " lanes for " + numTimeSlots + " hours, at timeslot " + startTimeSlot);

                List<LaneSchedulerReservation> newReservations = new List<LaneSchedulerReservation>(reservations);
                newReservations.Add(reservation);
                //emptyState = new State(numberOfLanes, numberOfTimeSlots, newReservations);
                LaneSchedulerStateReservationsPair result = LaneScheduler.Search(state, reservations, reservation);
                newState = result.state;

                long time2 = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
                timeSpent = time2 - time1;
                Debug.WriteLine("    Scheduling took: " + timeSpent + " miliseconds");
                if (newState != null)
                {
                    Debug.WriteLine("    It SUCCEEDED!!!!!!!!");
                    Debug.WriteLine(newState.ToString());

                    reservations = newReservations;
                    state = newState;
                    visitors = visitors + numVisitors;
                    Debug.WriteLine("Have now scheduled for: " + visitors + " visitors");
                    i++;
                }
                else
                {
                    Debug.WriteLine("    It failed. Alternative reservations are:");
                    for (int j = 0; j < result.reservations.Count; j++)
                    {
                        Debug.WriteLine("        Reservation for " + result.reservations[j].NumberOfLanes + " lanes at slot: " + result.reservations[j].StartTimeSlot + " for " + result.reservations[j].NumberOfTimeSlots + " hours");
                    }
                }
                if (visitors > numberOfVisitors)
                {
                    run = false;
                }
                if (runs > runLimit)
                {
                    run = false;
                }
                runs++;
            }
            Debug.WriteLine("The last scheduling took: " + timeSpent + " miliseconds");
            if (state != null)
            {
                Debug.WriteLine(state.ToString());
            }
            return true;
        }
示例#6
0
        public static LaneSchedulerState RecursiveSearch(LaneSchedulerState state, List<LaneSchedulerReservation> reservations, int depth, long timelimit, long time)
        {
            if (time > timelimit)
            {
                //Debug.WriteLine("TIME LIMIT EXCEEDED-1! Time was: " + time);
                return null;
            }

            long time1 = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
            //Debug.WriteLine("Reached depth: " + depth);
            if (reservations.Count == 0)
            {
                return state;
            }
            reservations = (from y in reservations
                            select y).OrderBy(y => state.GetReservationWeight(y)).ToList<LaneSchedulerReservation>();
            foreach (LaneSchedulerReservation reservation in reservations)
            {
                // Get applicable actions
                List<LaneSchedulerAction> actions = Expand(state, reservation);

                actions = (from y in actions
                           select y).OrderBy(y => y.weight).ToList<LaneSchedulerAction>();

                // Loop for actions in a depth-first manner, backtracking if no solution is found.
                for (int num = 0; num < actions.Count; num++)
                {
                    LaneSchedulerAction action = actions[num];
                    state.Apply(action);

                    //if (!Scheduler.closedStateList.ContainsKey(state.ReservationRepr(action.reservation)))
                    //{
                    List<LaneSchedulerReservation> remainingReservations = new List<LaneSchedulerReservation>(reservations);
                    remainingReservations.Remove(action.reservation);
                    int newDepth = depth + 1;
                    long time2 = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
                    long runTime = time2 - time1;
                    time = time + runTime;
                    LaneSchedulerState solution = RecursiveSearch(state, remainingReservations, newDepth, timelimit, time);
                    if (solution != null)
                    {
                        //Debug.WriteLine("Placed reservation: " + action.reservation.id);
                        return solution;
                    }
                    else
                    {
                        //string stateRepr = state.ReservationRepr(action.reservation);
                        //if (!Scheduler.closedStateList.ContainsKey(stateRepr))
                        //{
                        //    Scheduler.closedStateList.Add(stateRepr, 1);
                        //}
                        state.Unapply(action);
                        if (time > timelimit)
                        {
                            //Debug.WriteLine("TIME LIMIT EXCEEDED-2! Time was: " + time);
                            return null;
                        }
                        //Debug.WriteLine(state.toString());
                    }
                    //}else{
                    //Debug.WriteLine("    Hit an explored state!");
                    //Debug.WriteLine(state.toString());
                    //Debug.WriteLine("    " + state.ReservationRepr(action.reservation));
                    //state.Unapply(action);
                    //return null;
                    //}
                }
                //Debug.WriteLine("    Backtracking");
                //Debug.WriteLine(state.toString());
            }
            return null;
        }
示例#7
0
        public static LaneSchedulerStateReservationsPair Search(LaneSchedulerState state, List<LaneSchedulerReservation> reservations, LaneSchedulerReservation newReservation)
        {
            LaneScheduler.closedStateList = new Dictionary<string, int>();
            Debug.WriteLine("Adding new Reservation");
            if (!state.IsPossible(newReservation))
            {
                Debug.WriteLine("    It failed the first check");
                // get other reservations
                return new LaneSchedulerStateReservationsPair(null, LaneScheduler.GetAlternativeReservations(state, newReservation));
            }
            // if it can be applied easily
            List<LaneSchedulerAction> actions = Expand(state, newReservation);
            actions = (from y in actions
                       select y).OrderBy(y => y.weight).ToList<LaneSchedulerAction>();
            if (actions.Count > 0)
            {
                state.Apply(actions[0]);
                Debug.WriteLine("    The reservation was straight forward");
                return new LaneSchedulerStateReservationsPair(state, new List<LaneSchedulerReservation>());
            }

            // else, search

            // cut the relevant piece out of the state, so we end up with three pieces.
            // Solve the middle piece, and add it to the top and bottom piece.
            //List<State> statePieces = state.cutInPieces(newReservation);

            List<LaneSchedulerReservation> newReservations = new List<LaneSchedulerReservation>(reservations);
            newReservations.Add(newReservation);

            long time1 = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
            LaneSchedulerState emptyState = new LaneSchedulerState(state.numberOfLanes, state.numberOfTimeSlots, newReservations);
            LaneSchedulerState newState = LaneScheduler.RecursiveSearch(emptyState, newReservations, 0, 100000, 0);

            long time2 = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
            long runTime = time2 - time1;
            Debug.WriteLine("    Search took: " + runTime + " ms");
            if (newState != null)
            {
                Debug.WriteLine("    Returning state");
                return new LaneSchedulerStateReservationsPair(newState, new List<LaneSchedulerReservation>());
            }
            else
            {
                // get other reservations
                Debug.WriteLine("    Returning other reservations");
                return new LaneSchedulerStateReservationsPair(null, LaneScheduler.GetAlternativeReservations(state, newReservation));
            }
        }
示例#8
0
        public List<LaneSchedulerState> CutInPieces(LaneSchedulerReservation reservation)
        {
            List<LaneSchedulerState> stateList = new List<LaneSchedulerState>();

            // detect cutting lines
            // find cutting line for upper part
            int upperCut = -1;
            for (int i = reservation.StartTimeSlot + reservation.NumberOfTimeSlots; i < this.numberOfTimeSlots; i++)
            {
                bool foundAny = false;
                for (int j = 0; j < this.numberOfLanes; j++)
                {
                    if (this.state[i, j] == this.state[i + 1, j] || this.state[i, j] == this.state[i - 1, j])
                    {
                        foundAny = true;
                    }
                    if (!foundAny)
                    {
                        upperCut = i;
                        break;
                    }
                }
            }
            // find cutting line for lower part
            int lowerCut = -1;
            for (int i = reservation.StartTimeSlot - 1; i >= 0; i--)
            {
                bool foundAny = false;
                for (int j = 0; j < this.numberOfLanes; j++)
                {
                    if (this.state[i, j] == this.state[i + 1, j] || this.state[i, j] == this.state[i - 1, j])
                    {
                        foundAny = true;
                    }
                    if (!foundAny)
                    {
                        lowerCut = i;
                        break;
                    }
                }
            }

            // do the cutting
            LaneSchedulerState stateUpper = new LaneSchedulerState(this.numberOfLanes, this.numberOfTimeSlots, new List<LaneSchedulerReservation>());
            stateUpper.weight = this.weight;
            stateUpper.weight = this.weight;
            stateUpper.state = new int[numberOfTimeSlots, numberOfLanes];

            LaneSchedulerState stateMiddle = new LaneSchedulerState(this.numberOfLanes, this.numberOfTimeSlots, new List<LaneSchedulerReservation>());
            stateMiddle.weight = this.weight;
            stateMiddle.weight = this.weight;
            stateMiddle.state = new int[numberOfTimeSlots, numberOfLanes];

            LaneSchedulerState stateLower = new LaneSchedulerState(this.numberOfLanes, this.numberOfTimeSlots, new List<LaneSchedulerReservation>());
            stateLower.weight = this.weight;
            stateLower.weight = this.weight;
            stateLower.state = new int[numberOfTimeSlots, numberOfLanes];

            // Populate them

            for (int i = 0; i < this.numberOfTimeSlots; i++)
            {
                for (int j = 0; j < this.numberOfLanes; j++)
                {
                    if (i <= lowerCut)
                    {
                        stateLower.state[i, j] = this.state[i, j];
                    }
                    else if (j >= upperCut)
                    {
                        stateMiddle.state[i, j] = this.state[i, j];
                    }
                    else
                    {
                        stateUpper.state[i, j] = this.state[i, j];
                    }
                }
            }
            stateList.Add(stateUpper);
            stateList.Add(stateMiddle);
            stateList.Add(stateLower);
            return stateList;
        }
        public List<Reservation> Convert(LaneSchedulerState state, out Reservation newReservation)
        {
            int [,] internalState = state.State;
            int current = 0;
            newReservation = new Reservation();
            int laneCount = this.laneRepos.GetAll().Count();
            int timeSlotCount = this.timeSlotRepos.GetAll().Count();

            List<ReservationLaneTimeSlotPair> pairs = new List<ReservationLaneTimeSlotPair>();

            for (int i = 0; i < timeSlotCount; i++)
            {
                for (int j = 0; j < laneCount; j++)
                {
                    current = internalState[i, j];
                    if (current == 0)
                    {
                        continue;
                    }
                    var pair = new ReservationLaneTimeSlotPair()
                    {
                        LaneId = j+1,
                        TimeSlotId = i+1,
                        ReservationId = current
                    };

                    pairs.Add(pair);
                }
            }

            // load all reservations besides -1 by first gettting the distinct list of
            // ids, then loading these from db and converting to a dictionary
            // then finally clearing all lane and timeslots from these
            var distinctReservations = (from y in pairs
                                            where y.ReservationId != -1
                                            select y.ReservationId).Distinct<int>().ToList();
            var distinctTimeSlots = (from y in pairs
                                     select y.TimeSlotId).Distinct<int>().ToList();
            var distinctLanes = (from y in pairs
                                 select y.LaneId).Distinct<int>().ToList();

            var reservations = (from y in reservationRepos.GetAll()
                                where distinctReservations.Contains(y.Id)
                                select y).ToDictionary(t => t.Id, t => t);

            var timeslots = (from y in timeSlotRepos.GetAll()
                             where distinctTimeSlots.Contains(y.Id)
                             select y).ToDictionary(t => t.Id, t => t);

            var lanes = (from y in laneRepos.GetAll()
                         where distinctLanes.Contains(y.Id)
                         select y).ToDictionary(t => t.Id, t => t);

            foreach (var r in reservations)
            {
                r.Value.Lanes.Clear();
                r.Value.TimeSlots.Clear();
            }

            // now we can reschedule all of the reservations, and add the lanes and timeslots
            // to the new reservation as well
            foreach (var pair in pairs)
            {
                if (pair.ReservationId == -1)
                {
                    newReservation.AddLane(lanes[pair.LaneId]);
                    newReservation.AddTimeSlot(timeslots[pair.TimeSlotId]);
                    continue;
                }

                reservations[pair.ReservationId].AddLane(lanes[pair.LaneId]);
                reservations[pair.ReservationId].AddTimeSlot(timeslots[pair.TimeSlotId]);

            }

            var toReturn = new List<Reservation>();
            foreach(var r in reservations)
            {
                toReturn.Add(r.Value);
            }
            distinctLanes = null;
            distinctReservations = null;
            distinctTimeSlots = null;

            return toReturn;
        }
示例#10
0
 public LaneSchedulerStateReservationsPair(LaneSchedulerState state, List<LaneSchedulerReservation> reservations)
 {
     this.state = state;
     this.reservations = reservations;
 }