Originally posted by: CharlCillie
Hi Alex
Sorry for taking so long to reply, I had to put my work aside for a while. And yes - the questions I'm asking is regarding research that I'm doing.
Thank you very much for your answers. Im not sure that you understood my first questions correctly, so let me try again by giving some more detail. I have a problem where I need to divide 500 students into groups. An interval for the group sizes must be chosen by the user, which will determine the sizes of the groups. The number of groups that are created, however, should be an output by the program. In other words, the model will decide how many groups should be created. (For example, if the limits for group sizes are specified to be between 4 and 5 students per group, then the model can either choose to create 100 groups of size 5 each, or 125 groups of size 4 each, or a combination of 100 groups of size 4 each and 20 groups of size 5 each, etc.). Also, the amount of groups that are created should be a multiple of the variable P (also defined by the user). This means that if P is defined to be 10, then there must be 90 groups, or 100 groups, or 110 groups, etc that are created by the model. This amount of groups that the model choose to create are then saved as the integer G, which is then used in the model. I am not sure how to implement this, but let me try to explain:
MODEL:
int N = 500; // number of students
int P = 9; // number of groups that a pool should consist of
dvar int G = ...; // number of groups that will be created by the model
float a[students] = ...; // marks of the students that are read in from the Excel sheet
dvar boolean x[students][groups]; // decision variable, equal to 1 if student i is allocated to group j
// lower and upper bounds for the sizes of the groups, that will be defined by the user in an Excel sheet:
int cl = ...;
int cu = ...;
range students = 1..N;
range groups = 1..G;
// variables to be minimized in the objective function:
dvar float vpos[groups][groups];
dvar float vneg[groups][groups];
// Objective function:
minimize sum(j in groups, k in groups)(vpos[j][k] + vneg[j][k]);
subject to{
forall(j in groups, k in groups)
sum(i in students)x[i][j]*a[i] - sum(y in students)x[y][k]*a[y] - vpos[j][k] + vneg[j][k] == 0; // goal programming formulation just allocate values to variables vpos and vneg in order to minimize the difference in marks between groups.
// other general constraints:
forall(i in students)
sum(j in groups) x[i][j] == 1; // ensures that every student is only allocated to one group.
forall(j in groups)
cl <= sum(i in students)x[i][j] <= cu; // group sizes must be larger than the lower bound and smaller than the upper bound for group sizes
forall(j in groups)
(N/cu) <= G <= (N/cl); // ensures that the amount of groups formed will be able to contain all of the students.
// NB - NOW I STILL NEED A CONSTRAINT IN ORDER TO MAKE SURE THAT THE AMOUNT OF GROUPS FORMED ARE A MULTIPLE OF THE VARIABLE P.
}
DATA:
SheetConnection allocations2016("Data");
//The following variables are filled in on the Excel sheet by the user:
P from SheetRead(allocations2016,"'Data'!L4");
cl from SheetRead(allocations2016,"'Data'!I8");
cu from SheetRead(allocations2016,"'Data'!O8");
N from SheetRead(allocations2016,"'Data'!U2");
a from SheetRead(allocations2016,"'Marks'!E2:E502"); // This is read from the excel sheet from a list containing all the marks of all the students.
#DecisionOptimization#OPLusingCPLEXOptimizer