public Room FindRoom(Timeslot t, Course c, Solution s)
        {
            var        roomList   = new List <Room>();
            Room       room       = null;
            Assignment assignment = null;

            c = Instance.Courses.Values.First(x => x.Id == c.Id);

            foreach (var i in Instance.Rooms.Values)
            {
                if (c.ConstraintValidRooms.Where(x => x.Id == i.Id).Count() < 1)
                {
                    roomList.Add(i);
                }
            }
            if (roomList.Where(x => x.Size >= c.Students).Count() > 0)
            {
                roomList = roomList.Where(x => x.Size >= c.Students).ToList();
            }
            foreach (var r in roomList)
            {
                assignment = new Assignment(c, r, t);
                if (s.SlotRoomConstraint(assignment))
                {
                    room = r;
                    break;
                }
            }
            return(room);
        }
        /// <summary>
        /// List as parameter is copied in actual Solution
        /// </summary>
        /// <returns>Copied List</returns>
        public Solution Copy(List <Assignment> assignments)
        {
            List <Assignment> newList = new List <Assignment>();

            foreach (var item in assignments)
            {
                Course c = new Course(
                    item.course.Id, item.course.Teacher, item.course.Lectures, item.course.Students);
                Room r = new Room(item.room.Id);
                r.Size = Instance.Rooms[item.room.Id].Size;
                Timeslot t = new Timeslot(item.timeslot.Day, item.timeslot.Period);

                Assignment a = new Assignment(
                    c, r, t
                    );

                newList.Add(a);
            }

            Solution solution = new Solution
            {
                assignments = newList
            };

            return(solution);
        }
        public bool CheckIfTimeslotIsAvailable(Timeslot timeslot, Course course)
        {
            var notallowed = Instance.Courses[course.Id].ConstraintNotAvaliableTimeslots.FirstOrDefault(x => x.Day == timeslot.Day && x.Period >= timeslot.Period && x.Period <= (timeslot.Period + course.GetPeriods()));

            if (notallowed != null)
            {
                return(false);
            }
            return(true);
        }
 /// <summary>
 /// This function checks period constraint of course
 /// </summary>
 /// <param name="timeslot">Random Timeslot</param>
 /// <param name="course">Course objects to check period constraints</param>
 /// <returns>true or false</returns>
 public bool checkIfTimeslotIsAvailable(Timeslot timeslot, Course course)
 {
     foreach (var item in course.NotAvaliableTimeslots)
     {
         if (timeslot.day != item.day && timeslot.period != item.period)
         {
             return(true);
         }
     }
     return(false);
 }
 public Assignment(Course course, Room room, Timeslot timeslot)
 {
     this.course   = course;
     this.room     = room;
     this.timeslot = timeslot;
 }
        public void GenerateSolution()
        {
            List <Assignment>          assignments = new List <Assignment>();
            Dictionary <int, Timeslot> timeslots   = new Dictionary <int, Timeslot>();

            checkIfValidCurriculum();
            var random = new Random();


            int days            = Schedule.days;
            int periods_per_day = Schedule.periods_per_day;

            int k = 0;

            //filling all timeslots
            for (int i = 0; i < days; i++)
            {
                for (int j = 0; j < periods_per_day; j++)
                {
                    timeslots.Add(k, new Timeslot()
                    {
                        day = i, period = j
                    });
                    k++; // deri i*j = 30
                }
            }

            foreach (var course in Schedule.Courses)
            {
                var randRoom = new Room();
                if (course.Value.NotAvaliableTimeslots.Count > 0)
                {
                    random = new Random();
                    var  timeslot  = new Timeslot();
                    bool validSlot = false;
                    Room room      = new Room();
                    while (validSlot == false)
                    {
                        int rnd = random.Next(timeslots.Count - 1);
                        timeslot  = timeslots[rnd];
                        validSlot = checkIfTimeslotIsAvailable(timeslot, course.Value);
                        room      = Schedule.Rooms.ElementAt(random.Next(Schedule.Rooms.Count - 1)).Value;
                        var   rStatus = checkIfRoomIsAvailable(room, course.Value);
                        int[] slots   = new int[course.Value.lectures * 3];


                        if (rStatus != true)   // checking if room is legal
                        {
                            validSlot = false; // to continue search
                        }
                        else
                        {
                            Assignment asg = new Assignment()
                            {
                                courseId = course.Value.id,
                                roomID   = room.id,
                                day      = timeslot.day,
                                period   = timeslot.period,
                            };
                            assignments.Add(asg);
                            // Console.WriteLine("Room :" + room.id);
                            validSlot = true;
                        }
                    }
                    Console.WriteLine("Course:" + course.Value.id + " Room:" + room.id + " Day: " + timeslot.day + " Period: " + timeslot.period);
                }
                else
                {
                    random = new Random();
                    var  timeslot  = new Timeslot();
                    bool validSlot = false;
                    Room room      = new Room();
                    while (validSlot == false)
                    {
                        int rnd = random.Next(timeslots.Count - 1);
                        timeslot = timeslots[rnd];
                        //validSlot = checkIfTimeslotIsAvailable(timeslot, course.Value);
                        room = Schedule.Rooms.ElementAt(random.Next(Schedule.Rooms.Count - 1)).Value;

                        var   rStatus = checkIfRoomIsAvailable(room, course.Value);
                        int[] slots   = new int[course.Value.lectures * 3];


                        if (rStatus != true) // checking if room is legal
                        {
                            //Assignment asg = new Assignment()
                            //{
                            //    courseId = course.Value.id,
                            //    roomID = room.id,
                            //};
                            //assignments.Add(asg);
                            validSlot = false; // to continue search
                        }
                        else
                        {
                            Assignment asg = new Assignment()
                            {
                                courseId = course.Value.id,
                                roomID   = room.id,
                                day      = timeslot.day,
                                period   = timeslot.period,
                            };
                            assignments.Add(asg);
                            //Console.WriteLine("Room :" + room.id);
                            validSlot = true;
                        }
                    }
                    Console.WriteLine("Course:" + course.Value.id + " Room:" + room.id + " Day: " + timeslot.day + " Period: " + timeslot.period);
                }
                Console.WriteLine("\n-----------------------------------------");
            }
            int a = 0;

            foreach (var asg in assignments)
            {
                a++;
                Console.WriteLine(a + "  Kursi: " + asg.courseId + " Room: " + asg.roomID + " Day: " + asg.day + " Period: " + asg.period);
            }
        }
        public bool FindSlot(int dayIndex, Assignment sol)
        {
            Timeslot   timeslot   = null;
            Assignment assignment = null;
            bool       status     = false;
            Solution   s          = new Solution();

            s = s.Copy(assignments);

            s.assignments.RemoveAll(x => x.course.Id == sol.course.Id);

            Room room = null;

            bool hardConstraints = false;

            for (int j = 0; j < days; j++)
            {
                if (j == dayIndex)
                {
                    continue;
                }
                for (int i = 0; i < periods_per_day - sol.course.GetPeriods(); i++)
                {
                    timeslot = new Timeslot(j, i);
                    if (CheckIfTimeslotIsAvailable(timeslot, sol.course) == false)
                    {
                        continue;
                    }
                    room = FindRoom(timeslot, sol.course, s);
                    if (room == null)
                    {
                        continue;
                    }
                    assignment = new Assignment(sol.course, room, timeslot);

                    if (s.SlotCurriculaConstraint(assignment) == false || s.SlotTeacherConstraint(assignment) == false)
                    {
                        if (i == periods_per_day - sol.course.GetPeriods() - 1)
                        {
                            status          = false;
                            hardConstraints = false;
                            break;
                        }

                        status          = false;
                        hardConstraints = false;
                        continue;
                    }
                    else
                    {
                        status          = true;
                        hardConstraints = true;
                        break;
                    }
                }

                if (status == true)
                {
                    hardConstraints = true;
                    break;
                }
            }

            if (hardConstraints == true)
            {
                s.assignments.Add(assignment);
                assignments.First(x => x.course.Id == assignment.course.Id).timeslot = assignment.timeslot.ShallowCopy();
                assignments.First(x => x.course.Id == assignment.course.Id).room     = assignment.room.ShallowCopy();

                return(true);
            }
            else
            {
                return(false);
            }
        }
        public List <Assignment> GenerateSolution()
        {
            List <Course> anotherList = new List <Course>();

            //order by curricule
            foreach (var cur in Instance.Curricula)
            {
                foreach (var j in cur.Value.CoursesId)
                {
                    if (anotherList.Where(x => x.Id == j).Count() > 0)
                    {
                        continue;
                    }
                    else
                    {
                        anotherList.Add(Instance.Courses[j]);
                    }
                }
            }
            foreach (var c in Instance.Courses.Where(x => x.Value.GetCurriculums().Count < 1))
            {
                anotherList.Add(c.Value);
            }

            Assignment assignment = null;

Restart:
            foreach (var ass in Instance.FixedAssignments)
            {
                assignments.Add(ass);
            }
            foreach (var course in anotherList.Where(p => !Instance.FixedAssignments.Any(p2 => p2.course.Id == p.Id)))
            {
                bool       hardConstraints = false;
                bool       status          = true;
                List <int> daysList        = new List <int> {
                    0, 1, 2, 3, 4
                };
                while (hardConstraints == false)
                {
                    int      randDay  = 0;
                    Timeslot timeslot = null;
                    Random   random   = new Random();

                    //find valid room
                    var  r    = new List <Room>();
                    Room room = null;
                    foreach (var i in Instance.Rooms.Values)
                    {
                        if (course.ConstraintValidRooms.Where(x => x.Id == i.Id).Count() < 1)
                        {
                            r.Add(i);
                        }
                    }
                    if (r.Where(x => x.Size >= course.Students).Count() > 0)
                    {
                        int size = r.Where(x => x.Size >= course.Students).Count();
                        room = r.Where(x => x.Size >= course.Students).ElementAt(random.Next(0, size));
                    }
                    else
                    {
                        room = r.ElementAt(random.Next(0, r.Count()));
                    }

                    if (daysList.Count < 1)
                    {
                        assignments.Clear();
                        goto Restart;
                    }
                    var g = random.Next(0, daysList.Count());
                    randDay = daysList.ElementAt(g);
                    daysList.RemoveAt(g);

                    if (assignments.FirstOrDefault(x => x.timeslot.Day == randDay) != null)
                    {
                        for (int i = 0; i < periods_per_day - course.GetPeriods(); i++)
                        {
                            timeslot = new Timeslot(randDay, i);
                            if (CheckIfTimeslotIsAvailable(timeslot, course) == false)
                            {
                                continue;
                            }
                            assignment = new Assignment(course, room, timeslot);
                            if (SlotRoomConstraint(assignment) == false || SlotCurriculaConstraint(assignment) == false || SlotTeacherConstraint(assignment) == false)
                            {
                                if (i == periods_per_day - course.GetPeriods() - 1)
                                {
                                    hardConstraints = false;
                                    break;
                                }
                                continue;
                            }
                            else
                            {
                                hardConstraints = true;
                                break;
                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < periods_per_day - course.GetPeriods(); i++)
                        {
                            timeslot = new Timeslot(randDay, i);
                            if (CheckIfTimeslotIsAvailable(timeslot, course) == true)
                            {
                                assignment      = new Assignment(course, room, timeslot);
                                hardConstraints = true;
                                break;
                            }
                        }
                    }
                }
                if (status == true)
                {
                    assignments.Add(assignment);
                }
            }
            return(assignments);
        }