static void Main(string[] args) { try { int n = 10; if (args.Length > 0) { n = Int32.Parse(args[0]); } if ((n % 2) == 1) { n++; } Console.WriteLine("Finding schedule for {0} teams", n); int nbWeeks = 2 * (n - 1); int nbGamesPerWeek = n / 2; int nbGames = n * (n - 1); CP cp = new CP(); IIntVar[][] games = new IIntVar[nbWeeks][]; IIntVar[][] home = new IIntVar[nbWeeks][]; IIntVar[][] away = new IIntVar[nbWeeks][]; for (int i = 0; i < nbWeeks; i++) { home[i] = cp.IntVarArray(nbGamesPerWeek, 0, n - 1); away[i] = cp.IntVarArray(nbGamesPerWeek, 0, n - 1); games[i] = cp.IntVarArray(nbGamesPerWeek, 0, nbGames - 1); } // // For each play slot, set up correspondance between game id, // home team, and away team // IIntTupleSet gha = cp.IntTable(3); int[] tuple = new int[3]; for (int i = 0; i < n; i++) { tuple[0] = i; for (int j = 0; j < n; j++) { if (i != j) { tuple[1] = j; tuple[2] = Game(i, j, n); cp.AddTuple(gha, tuple); } } } for (int i = 0; i < nbWeeks; i++) { for (int j = 0; j < nbGamesPerWeek; j++) { IIntVar[] vars = cp.IntVarArray(3); vars[0] = home[i][j]; vars[1] = away[i][j]; vars[2] = games[i][j]; cp.Add(cp.AllowedAssignments(vars, gha)); } } // // All teams play each week // for (int i = 0; i < nbWeeks; i++) { IIntVar[] teamsThisWeek = cp.IntVarArray(n); for (int j = 0; j < nbGamesPerWeek; j++) { teamsThisWeek[j] = home[i][j]; teamsThisWeek[nbGamesPerWeek + j] = away[i][j]; } cp.Add(cp.AllDiff(teamsThisWeek)); } // // Dual representation: for each game id, the play slot is maintained // IIntVar[] weekOfGame = cp.IntVarArray(nbGames, 0, nbWeeks - 1); IIntVar[] allGames = cp.IntVarArray(nbGames); IIntVar[] allSlots = cp.IntVarArray(nbGames, 0, nbGames - 1); for (int i = 0; i < nbWeeks; i++) { for (int j = 0; j < nbGamesPerWeek; j++) { allGames[i * nbGamesPerWeek + j] = games[i][j]; } } cp.Add(cp.Inverse(allGames, allSlots)); for (int i = 0; i < nbGames; i++) { cp.Add(cp.Eq(weekOfGame[i], cp.Div(allSlots[i], nbGamesPerWeek))); } // // Two half schedules. Cannot play the same pair twice in the same half. // Plus, impose a minimum number of weeks between two games involving // the same teams (up to six weeks) // int mid = nbWeeks / 2; int overlap = 0; if (n >= 6) { overlap = min(n / 2, 6); } for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { int g1 = Game(i, j, n); int g2 = Game(j, i, n); cp.Add(cp.Equiv(cp.Ge(weekOfGame[g1], mid), cp.Lt(weekOfGame[g2], mid))); // Six week difference... if (overlap != 0) { cp.Add(cp.Ge(cp.Abs(cp.Diff(weekOfGame[g1], weekOfGame[g2])), overlap)); } } } // // Can't have three homes or three aways in a row. // IIntVar[][] playHome = new IIntVar[n][]; for (int i = 0; i < n; i++) { playHome[i] = cp.IntVarArray(nbWeeks, 0, 1); for (int j = 0; j < nbWeeks; j++) { cp.Add(cp.Eq(playHome[i][j], cp.Count(home[j], i))); } for (int j = 0; j < nbWeeks - 3; j++) { IIntVar[] window = cp.IntVarArray(3); for (int k = j; k < j + 3; k++) { window[k - j] = playHome[i][k]; } IIntExpr windowSum = cp.Sum(window); cp.Add(cp.Le(1, windowSum)); cp.Add(cp.Le(windowSum, 2)); } } // // If we start the season home, we finish away and vice versa. // for (int i = 0; i < n; i++) { cp.Add(cp.Neq(playHome[i][0], playHome[i][nbWeeks - 1])); } // // Objective: minimize the number of `breaks'. A break is // two consecutive home or away matches for a // particular team IIntVar[] teamBreaks = cp.IntVarArray(n, 0, nbWeeks / 2); for (int i = 0; i < n; i++) { IIntExpr nbreaks = cp.Constant(0); for (int j = 1; j < nbWeeks; j++) { nbreaks = cp.Sum(nbreaks, cp.IntExpr(cp.Eq(playHome[i][j - 1], playHome[i][j]))); } cp.Add(cp.Eq(teamBreaks[i], nbreaks)); } IIntVar breaks = cp.IntVar(n - 2, n * (nbWeeks / 2)); cp.Add(cp.Eq(breaks, cp.Sum(teamBreaks))); cp.Add(cp.Minimize(breaks)); // // Catalyzing constraints // // Each team plays home the same number of times as away for (int i = 0; i < n; i++) { cp.Add(cp.Eq(cp.Sum(playHome[i]), nbWeeks / 2)); } // Breaks must be even for each team for (int i = 0; i < n; i++) { cp.Add(cp.Eq(cp.Modulo(teamBreaks[i], 2), 0)); } // // Symmetry breaking constraints // // Teams are interchangeable. Fix first week. // Also breaks reflection symmetry of the whole schedule. for (int i = 0; i < nbGamesPerWeek; i++) { cp.Add(cp.Eq(home[0][i], i * 2)); cp.Add(cp.Eq(away[0][i], i * 2 + 1)); } // Order of games in each week is arbitrary. // Break symmetry by forcing an order. for (int i = 0; i < nbWeeks; i++) { for (int j = 1; j < nbGamesPerWeek; j++) { cp.Add(cp.Gt(games[i][j], games[i][j - 1])); } } cp.SetParameter(CP.DoubleParam.TimeLimit, 20); cp.SetParameter(CP.IntParam.LogPeriod, 10000); IVarSelector varSel = cp.SelectSmallest(cp.VarIndex(allGames));; IValueSelector valSel = cp.SelectRandomValue(); ISearchPhase phase = cp.SearchPhase(allGames, cp.IntVarChooser(varSel), cp.IntValueChooser(valSel)); cp.SetSearchPhases(phase); cp.StartNewSearch(); while (cp.Next()) { Console.WriteLine("Solution at {0}", cp.GetValue(breaks)); } cp.EndSearch(); } catch (ILOG.Concert.Exception e) { Console.WriteLine("Error {0}", e); } }
public static void Main(String[] args) { CP cp = new CP(); dist[0]=new int[] { 16,1,1,0,0,0,0,0,1,1,1,1,1,2,2,1,1,0,0,0,2,2,1,1,1 }; dist[1]=new int[] { 1,16,2,0,0,0,0,0,2,2,1,1,1,2,2,1,1,0,0,0,0,0,0,0,0 }; dist[2]=new int[] { 1,2,16,0,0,0,0,0,2,2,1,1,1,2,2,1,1,0,0,0,0,0,0,0,0 }; dist[3]=new int[] { 0,0,0,16,2,2,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1 }; dist[4]=new int[] { 0,0,0,2,16,2,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1 }; dist[5]=new int[] { 0,0,0,2,2,16,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1 }; dist[6]=new int[] { 0,0,0,0,0,0,16,2,0,0,1,1,1,0,0,1,1,1,1,2,0,0,0,1,1 }; dist[7]=new int[] { 0,0,0,0,0,0,2,16,0,0,1,1,1,0,0,1,1,1,1,2,0,0,0,1,1 }; dist[8]=new int[] { 1,2,2,0,0,0,0,0,16,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1 }; dist[9]=new int[] { 1,2,2,0,0,0,0,0,2,16,2,2,2,2,2,1,1,1,1,1,1,1,0,1,1 }; dist[10]=new int[]{ 1,1,1,0,0,0,1,1,2,2,16,2,2,2,2,2,2,1,1,2,1,1,0,1,1 }; dist[11]=new int[]{ 1,1,1,0,0,0,1,1,2,2,2,16,2,2,2,2,2,1,1,2,1,1,0,1,1 }; dist[12]=new int[]{ 1,1,1,0,0,0,1,1,2,2,2,2,16,2,2,2,2,1,1,2,1,1,0,1,1 }; dist[13]=new int[]{ 2,2,2,0,0,0,0,0,2,2,2,2,2,16,2,1,1,1,1,1,1,1,1,1,1 }; dist[14]=new int[]{ 2,2,2,0,0,0,0,0,2,2,2,2,2,2,16,1,1,1,1,1,1,1,1,1,1 }; dist[15]=new int[]{ 1,1,1,0,0,0,1,1,1,1,2,2,2,1,1,16,2,2,2,1,2,2,1,2,2 }; dist[16]=new int[]{ 1,1,1,0,0,0,1,1,1,1,2,2,2,1,1,2,16,2,2,1,2,2,1,2,2 }; dist[17]=new int[]{ 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,16,2,2,1,1,0,2,2 }; dist[18]=new int[]{ 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,16,2,1,1,0,2,2 }; dist[19]=new int[]{ 0,0,0,1,1,1,2,2,1,1,2,2,2,1,1,1,1,2,2,16,1,1,0,1,1 }; dist[20]=new int[]{ 2,0,0,0,0,0,0,0,1,1,1,1,1,1,1,2,2,1,1,1,16,2,1,2,2 }; dist[21]=new int[]{ 2,0,0,0,0,0,0,0,1,1,1,1,1,1,1,2,2,1,1,1,2,16,1,2,2 }; dist[22]=new int[]{ 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,16,1,1 }; dist[23]=new int[]{ 1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,1,2,2,1,16,2 }; dist[24]=new int[]{ 1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,1,2,2,1,2,16 }; int nbTransmitters = getTransmitterIndex(nbCell, 0); IIntVar[] freq = cp.IntVarArray(nbTransmitters, 0, nbAvailFreq-1, "freq"); for (int cell = 0; cell < nbCell; cell++) for (int channel1 = 0; channel1 < nbChannel[cell]; channel1++) for (int channel2= channel1+1; channel2 < nbChannel[cell]; channel2++) cp.Add(cp.Ge(cp.Abs(cp.Diff(freq[getTransmitterIndex(cell, channel1)], freq[getTransmitterIndex(cell, channel2)])), 16)); for (int cell1 = 0; cell1 < nbCell; cell1++) for (int cell2 = cell1+1; cell2 < nbCell; cell2++) if (dist[cell1][cell2] > 0) for (int channel1 = 0; channel1 < nbChannel[cell1]; channel1++) for (int channel2 = 0; channel2 < nbChannel[cell2]; channel2++) cp.Add(cp.Ge(cp.Abs(cp.Diff(freq[getTransmitterIndex(cell1, channel1)], freq[getTransmitterIndex(cell2, channel2)])), dist[cell1][cell2])); // Minimizing the total number of frequencies IIntExpr nbFreq = cp.CountDifferent(freq); cp.Add(cp.Minimize(nbFreq)); cp.SetParameter(CP.IntParam.CountDifferentInferenceLevel, CP.ParameterValues.Extended); cp.SetParameter(CP.IntParam.FailLimit, 40000); cp.SetParameter(CP.IntParam.LogPeriod, 100000); if (cp.Solve()) { for (int cell = 0; cell < nbCell; cell++) { for (int channel = 0; channel < nbChannel[cell]; channel++) Console.Write(cp.GetIntValue(freq[getTransmitterIndex(cell, channel)]) + " " ); Console.WriteLine(); } Console.WriteLine("Total # of sites " + nbTransmitters); Console.WriteLine("Total # of frequencies " + cp.GetValue(nbFreq)); } else Console.WriteLine("No solution"); cp.End(); }
static void Main(string[] args) { try { int n = 10; if (args.Length > 0) n = Int32.Parse(args[0]); if ((n % 2) == 1) n++; Console.WriteLine("Finding schedule for {0} teams", n); int nbWeeks = 2 * (n - 1); int nbGamesPerWeek = n / 2; int nbGames = n * (n - 1); CP cp = new CP(); IIntVar[][] games = new IIntVar[nbWeeks][]; IIntVar[][] home = new IIntVar[nbWeeks][]; IIntVar[][] away = new IIntVar[nbWeeks][]; for (int i = 0; i < nbWeeks; i++) { home[i] = cp.IntVarArray(nbGamesPerWeek, 0, n - 1); away[i] = cp.IntVarArray(nbGamesPerWeek, 0, n - 1); games[i] = cp.IntVarArray(nbGamesPerWeek, 0, nbGames - 1); } // // For each play slot, set up correspondance between game id, // home team, and away team // IIntTupleSet gha = cp.IntTable(3); int[] tuple = new int[3]; for (int i = 0; i < n; i++) { tuple[0] = i; for (int j = 0; j < n; j++) { if (i != j) { tuple[1] = j; tuple[2] = Game(i, j, n); cp.AddTuple(gha, tuple); } } } for (int i = 0; i < nbWeeks; i++) { for (int j = 0; j < nbGamesPerWeek; j++) { IIntVar[] vars = cp.IntVarArray(3); vars[0] = home[i][j]; vars[1] = away[i][j]; vars[2] = games[i][j]; cp.Add(cp.AllowedAssignments(vars, gha)); } } // // All teams play each week // for (int i = 0; i < nbWeeks; i++) { IIntVar[] teamsThisWeek = cp.IntVarArray(n); for (int j = 0; j < nbGamesPerWeek; j++) { teamsThisWeek[j] = home[i][j]; teamsThisWeek[nbGamesPerWeek + j] = away[i][j]; } cp.Add(cp.AllDiff(teamsThisWeek)); } // // Dual representation: for each game id, the play slot is maintained // IIntVar[] weekOfGame = cp.IntVarArray(nbGames, 0, nbWeeks - 1); IIntVar[] allGames = cp.IntVarArray(nbGames); IIntVar[] allSlots = cp.IntVarArray(nbGames, 0, nbGames - 1); for (int i = 0; i < nbWeeks; i++) for (int j = 0; j < nbGamesPerWeek; j++) allGames[i * nbGamesPerWeek + j] = games[i][j]; cp.Add(cp.Inverse(allGames, allSlots)); for (int i = 0; i < nbGames; i++) cp.Add(cp.Eq(weekOfGame[i], cp.Div(allSlots[i], nbGamesPerWeek))); // // Two half schedules. Cannot play the same pair twice in the same half. // Plus, impose a minimum number of weeks between two games involving // the same teams (up to six weeks) // int mid = nbWeeks / 2; int overlap = 0; if (n >= 6) overlap = min(n / 2, 6); for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { int g1 = Game(i, j, n); int g2 = Game(j, i, n); cp.Add(cp.Equiv(cp.Ge(weekOfGame[g1], mid), cp.Lt(weekOfGame[g2], mid))); // Six week difference... if (overlap != 0) cp.Add(cp.Ge(cp.Abs(cp.Diff(weekOfGame[g1], weekOfGame[g2])), overlap)); } } // // Can't have three homes or three aways in a row. // IIntVar[][] playHome = new IIntVar[n][]; for (int i = 0; i < n; i++) { playHome[i] = cp.IntVarArray(nbWeeks, 0, 1); for (int j = 0; j < nbWeeks; j++) cp.Add(cp.Eq(playHome[i][j], cp.Count(home[j], i))); for (int j = 0; j < nbWeeks - 3; j++) { IIntVar[] window = cp.IntVarArray(3); for (int k = j; k < j + 3; k++) window[k - j] = playHome[i][k]; IIntExpr windowSum = cp.Sum(window); cp.Add(cp.Le(1, windowSum)); cp.Add(cp.Le(windowSum, 2)); } } // // If we start the season home, we finish away and vice versa. // for (int i = 0; i < n; i++) cp.Add(cp.Neq(playHome[i][0], playHome[i][nbWeeks - 1])); // // Objective: minimize the number of `breaks'. A break is // two consecutive home or away matches for a // particular team IIntVar[] teamBreaks = cp.IntVarArray(n, 0, nbWeeks / 2); for (int i = 0; i < n; i++) { IIntExpr nbreaks = cp.Constant(0); for (int j = 1; j < nbWeeks; j++) nbreaks = cp.Sum(nbreaks, cp.IntExpr(cp.Eq(playHome[i][j - 1], playHome[i][j]))); cp.Add(cp.Eq(teamBreaks[i], nbreaks)); } IIntVar breaks = cp.IntVar(n - 2, n * (nbWeeks / 2)); cp.Add(cp.Eq(breaks, cp.Sum(teamBreaks))); cp.Add(cp.Minimize(breaks)); // // Catalyzing constraints // // Each team plays home the same number of times as away for (int i = 0; i < n; i++) cp.Add(cp.Eq(cp.Sum(playHome[i]), nbWeeks / 2)); // Breaks must be even for each team for (int i = 0; i < n; i++) cp.Add(cp.Eq(cp.Modulo(teamBreaks[i], 2), 0)); // // Symmetry breaking constraints // // Teams are interchangeable. Fix first week. // Also breaks reflection symmetry of the whole schedule. for (int i = 0; i < nbGamesPerWeek; i++) { cp.Add(cp.Eq(home[0][i], i * 2)); cp.Add(cp.Eq(away[0][i], i * 2 + 1)); } // Order of games in each week is arbitrary. // Break symmetry by forcing an order. for (int i = 0; i < nbWeeks; i++) for (int j = 1; j < nbGamesPerWeek; j++) cp.Add(cp.Gt(games[i][j], games[i][j - 1])); cp.SetParameter(CP.DoubleParam.TimeLimit, 20); cp.SetParameter(CP.IntParam.LogPeriod, 10000); IVarSelector varSel = cp.SelectSmallest(cp.VarIndex(allGames)); ; IValueSelector valSel = cp.SelectRandomValue(); ISearchPhase phase = cp.SearchPhase(allGames, cp.IntVarChooser(varSel), cp.IntValueChooser(valSel)); cp.StartNewSearch(phase); while (cp.Next()) { Console.WriteLine("Solution at {0}", cp.GetValue(breaks)); } cp.EndSearch(); } catch (ILOG.Concert.Exception e) { Console.WriteLine("Error {0}", e); } }
public static void Main(String[] args) { CP cp = new CP(); dist[0] = new int[] { 16, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 1, 1, 0, 0, 0, 2, 2, 1, 1, 1 }; dist[1] = new int[] { 1, 16, 2, 0, 0, 0, 0, 0, 2, 2, 1, 1, 1, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; dist[2] = new int[] { 1, 2, 16, 0, 0, 0, 0, 0, 2, 2, 1, 1, 1, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; dist[3] = new int[] { 0, 0, 0, 16, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1 }; dist[4] = new int[] { 0, 0, 0, 2, 16, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1 }; dist[5] = new int[] { 0, 0, 0, 2, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1 }; dist[6] = new int[] { 0, 0, 0, 0, 0, 0, 16, 2, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 2, 0, 0, 0, 1, 1 }; dist[7] = new int[] { 0, 0, 0, 0, 0, 0, 2, 16, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 2, 0, 0, 0, 1, 1 }; dist[8] = new int[] { 1, 2, 2, 0, 0, 0, 0, 0, 16, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1 }; dist[9] = new int[] { 1, 2, 2, 0, 0, 0, 0, 0, 2, 16, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1 }; dist[10] = new int[] { 1, 1, 1, 0, 0, 0, 1, 1, 2, 2, 16, 2, 2, 2, 2, 2, 2, 1, 1, 2, 1, 1, 0, 1, 1 }; dist[11] = new int[] { 1, 1, 1, 0, 0, 0, 1, 1, 2, 2, 2, 16, 2, 2, 2, 2, 2, 1, 1, 2, 1, 1, 0, 1, 1 }; dist[12] = new int[] { 1, 1, 1, 0, 0, 0, 1, 1, 2, 2, 2, 2, 16, 2, 2, 2, 2, 1, 1, 2, 1, 1, 0, 1, 1 }; dist[13] = new int[] { 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 16, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; dist[14] = new int[] { 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; dist[15] = new int[] { 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 1, 16, 2, 2, 2, 1, 2, 2, 1, 2, 2 }; dist[16] = new int[] { 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 1, 2, 16, 2, 2, 1, 2, 2, 1, 2, 2 }; dist[17] = new int[] { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 16, 2, 2, 1, 1, 0, 2, 2 }; dist[18] = new int[] { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 16, 2, 1, 1, 0, 2, 2 }; dist[19] = new int[] { 0, 0, 0, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 16, 1, 1, 0, 1, 1 }; dist[20] = new int[] { 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 16, 2, 1, 2, 2 }; dist[21] = new int[] { 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 16, 1, 2, 2 }; dist[22] = new int[] { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 16, 1, 1 }; dist[23] = new int[] { 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 1, 16, 2 }; dist[24] = new int[] { 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 16 }; int nbTransmitters = getTransmitterIndex(nbCell, 0); IIntVar[] freq = cp.IntVarArray(nbTransmitters, 0, nbAvailFreq - 1, "freq"); for (int cell = 0; cell < nbCell; cell++) { for (int channel1 = 0; channel1 < nbChannel[cell]; channel1++) { for (int channel2 = channel1 + 1; channel2 < nbChannel[cell]; channel2++) { cp.Add(cp.Ge(cp.Abs(cp.Diff(freq[getTransmitterIndex(cell, channel1)], freq[getTransmitterIndex(cell, channel2)])), 16)); } } } for (int cell1 = 0; cell1 < nbCell; cell1++) { for (int cell2 = cell1 + 1; cell2 < nbCell; cell2++) { if (dist[cell1][cell2] > 0) { for (int channel1 = 0; channel1 < nbChannel[cell1]; channel1++) { for (int channel2 = 0; channel2 < nbChannel[cell2]; channel2++) { cp.Add(cp.Ge(cp.Abs(cp.Diff(freq[getTransmitterIndex(cell1, channel1)], freq[getTransmitterIndex(cell2, channel2)])), dist[cell1][cell2])); } } } } } // Minimizing the total number of frequencies IIntExpr nbFreq = cp.CountDifferent(freq); cp.Add(cp.Minimize(nbFreq)); cp.SetParameter(CP.IntParam.CountDifferentInferenceLevel, CP.ParameterValues.Extended); cp.SetParameter(CP.IntParam.FailLimit, 40000); cp.SetParameter(CP.IntParam.LogPeriod, 100000); if (cp.Solve()) { for (int cell = 0; cell < nbCell; cell++) { for (int channel = 0; channel < nbChannel[cell]; channel++) { Console.Write(cp.GetIntValue(freq[getTransmitterIndex(cell, channel)]) + " "); } Console.WriteLine(); } Console.WriteLine("Total # of sites " + nbTransmitters); Console.WriteLine("Total # of frequencies " + cp.GetValue(nbFreq)); } else { Console.WriteLine("No solution"); } cp.End(); }
public static void Main(String[] args) { String filename = "../../../../examples/data/learningeffect_default.data"; int nbJobs, nbMachines; if (args.Length > 0) { filename = args[0]; } CP cp = new CP(); DataReader data = new DataReader(filename); nbJobs = data.Next(); nbMachines = data.Next(); IIntExpr[] ends = new IIntExpr[nbJobs]; IIntervalVar[][] machines = new IIntervalVar[nbMachines][]; int[][] sizes = new int[nbMachines][]; for (int j = 0; j < nbMachines; j++) { machines[j] = new IIntervalVar[nbJobs]; sizes[j] = new int[nbJobs]; } for (int i = 0; i < nbJobs; i++) { IIntervalVar prec = cp.IntervalVar(); for (int j = 0; j < nbMachines; j++) { int m, d; m = data.Next(); d = data.Next(); IIntervalVar ti = cp.IntervalVar(0, d); machines[m][i] = ti; sizes[m][i] = d; if (j > 0) { cp.Add(cp.EndBeforeStart(prec, ti)); } prec = ti; } ends[i] = cp.EndOf(prec); } for (int j = 0; j < nbMachines; j++) { double alpha = data.Next() / ((double)100); IIntervalVar[] chain = new IIntervalVar[nbJobs]; IIntervalVar prec = cp.IntervalVar(); IIntExpr[] indices = new IIntExpr[nbJobs]; for (int i = 0; i < nbJobs; i++) { IIntervalVar syncti = cp.IntervalVar(); if (i > 0) { cp.Add(cp.EndBeforeStart(prec, syncti)); } prec = syncti; chain[i] = syncti; IIntExpr index = cp.IntVar(0, nbJobs - 1); indices[i] = index; // Learning effect captured by the decreasing function // of the position (0 <= alpha <= 1). // At first position, in the sequence index = 0; there is no // learning effect and duration of the task is its nominal duration INumExpr floatDur = cp.Prod(sizes[j][i], cp.Power(alpha, index)); cp.Add(cp.Le( cp.Abs(cp.Diff(floatDur, cp.SizeOf(machines[j][i]))), 0.5) ); } cp.Add(cp.Isomorphism(chain, machines[j], indices, nbJobs)); // The no-overlap is a redundant constraint in this quite // simple model - it is used only to provide stronger inference. cp.Add(cp.NoOverlap(machines[j])); } IObjective objective = cp.Minimize(cp.Max(ends)); cp.Add(objective); cp.SetParameter(CP.IntParam.LogPeriod, 10000); Console.WriteLine("Instance \t: " + filename); if (cp.Solve()) { Console.WriteLine("Makespan \t: " + cp.ObjValue); } else { Console.WriteLine("No solution found."); } }