## 3 CPLEX CP Solver Solution
### MILP Model
#### 3.2.2 Using CP Solver  
In the CPLEX constraint programming solver, for time window constraints, \"interval\" and \"sequence\" data types can be used to describe time windows and sequences of time windows. The \"noOverlap\" function can be employed to ensure that the execution times of tasks on the same satellite do not overlap, as well as to impose constraints on attitude transition times.  
dvar boolean x[i in tasks][k in satellites][m in orbits]; dvar boolean y[i in tasks][j in stations][k in satellites][n in orbits]; dvar interval x_val[j in tasks][k in satellites]optional size duration[j]; dvar interval g_val[i in stations][k in satellites][m in orbits] optional in wsg[i][k][m]..weg[i][k][m]; dvar interval y_val[i in tasks][j in stations][k in satellites][m in orbits] optional size uterine[i]; dvar sequence x_seq[k in satellites] in all (j in tasks) x_val[j][k]; dvar sequence y_seq[k in satellites] in all (i in tasks, j in stations, m in orbits) y_val[i][j][k][m]; dvar sequence g_seq[j in stations] in all (i in tasks, m in orbits, k in satellites) y_val[i][j][k][m]; dvar sequence q_seq[j in stations] in all (m in orbits, k in satellites) g_val[j][k][m]; cumulFunction storageUsage[k in satellites] = sum(i in tasks) stepAtStart(x_val[i][k], umemory[k][1] * duration[i]) - sum(j in stations, i in tasks, m in orbits) stepAtStart(y_val[i][j][k][m], umemory[k][2] * utime[i]); cumulFunction energyUsage[k in satellites] = sum(i in tasks) stepAtStart(x_val[i][k], uenergy[k][1] * duration[i]) + sum(j in stations, i in tasks, m in orbits) stepAtStart(y_val[i][j][k][m], uenergy[k][2] * utime[i]); maximize sum(j in tasks, m in orbits,k in satellites) (profit[j] *x[j][k][m]); subject to { forall(i in tasks){ sum(m in orbits,k in satellites) x[i][k][m] <= 1;} forall(i in tasks){ sum(n in orbits, j in stations, k  
forall(i in tasks, k in satellites){ sum(n in orbits, j in stations) y[i][j][k][m] >= sum(m in orbits) x[i][k][m];} forall(i in tasks, j in stations, m in orbits, k in satellites){ y[i][j][k][m] == presenceOf(y_val[i][j][k][m]);} forall(i in tasks,k in satellites){ sum(m in orbits)x[i][k][m] == presenceOf(x_val[i][k]);} forall(i in tasks, k in satellites){ startOf(x_val[i][k])>=sum(m in orbits)x[i][k][m]*wst[i][k][m]; endOf(x_val[i][k])<=sum(m in orbits)x[i][k][m]*wst[i][k][m];} forall(i in tasks, j in stations, m in orbits, k in satellites){ endBeforeStart(x_val[i][k], y_val[i][j][k][m]); (y[i][j][k][m] == 1) => ( endOf(x_val[i][k]) <= startOf(g_val[j][k][m]) );} forall(j in stations, m in orbits, k in satellites) span(g_val[j][k][m], all(i in tasks) y_val[i][j][k][m]); forall(k in satellites) storageUsage[k] <= memory[k]; forall(k in satellites) energyUsage[k] <= energy[k]; forall(k in satellites) noOverlap(y_seq[k]); forall(j in stations) noOverlap(g_seq[j]); forall(j in stations) noOverlap(d_seq[j]); forall(k in satellites) noOverlap(x_seq[k], Setup[k]); forall(k in satellites){ forall(j in stations, m1 in orbits, j2 in stations, m2 in orbits : j1!= j2){ (presenceOf(g_val[j][k][m1]) && presenceOf(g_val[j][2][k][m2])) -> abs(endOf(g_val[j][k][m1])-startOf(g_val[j][2][k][m2])) >= sketime[k]; (presenceOf(g_val[j][k][m1]) && presenceOf(g_val[j][2][k][m2])) -> abs(endOf(g_val[j][2][k][m2])-startOf(g_val[j][k][m1])) >= sketime[k];} forall(j in stations){ forall(k1 in satellites, m1 in orbits, k2 in satellites, m2 in orbits : k1!= k2){ (presenceOf(g_val[j][k1][m1]) && presenceOf(g_val[j][k2][m2])) -> abs(endOf(g_val[j][k1][m1])-startOf(g_val[j][k2][m2])) >= sketime[j]; (presenceOf(g_val[j][k1][m1]) && presenceOf(g_val[j][k2][m2])) -> abs(endOf(g_val[j][k2][m2])-startOf(g_val[j][k1][m1])) >= sketime[j];} } By utilizing the special variable types and built-in constraint functions of the CP solver, it is possible to model the original mixed-integer linear programming problem conveniently and solve it conveniently using the solver.