public bool isAvl(solution X, simpleMove move) { if (move.courseId == null) { return(true); } foreach (var item in X.Constraints) { int t = item.Day * prblm.Periods_per_day + item.Day_Period; if (item.CourseID == move.courseId && t == move.t) { return(false); } } return(true); }
public bool isMoveAv(solution X, string cId, int period, int room) { simpleMove m = new simpleMove(); m.courseId = cId; m.r = room; m.t = period; if (simpleSwapTabuList.Contains(m)) { return(false); } List <string> relatedCourse = new List <string>(); foreach (var item in prblm.Curricula) { if (item.Courses.Contains(cId)) { foreach (var course in item.Courses) { if (course != "" && !relatedCourse.Contains(course)) { relatedCourse.Add(course); } } } } for (int i = 0; i < X.timeTable[period].Length; i++) { foreach (var item in X.timeTable[period]) { if (relatedCourse.Contains(item.CourseID))//this move is not possible!!! { return(false); } } } return(true); }
public bool swap(solution X, int[] swap) { course c1 = X.timeTable[swap[0]][swap[1]]; course c2 = X.timeTable[swap[2]][swap[3]]; if (c1.CourseID != null)//mojaz bodan enteqal ra barasi kon { if (!isMoveAv(X, c1.CourseID, swap[2], swap[3])) { // Console.WriteLine("{0} can't move to {1}",c1.CourseID,swap[2]); impomov++; return false; } } if (c2.CourseID != null)//mojaz bodan enteqal ra barasi kon { if (!isMoveAv(X, c2.CourseID, swap[0], swap[1])) { // Console.WriteLine("{0} can't move to {1}", c2.CourseID, swap[0]); impomov++; return false; } } pomov++; X.timeTable[swap[0]][swap[1]] = c2; X.timeTable[swap[2]][swap[3]] = c1; int c1Index, c2Index; c1Index = c2Index = 0; for (int i = 0; i < prblm.courses.Length; i++) { if (prblm.courses[i].CourseID == c1.CourseID) c1Index = i; if (prblm.courses[i].CourseID == c2.CourseID) c2Index = i; } if (c1.CourseID != null) { simpleMove m1 = new simpleMove(); m1.courseId = c1.CourseID; m1.t = swap[2]; m1.r = swap[3]; X.setNr(c1.CourseID); X.setNd(c1Index); simpleSwapTabuList.Add(m1); } if (c2.CourseID != null) { simpleMove m2 = new simpleMove(); m2.courseId = c2.CourseID; m2.t = swap[0]; m2.r = swap[1]; X.setNr(c2.CourseID); X.setNd(c2Index); simpleSwapTabuList.Add(m2); } return true; }
public bool isMoveAv(solution X, string cId, int period, int room) { simpleMove m = new simpleMove(); m.courseId = cId; m.r = room; m.t = period; if (simpleSwapTabuList.Contains(m)) return false; List<string> relatedCourse = new List<string>(); foreach (var item in prblm.Curricula) { if (item.Courses.Contains(cId)) { foreach (var course in item.Courses) { if (course != "" && !relatedCourse.Contains(course)) relatedCourse.Add(course); } } } for (int i = 0; i < X.timeTable[period].Length; i++) { foreach (var item in X.timeTable[period]) { if (relatedCourse.Contains(item.CourseID))//this move is not possible!!! { return false; } } } return true; }
public bool isAvl(solution X, simpleMove move) { if (move.courseId == null) return true; foreach (var item in X.Constraints) { int t = item.Day * prblm.Periods_per_day + item.Day_Period; if (item.CourseID == move.courseId && t == move.t) return false; } return true; }
/// <summary> /// tabu search /// </summary> /// <param name="X">a feasible initial solution</param> /// <param name="theta">θ:the depth of TS</param> /// <returns>X best :best solution found so far</returns> public solution TS(solution X, int theta) { int loops = theta; solution Xbest = new solution(); solutionCopier.copy(X, out Xbest);//make a deep copy of X to Xbest simpleSwapList = new List<int[]>(); poindex = 0; int r1, r2, t1, t2; int len = X.timeTable.Length * X.timeTable[0].Length; for (int i = 0; i < len; i++) { for (int j = i + 1; j < len; j++) { // simswap[0]:t1 // simswap[1]:r1 // simswap[2]:t2 // simswap[3]:r2 int[] simswap = new int[4]; t1 = simswap[0] = i / X.timeTable[0].Length; r1 = simswap[1] = i % X.timeTable[0].Length; t2 = simswap[2] = j / X.timeTable[0].Length; r2 = simswap[3] = +j % X.timeTable[0].Length; string course1 = X.timeTable[t1][r1].CourseID; string course2 = X.timeTable[t2][r2].CourseID; simpleMove m1 = new simpleMove(); simpleMove m2 = new simpleMove(); m1.courseId = course1; m1.r = r2; m1.t = t2; m2.courseId = course2; m2.r = r1; m2.t = t1; if (isAvl(X, m1) && isAvl(X, m2)) { if (m1.courseId != null || m2.courseId != null) simpleSwapList.Add(simswap); // if (m1.courseId != null && m2.courseId != null) //Console.WriteLine("{0} , {1}",m1.courseId, m2.courseId); } } } do { solutionCopier.copy(TSN1(X, theta), out Xstar); solutionCopier.copy(TSN2(Xstar, (int)(theta / 3)), out XstarPrime); double costXstarPrime, costXbest; costXbest = validator.getCost(prblm, Xbest); costXstarPrime = validator.getCost(prblm, XstarPrime); if (costXstarPrime < costXbest) { // Console.Write("{0} < {1} < {2}\n",validator.getCost( prblm,Xstar), costXstarPrime,costXbest); solutionCopier.copy(XstarPrime, out Xbest); solutionCopier.copy(XstarPrime, out X); } } while (loops-- > 0); return Xbest; }
public Move chooseMove(Game game, Player player) { Dictionary <simpleMove, MoveScore> moveResults = new Dictionary <simpleMove, MoveScore>(); // have to treat this player as if they will play random in these sub-games, not as monte carlo var currentController = player.Controller; player.Controller = new ControllerRandom(); var currentLogSettings = game.rules.LoggingSettings; object scorelock = new object(); // for monte carlo we should play out n random games and track how our next move might win or lose for (int i = 0; i < GamesToRun; i++) //Parallel.For(0, GamesToRun, (i) => { System.Diagnostics.Debug.Indent(); if (game.rules.LoggingSettings.showEachPlayersPlanning || ShowSubResults) { Console.WriteLine("Running sub-game"); } // create a copy of the game and play it through with what we know so far Game testgame = new Game(game); // becomes an infinitely recursive problem since every sub-game is also monte carlo testgame.rules.MaxPhysicalTurns = MaxSubGameDepth; if (!ShowSubGames) { testgame.rules.LoggingSettings = new GameRules.LogSettings() { logTime = false, showEachPlayersPlanning = false, showStatePerTurn = false, pausePerMove = false, winLossReasons = false, debugJumpchecks = false, showMovePerTurn = false, listMoveSeqenceAtEnd = false, showBombDefusals = false, showHiddenPieces = false, }; } // randomize any unknown pieces on the board if (testgame.CurrentBoard.PieceSet.Any(x => x.IsRevealed == false && x.Owner != player)) { List <CoordAbs> availableSpaces = new List <CoordAbs>(); // randomize any unknown piece and play through foreach (Piece unknownPiece in testgame.CurrentBoard.PieceSet.Where( x => x.IsRevealed == false && x.Owner != player)) { availableSpaces.Add(unknownPiece.pos); unknownPiece.turnRevealed = -1; // place holder to indicate piece is being moved testgame.CurrentBoard.PiecesLayout[unknownPiece.pos.X, unknownPiece.pos.Y] = null; } Random rand = new Random(); foreach (Piece unknownPiece in testgame.CurrentBoard.PieceSet.Where(x => x.turnRevealed == -1)) { // hide the piece again unknownPiece.turnRevealed = null; // assign it a random location from the spots available int ran = rand.Next(0, availableSpaces.Count); unknownPiece.pos = availableSpaces[ran]; availableSpaces.RemoveAt(ran); testgame.CurrentBoard.PiecesLayout[unknownPiece.pos.X, unknownPiece.pos.Y] = unknownPiece; } } // DIFFERENCE FROM MONTE CARLO - // weigh the state based on number of pieces we own instead of win/lose var results = testgame.Run(); int score = 0; if (results.Winners.Count == 1 && results.Winners.Contains(player)) // WIN { score = 100; } else if (results.Winners.Count == 1 && results.Winners.Contains(player)) // LOSS { score = -100; } else { score = testgame.CurrentBoard.PieceSet.Count(x => x.Owner == player); } // lookup via string instead of object Move firstMove = testgame.MoveSequence.FirstOrDefault().Value; // remember move sequence is <turn, move> if (firstMove == null) { continue; } simpleMove simple = new simpleMove() { from = firstMove.FromCoord, to = firstMove.ToCoord, }; MoveScore mscore = new MoveScore(); lock (scorelock) { if (moveResults.Keys.Contains(simple)) { mscore = moveResults[simple]; mscore.occurances++; mscore.totalScore += score; moveResults[simple] = mscore; } else { mscore.totalScore = score; mscore.occurances = 1; moveResults.Add(simple, mscore); } } if (game.rules.LoggingSettings.showEachPlayersPlanning || ShowSubResults) { Console.WriteLine($"{firstMove} ... => {score}, x{moveResults[simple].occurances} Total = {(moveResults[simple].totalScore / moveResults[simple].occurances)}"); } System.Diagnostics.Debug.Unindent(); } ; // reset back to original settings player.Controller = currentController; game.rules.LoggingSettings = currentLogSettings; // do the move that has the most win options // Note: the liklihood of making the same move, with 1000 randomized boards seems infinitely tiny, let alone useful var bestMoveStats = moveResults.OrderByDescending(x => x.Value.totalScore / x.Value.occurances).FirstOrDefault(); if (game.rules.LoggingSettings.showEachPlayersPlanning || ShowSubResults) { Console.WriteLine("Best move from subgames: " + bestMoveStats.Key.from + " to " + bestMoveStats.Key.to + " w/ avg score " + (bestMoveStats.Value.totalScore / bestMoveStats.Value.occurances)); } var bestMove = bestMoveStats.Key; if (bestMove.from == null) // if there is no moves available then return null and be removed from game { return(null); } // convert the sub-game move into a move that is applicable to the current game var relevantMove = new Move( game.CurrentBoard.GetPieceAtCoord(bestMove.from), bestMove.to, game.CurrentBoard, game.rules ); return(relevantMove); }
public bool swap(solution X, int[] swap) { course c1 = X.timeTable[swap[0]][swap[1]]; course c2 = X.timeTable[swap[2]][swap[3]]; if (c1.CourseID != null)//mojaz bodan enteqal ra barasi kon { if (!isMoveAv(X, c1.CourseID, swap[2], swap[3])) { // Console.WriteLine("{0} can't move to {1}",c1.CourseID,swap[2]); impomov++; return(false); } } if (c2.CourseID != null)//mojaz bodan enteqal ra barasi kon { if (!isMoveAv(X, c2.CourseID, swap[0], swap[1])) { // Console.WriteLine("{0} can't move to {1}", c2.CourseID, swap[0]); impomov++; return(false); } } pomov++; X.timeTable[swap[0]][swap[1]] = c2; X.timeTable[swap[2]][swap[3]] = c1; int c1Index, c2Index; c1Index = c2Index = 0; for (int i = 0; i < prblm.courses.Length; i++) { if (prblm.courses[i].CourseID == c1.CourseID) { c1Index = i; } if (prblm.courses[i].CourseID == c2.CourseID) { c2Index = i; } } if (c1.CourseID != null) { simpleMove m1 = new simpleMove(); m1.courseId = c1.CourseID; m1.t = swap[2]; m1.r = swap[3]; X.setNr(c1.CourseID); X.setNd(c1Index); simpleSwapTabuList.Add(m1); } if (c2.CourseID != null) { simpleMove m2 = new simpleMove(); m2.courseId = c2.CourseID; m2.t = swap[0]; m2.r = swap[1]; X.setNr(c2.CourseID); X.setNd(c2Index); simpleSwapTabuList.Add(m2); } return(true); }
/// <summary> /// tabu search /// </summary> /// <param name="X">a feasible initial solution</param> /// <param name="theta">θ:the depth of TS</param> /// <returns>X best :best solution found so far</returns> public solution TS(solution X, int theta) { int loops = theta; solution Xbest = new solution(); solutionCopier.copy(X, out Xbest);//make a deep copy of X to Xbest simpleSwapList = new List <int[]>(); poindex = 0; int r1, r2, t1, t2; int len = X.timeTable.Length * X.timeTable[0].Length; for (int i = 0; i < len; i++) { for (int j = i + 1; j < len; j++) { // simswap[0]:t1 // simswap[1]:r1 // simswap[2]:t2 // simswap[3]:r2 int[] simswap = new int[4]; t1 = simswap[0] = i / X.timeTable[0].Length; r1 = simswap[1] = i % X.timeTable[0].Length; t2 = simswap[2] = j / X.timeTable[0].Length; r2 = simswap[3] = +j % X.timeTable[0].Length; string course1 = X.timeTable[t1][r1].CourseID; string course2 = X.timeTable[t2][r2].CourseID; simpleMove m1 = new simpleMove(); simpleMove m2 = new simpleMove(); m1.courseId = course1; m1.r = r2; m1.t = t2; m2.courseId = course2; m2.r = r1; m2.t = t1; if (isAvl(X, m1) && isAvl(X, m2)) { if (m1.courseId != null || m2.courseId != null) { simpleSwapList.Add(simswap); } // if (m1.courseId != null && m2.courseId != null) //Console.WriteLine("{0} , {1}",m1.courseId, m2.courseId); } } } do { solutionCopier.copy(TSN1(X, theta), out Xstar); solutionCopier.copy(TSN2(Xstar, (int)(theta / 3)), out XstarPrime); double costXstarPrime, costXbest; costXbest = validator.getCost(prblm, Xbest); costXstarPrime = validator.getCost(prblm, XstarPrime); if (costXstarPrime < costXbest) { // Console.Write("{0} < {1} < {2}\n",validator.getCost( prblm,Xstar), costXstarPrime,costXbest); solutionCopier.copy(XstarPrime, out Xbest); solutionCopier.copy(XstarPrime, out X); } } while (loops-- > 0); return(Xbest); }//end of TS