/// <summary> /// زمان - مان متانسب با هیورستیک 2 مقاله را پیدا میکند /// </summary> /// <param name="cindex">اندیس درس انتخاب شده برای انتساب زمان - مکان</param> /// <returns>[0]: period [1]: room </returns> public int[] HR2(int cindex) { k1 = 1; k2 = 0.5; int[] pos = new int[2]; pos[0] = -1; pos[1] = -1; List <int> uavtimes = new List <int>(); uavtimes = getUavPeriods(cindex); double minCost = double.MaxValue; int[] bestPos = new int[2]; bestPos[0] = -1; bestPos[1] = -1; for (int t = 0; t < p.Periods_per_day * p.Days; t++) { if (!uavtimes.Contains(t)) { for (int r = 0; r < p.Rooms.Length; r++) { if (timeTable[t][r].CourseID == null) { int[] pr = new int[2]; pr[0] = t / p.Days; pr[1] = t % p.Periods_per_day; solution tempSol = new solution(); solutionCopier.copy(this, out tempSol); tempSol.insertLecture(cindex, t, r); double cost = k1 * uac(cindex, pr) + k2 * validator.getCost(p, tempSol); if (cost < minCost) { minCost = cost; bestPos[0] = t; bestPos[1] = r; } } } } } return(bestPos); }
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); }
/// <summary> /// تابع سازنده کلاس که شروع به حل مساله میکند /// </summary> /// <param name="input">نام فایل ورودی</param> /// <param name="output">نام فایل خروجی</param> public tabuSolver(string input, string output) { pomov = 0; impomov = 0; try { IReader = new StreamReader(input); OWriter = new StreamWriter(output); logWriter = new StreamWriter("log_" + output); } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine("press any to exit..."); Console.Read(); return; } DateTime startRuntime = new DateTime(); startRuntime = DateTime.Now; readInput(out prblm);//Algorithm 3 line 1 Xi = 0; theta = theta0 = 10; Eta = EtaMin = 4; EtaMax = 15; landa = 0.3; simpleSwapTabuList = new List<simpleMove>(); kempeSwapTabuList = new List<kempeSwap>(); X0.initSol(prblm); int[] pos = new int[2]; do { int ci = X0.HR1(); pos = X0.HR2(ci); X0.insertLecture(ci, pos[0], pos[1]); //OWriter.WriteLine(prblm.courses[ci].CourseID + " " + prblm.Rooms[pos[1]].ID + " " + pos[0] / prblm.Periods_per_day + " " + pos[0] % prblm.Periods_per_day); logWriter.WriteLine("ci:" + ci + " " + prblm.courses[ci].CourseID + " " + prblm.Rooms[pos[1]].ID + " " + pos[0] / prblm.Periods_per_day + " " + pos[0] % prblm.Periods_per_day); Console.WriteLine("ci:" + ci + " " + prblm.courses[ci].CourseID + " " + prblm.Rooms[pos[1]].ID + " " + pos[0] / prblm.Periods_per_day + " " + pos[0] % prblm.Periods_per_day); } while (X0.LC.Count > 0 && pos[0] != -1);//end of part1: initialization poindex = 0; Xstar = new solution(); solutionCopier.copy(X0, out Xstar); solutionCopier.copy(TS(X0, theta), out Xstar); int loopCount1 = 10; int loopCount2 = 20; int tbcouner = 0; do { loopCount1 = 10; solutionCopier.copy(perturb(Xstar, Eta), out Xprime); solutionCopier.copy(TS(Xprime, theta), out XstarPrime); double XstarPrime_Cost = validator.getCost(prblm, XstarPrime); double Xstar_Cost = validator.getCost(prblm, Xstar); if (XstarPrime_Cost < Xstar_Cost + 2) { do { theta = (int)(1.6 * theta0); solutionCopier.copy(TS(Xprime, theta), out XstarPrime); } while (loopCount1-- > 0); } if (validator.getCost(prblm, XstarPrime) < validator.getCost(prblm, Xstar)) { solutionCopier.copy(XstarPrime, out Xstar); theta = theta0; Eta = EtaMin; } else { theta = theta0; Xi++; Eta = Math.Max((int)(EtaMin + landa * Xi), EtaMax); } Console.WriteLine("tabu list count = {0}", simpleSwapTabuList.Count); Console.WriteLine("cost = {0}", validator.getCost(prblm, Xstar)); logWriter.WriteLine("tabu list count = {0}", simpleSwapTabuList.Count); logWriter.WriteLine("cost = {0}", validator.getCost(prblm, Xstar)); if (tbcouner != 0 && tbcouner == simpleSwapTabuList.Count) { loopCount2 = 0; } else { tbcouner = simpleSwapTabuList.Count; } } while (loopCount2-- > 0); for (int t = 0; t < Xstar.timeTable.Length; t++) { for (int r = 0; r < Xstar.timeTable[0].Length; r++) { course c = Xstar.timeTable[t][r]; if(c.CourseID!=null){ OWriter.WriteLine(c.CourseID + " " + prblm.Rooms[r].ID + " " + t / prblm.Periods_per_day + " " + t % prblm.Periods_per_day); } } } OWriter.Close(); DateTime endRuntime = new DateTime(); endRuntime = DateTime.Now; Console.WriteLine("{0} possible moves \n{1} impossible move \n", pomov, impomov); Console.WriteLine("run time = {0}", endRuntime - startRuntime); logWriter.WriteLine("{0} possible moves \n {1} impossible move \n", pomov, impomov); logWriter.WriteLine("run time = {0}", endRuntime - startRuntime); logWriter.Close(); Console.WriteLine("press any to exit..."); Console.Read(); }
/// <summary> /// make a deep copy of solution s to solution d /// </summary> /// <param name="s">source solution</param> /// <param name="d">destination solution</param> public static void copy(solution s, out solution d) { d = new solution(); d.p = s.p; d.apd = new int[s.apd.Length]; d.aps = new int[s.aps.Length]; d.arm = new int[s.arm.Length]; d.Constraints = new List<UNAVAILABILITY_CONSTRAINT>(); for (int i = 0; i <s.Constraints.Count; i++) { UNAVAILABILITY_CONSTRAINT Constraint = new UNAVAILABILITY_CONSTRAINT(); Constraint.CourseID = s.Constraints[i].CourseID; Constraint.Day = s.Constraints[i].Day; Constraint.Day_Period = s.Constraints[i].Day_Period; d.Constraints.Add(Constraint); } d.LC = new Dictionary<int, course>(); foreach (var item in s.LC) { d.LC.Add(item.Key, item.Value);// its not a deep copy of s.LC } d.nd = new int[s.nd.Length]; d.nl = new int[s.nl.Length]; d.nr = new int[s.nr.Length]; for (int i = 0; i < s.nl.Length; i++) { d.apd[i] = s.apd[i]; d.aps[i] = s.aps[i]; d.arm[i] = s.arm[i]; d.nd[i] = s.nd[i]; d.nl[i] = s.nl[i]; d.nr[i] = s.nr[i]; } d.timeTable = new course[s.timeTable.Length][]; for (int i = 0; i < s.timeTable.Length; i++) { d.timeTable[i] = new course[s.timeTable[i].Length]; for (int j = 0; j < s.timeTable[i].Length; j++) { d.timeTable[i][j] = s.timeTable[i][j]; } } }
/// <summary> /// زمان - مان متانسب با هیورستیک 2 مقاله را پیدا میکند /// </summary> /// <param name="cindex">اندیس درس انتخاب شده برای انتساب زمان - مکان</param> /// <returns>[0]: period [1]: room </returns> public int[] HR2(int cindex) { k1 = 1; k2 = 0.5; int[] pos = new int[2]; pos[0] = -1; pos[1] = -1; List<int> uavtimes=new List<int>(); uavtimes = getUavPeriods(cindex); double minCost = double.MaxValue; int[] bestPos = new int[2]; bestPos[0] = -1; bestPos[1] = -1; for (int t = 0; t < p.Periods_per_day*p.Days; t++) { if (!uavtimes.Contains(t)) { for (int r = 0; r < p.Rooms.Length; r++) { if(timeTable[t][r].CourseID==null){ int[] pr = new int[2]; pr[0] = t / p.Days; pr[1] = t % p.Periods_per_day; solution tempSol = new solution(); solutionCopier.copy(this, out tempSol); tempSol.insertLecture(cindex, t, r); double cost = k1 * uac(cindex, pr) + k2 * validator.getCost(p, tempSol); if (cost < minCost) { minCost = cost; bestPos[0] = t; bestPos[1] = r; }} } } } return bestPos; }
public static int iso(solution X,int q, int i) { if ((i % P.Periods_per_day == 1 && X.app(q, i - 1) == 0) || (i % P.Periods_per_day == 0 && X.app(q, i + 1) == 0)) { return 1; } return 0; }
public static double getCost(problemInstance p, solution x) { alpha1 = 1; alpha2 = 1; alpha3 = 5; alpha4 = 2; P = p; if (x.apd == null) { X = x; } X = x; return f(); }
/// <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
public solution perturb(solution Xstar, int Eta) { poindex += Eta; return Xstar; }
/// <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; }
/// <summary> /// تابع سازنده کلاس که شروع به حل مساله میکند /// </summary> /// <param name="input">نام فایل ورودی</param> /// <param name="output">نام فایل خروجی</param> public tabuSolver(string input, string output) { pomov = 0; impomov = 0; try { IReader = new StreamReader(input); OWriter = new StreamWriter(output); logWriter = new StreamWriter("log_" + output); } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine("press any to exit..."); Console.Read(); return; } DateTime startRuntime = new DateTime(); startRuntime = DateTime.Now; readInput(out prblm);//Algorithm 3 line 1 Xi = 0; theta = theta0 = 10; Eta = EtaMin = 4; EtaMax = 15; landa = 0.3; simpleSwapTabuList = new List <simpleMove>(); kempeSwapTabuList = new List <kempeSwap>(); X0.initSol(prblm); int[] pos = new int[2]; do { int ci = X0.HR1(); pos = X0.HR2(ci); X0.insertLecture(ci, pos[0], pos[1]); //OWriter.WriteLine(prblm.courses[ci].CourseID + " " + prblm.Rooms[pos[1]].ID + " " + pos[0] / prblm.Periods_per_day + " " + pos[0] % prblm.Periods_per_day); logWriter.WriteLine("ci:" + ci + " " + prblm.courses[ci].CourseID + " " + prblm.Rooms[pos[1]].ID + " " + pos[0] / prblm.Periods_per_day + " " + pos[0] % prblm.Periods_per_day); Console.WriteLine("ci:" + ci + " " + prblm.courses[ci].CourseID + " " + prblm.Rooms[pos[1]].ID + " " + pos[0] / prblm.Periods_per_day + " " + pos[0] % prblm.Periods_per_day); } while (X0.LC.Count > 0 && pos[0] != -1);//end of part1: initialization poindex = 0; Xstar = new solution(); solutionCopier.copy(X0, out Xstar); solutionCopier.copy(TS(X0, theta), out Xstar); int loopCount1 = 10; int loopCount2 = 20; int tbcouner = 0; do { loopCount1 = 10; solutionCopier.copy(perturb(Xstar, Eta), out Xprime); solutionCopier.copy(TS(Xprime, theta), out XstarPrime); double XstarPrime_Cost = validator.getCost(prblm, XstarPrime); double Xstar_Cost = validator.getCost(prblm, Xstar); if (XstarPrime_Cost < Xstar_Cost + 2) { do { theta = (int)(1.6 * theta0); solutionCopier.copy(TS(Xprime, theta), out XstarPrime); } while (loopCount1-- > 0); } if (validator.getCost(prblm, XstarPrime) < validator.getCost(prblm, Xstar)) { solutionCopier.copy(XstarPrime, out Xstar); theta = theta0; Eta = EtaMin; } else { theta = theta0; Xi++; Eta = Math.Max((int)(EtaMin + landa * Xi), EtaMax); } Console.WriteLine("tabu list count = {0}", simpleSwapTabuList.Count); Console.WriteLine("cost = {0}", validator.getCost(prblm, Xstar)); logWriter.WriteLine("tabu list count = {0}", simpleSwapTabuList.Count); logWriter.WriteLine("cost = {0}", validator.getCost(prblm, Xstar)); if (tbcouner != 0 && tbcouner == simpleSwapTabuList.Count) { loopCount2 = 0; } else { tbcouner = simpleSwapTabuList.Count; } } while (loopCount2-- > 0); for (int t = 0; t < Xstar.timeTable.Length; t++) { for (int r = 0; r < Xstar.timeTable[0].Length; r++) { course c = Xstar.timeTable[t][r]; if (c.CourseID != null) { OWriter.WriteLine(c.CourseID + " " + prblm.Rooms[r].ID + " " + t / prblm.Periods_per_day + " " + t % prblm.Periods_per_day); } } } OWriter.Close(); DateTime endRuntime = new DateTime(); endRuntime = DateTime.Now; Console.WriteLine("{0} possible moves \n{1} impossible move \n", pomov, impomov); Console.WriteLine("run time = {0}", endRuntime - startRuntime); logWriter.WriteLine("{0} possible moves \n {1} impossible move \n", pomov, impomov); logWriter.WriteLine("run time = {0}", endRuntime - startRuntime); logWriter.Close(); Console.WriteLine("press any to exit..."); Console.Read(); }
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 solution perturb(solution Xstar, int Eta) { poindex += Eta; return(Xstar); }
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 solution TSN1(solution X, int theta) { solution tempX = new solution(); solutionCopier.copy(X, out tempX); double cost2 = validator.getCost(prblm, Xstar); double cost1 = 10000000000; Random r = new Random(); //int index = r.Next(simpleSwapList.Count); int maxUav = 200; do { if (++poindex < simpleSwapList.Count - 1) { int index = r.Next(simpleSwapList.Count); bool re = swap(tempX, simpleSwapList[poindex]); if (!re) { // maxUav--; theta++; if (maxUav == 0) theta = 0; } } cost1 = validator.getCost(prblm, tempX); if (cost1 < cost2) { theta++; return tempX; } else { if (cost1 > cost2 + 10) { solutionCopier.copy(X, out tempX); } } } while (theta-- > 0); if (cost1 < cost2) return tempX; return Xstar; }
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 solution TSN2(solution X, int theta) { solution tempX = new solution(); solutionCopier.copy(X, out tempX); do { } while (theta-- > 0); return tempX; }