public void CheckSpp(SppStruct spp)//check spp to see if it is possible. otherwise raises exception { CanPickupPerson(spp.s, spp.p1); CanPickupPerson(spp.s, spp.p2); CanMoveTo(spp.s, spp.p1, spp.p2); //Checks if p1 can go in place of p2 CanMoveTo(spp.s, spp.p2, spp.p1); //checks if p2 can go near p1 }
public SppStruct GetSPP()//service-person-person { if (SppRepository.Count > 0) { int r = rnd.Next(SppRepository.Count); SppStruct temp = SppRepository[r]; SppRepository.RemoveAt(r); return(temp); } else { throw new HaltException("No more change possible"); } }
static void Main(string[] args) { /* * 3*[5|5|5|7] * [5|5|7|8][5|5|7|8] */ Console.WriteLine("Please enter the number of services: "); String str = Console.ReadLine(); int serviceCount = int.Parse(str); List <List <int> > formule = new List <List <int> >(); /* the commented section is for the cases that there is different table number with different capacity in services * for (int i = 0; i < serviceCount; i++) * { * Console.WriteLine("Please enter the number of tables on service " + i + " : "); * str = Console.ReadLine(); * int tableCount = int.Parse(str); * List<int> tableCapacities = new List<int>(); * for (int j = 0; j < tableCount; j++) * { * Console.WriteLine("Please enter the capacity of table {0} of service {1}", j, i); * str = Console.ReadLine(); * int t = int.Parse(str); * tableCapacities.Add(t); * } * formule.Add(tableCapacities); * }*/ Console.Write("Please enter the number of tables in each service: "); str = Console.ReadLine(); int tableCount = int.Parse(str); Console.Write("Please enter the capacity of tables: "); str = Console.ReadLine(); int tableCapacity = int.Parse(str); int friendCount = tableCapacity + 1; while (friendCount > tableCapacity) { Console.Write("Please enter the number of friends (ones who want to sit together): "); str = Console.ReadLine(); friendCount = int.Parse(str); if (friendCount > tableCapacity) { Console.Write("Should be less than table capacity ({0}) ", tableCapacity); } } int enemyCount = tableCount + 1; while (enemyCount > tableCount) { Console.Write("Please enter the number of enemies (ones who dont want to sit together): "); str = Console.ReadLine(); enemyCount = int.Parse(str); if (enemyCount > tableCount) { Console.Write("Should be less than table count ({0}) ", tableCount); } } Random rnd = new Random(); Session session = new Session(); for (int i = 0; i < serviceCount; i++) { Service service = new Service(); for (int j = 0; j < tableCount; j++) { service.Add(new Table()); } session.Add(service); } for (int k = 0; k < serviceCount; k++) { for (int i = 0; i < friendCount; i++) { session[k][0].Add(i);//add friends on service k table 0 } } for (int k = 0; k < serviceCount; k++) { for (int i = friendCount; i < enemyCount && session[k][i].Count < tableCapacity; i++) { session[k][i].Add(i); } } int start = friendCount + enemyCount; int total = tableCount * tableCapacity; for (int i = 0; i < serviceCount; i++) { int j = 0; for (int k = start; k < total; k++)//rest of persons for each service { if (session[i][j].Count < tableCapacity) { session[i][j].Add(k); } else { j++; session[i][j].Add(k); } } } //session = LoadSession(); //List<Visit> rencontres = session.ComputeVisits(); /*List<int> p1Candidates = new List<int>(); * var collisions = rencontres.GroupBy(visit => new { visit.Visitor1, visit.Visitor2 }, * visit => visit, * (visKey, visits) => new { A = visits.First().Visitor1, B = visits.First().Visitor2, Count = visits.Count() }) * .Where(g => g.Count > 1) * * .Distinct(); * foreach (var col in collisions) * { * Console.WriteLine(col); * } */ int minScore = serviceCount * friendCount * (friendCount - 1) / 2; //session.Initialize(); int score = session.ReEvaluateScore(); bool accepted = false; int minIterations = 1000; int iterationsCount = minIterations; session.ReloadSppRepository(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); bool mayExists = true; int scoreBeforeLoop = score; int counter = 0; //counts the number of series of loops without success int iterationsSofar = 0; int pointCounter = 0; //counts the number of points written on console after conflict count try { while (mayExists) { for (int i = 0; i < iterationsCount && score > minScore; i++) { iterationsSofar++; SppStruct spp = session.GetSPP(); accepted = false; // boolean shows if spp is accepted by the session while (!accepted) //always enters { try { session.CheckSpp(spp); session.ChangePlaces(spp.s, spp.p1, spp.p2); accepted = true;//if no exception means accepted } catch (Exception ex) { try { spp = session.GetSPP(); } catch (Exception exp)//no more change { throw exp; } } } int newscore = session.ReEvaluateScore(); //Console.WriteLine("newscore{0}", newscore); if (newscore > score) { //Console.WriteLine("refused"); session.ChangePlaces(spp.s, spp.p2, spp.p1); } else { Console.Write("\r Conflicts {0} iteration {1} from {2} {3} ", newscore, i, iterationsCount, GetPoints(pointCounter)); score = newscore; session.Success(); } if (pointCounter >= 5) { pointCounter = 0; } pointCounter++; } if (score == minScore) { mayExists = false; } else { if (scoreBeforeLoop == score) { if (counter < 1) { counter++; iterationsCount = (minIterations > iterationsSofar) ? minIterations : iterationsSofar; } else { mayExists = false; } } else//had progression { if (iterationsSofar > minIterations) { iterationsCount = iterationsSofar; } else { iterationsCount = minIterations; } scoreBeforeLoop = score; counter = 0; } } } } catch (HaltException exp) { Console.WriteLine(session); } Console.WriteLine(session); Console.ReadKey(); }