示例#1
0
 static void StudentPairValueHandler(StudentPair pair)
 {
     if (pair != null && pair.FirstStudent != null)
     {
         Console.WriteLine($"{pair.SecondStudent.Name} joined {pair.School.Name} {Math.Round(pair.IntervalBetweenJoining.TotalSeconds, 2)} seconds after {pair.FirstStudent.Name}.");
     }
 }
示例#2
0
        static void ObserveStudentsJoiningWithin(TimeSpan timeSpan)
        {
            var school = new School("School 1");

            var admissionObservable =
                Observable.FromEventPattern <StudentAdmittedEventArgs>(school, "StudentAdmitted");

            var observable = admissionObservable.TimeInterval()
                             .Scan <TimeInterval <EventPattern <StudentAdmittedEventArgs> >, StudentPair>(null, (previousPair, current) =>
            {
                Debug.Print(string.Format($"Student joined after {current.Interval.TotalSeconds} seconds, timeSpan = {timeSpan.TotalSeconds} seconds"));

                var pair = new StudentPair();

                if (previousPair == null)
                {
                    pair.FirstStudent           = null;
                    pair.SecondStudent          = current.Value.EventArgs.Student;
                    pair.IntervalBetweenJoining = current.Interval;
                    pair.School = current.Value.EventArgs.School;

                    return(pair);
                }

                if (current.Interval <= timeSpan)
                {
                    pair.FirstStudent           = previousPair.SecondStudent;
                    pair.SecondStudent          = current.Value.EventArgs.Student;
                    pair.IntervalBetweenJoining = current.Interval;
                    pair.School = current.Value.EventArgs.School;

                    return(pair);
                }
                else
                {
                    return(default(StudentPair));
                }
            })
                             .Where(p => (p != default(StudentPair)) && (p.FirstStudent != null));

            var subscription = observable.Subscribe(StudentPairValueHandler);

            school.FillWithStudents(4, TimeSpan.FromSeconds(1));
            school.FillWithStudents(2, TimeSpan.FromSeconds(10));
            school.FillWithStudents(3, TimeSpan.FromSeconds(2));
            school.FillWithStudents(2, TimeSpan.FromSeconds(5));
            school.FillWithStudents(5, TimeSpan.FromSeconds(0.6));

            Console.WriteLine("Press any key to exit the program");
            Console.ReadKey();
            subscription.Dispose();
        }
        private static int costCalc(Student[, ,] toCalc, School[,] schoolCalc)
        {
            int totalCost = 0;
            //let's hope this does not throw the value out of range.
            foreach (School brush in schools)
            {
                foreach (Student paint in brush.attending)
                    totalCost += max*paint.blocks;
            }
            for (int a = 0; a < weekLength; ++a)
            {
                HashSet<Student> lastSet = null;
                for (int b = 0; b < daySlots; ++b)
                {
                    if (schoolCalc[a, b] != null)
                    {
                        HashSet<Student> currentSet = new HashSet<Student>();
                        int nulls = 0;

                        for (int c = 0; c < slots; ++c)
                        {
                            //The hashset has a problem with nulls, so this prevents nulls from getting in.
                            if (toCalc[a, b, c] == null)
                                ++nulls;
                            else
                                currentSet.Add(toCalc[a, b, c]);
                        }
                        foreach (Student afd in currentSet)
                        {
                            //surely there has to be a better way to find the longest run of a student, but this is the best I could think of.
                            if (lastSet != null && !lastSet.Contains(afd))//It makes sure runs aren't counted twice.
                            {
                                int subpos = b;
                                int finds = 0;
                                bool found;
                                do
                                {
                                    found = false;
                                    for (int c = 0; !found && c < slots; ++c)
                                    {
                                        if (afd == toCalc[a, subpos, c])
                                        {
                                            found = true;
                                            ++finds;
                                        }
                                    }
                                    ++subpos;
                                } while (found&&subpos<daySlots);
                                //divide finds by the number of slots per session to get the number of sessions this run composes.  It's formatted like this so that it truncates the sessions to an integer.
                                int slotsTaken=(finds / afd.slotsPerSession);
                                if(afd.name=="Liberty Prime")
                                    System.Console.WriteLine("liberty Prime slots= "+slotsTaken.ToString());

                                totalCost-=slotsTaken*max;

                            }
                            //factor in affinities.
                            foreach (Student ase in currentSet)
                            {
                                StudentPair key = new StudentPair(afd, ase);
                                if (schoolCalc[a, b].affinities.Keys.Contains(key))//Let's hope the optimizer realizes the key for the affinities has to be found within its own hash set
                                    totalCost -= schoolCalc[a, b].affinities[key];
                                if (afd.therapyType != ase.therapyType)
                                    totalCost += diffTherapyCost;

                            }
                            if (!afd.times[a, b])
                                totalCost += max;
                        }
                        //check to see if a school is available at the time it is scheduled here.
                        if (!schoolCalc[a, b].times[a, b])
                            totalCost += max;
                        //This makes sure that a change in schools has at least a half an hour between them.  Hardcoded in for now.  In the future it should be possible to adjust the time between.
                        if ((b >= 1 && schoolCalc[a, b - 1] != null && schoolCalc[a, b - 1] != schoolCalc[a, b]) || (b >= 2 && schoolCalc[a, b - 2] != null && schoolCalc[a, b - 2] != schoolCalc[a, b]))
                            totalCost += max;
                        //calculate all the conflicts by having the same student in the same timeslot.  It works by removing the unique elements from the slots and excluding nulls
                        totalCost += (slots - currentSet.Count - nulls) * max;
                        lastSet = currentSet;
                    }
                    else
                        lastSet = null;
                }

            }

            return totalCost;
        }
 public void modifyRight(Student toPutIn)
 {
     right = toPutIn;
     if (left != null)
         current = new StudentPair(left, right);
 }
            public void modifyLeft(Student toPutIn)
            {

                left = toPutIn;
                if (right != null)
                    current = new StudentPair(left, right);
            }