Originally posted by: SystemAdmin
[jfk said:]
Hello,
clearly you have a set of people with given features (can drive, engineer, etc) and they have to work (or have a rest) on a given day. You must have a set of jobs to execute and each job has a set of requirement what type of team is necessary to attend to. Then clearly you need a workers variable array, where the domain of each variable for a worker can be the possible job.
so if you have 5 jobs, where a job is described by (engineer needed, driver needed, start, end, location) or something like that (start is the earliest day of the week when the job can be done, end is the latest day of the week when the job has to be done) and you have 10 people with the description (engineer, driver license,working days, location) or something like that (where working days are the days when the worker can work.
then an element of the variable array assignment[i] can take 1..5, that is the ith worker can be assigned to one of the jobs'. Then the constraint like "i, j workers can't stand each other" means that assigned[i] != assigned[j].
If you want to say that "if and engineer has driving license then no need for another driver" then
forall(i in nbJobs, j in nbWorkers: workers[j].license=1&workers[i].engineer=1)
assignment[j] = i => sum(k in nbWorkers: workers[k].engineer=0) (assignment[k]==i) ==0;
the goal function seems some sort of distance which is you want to send the workers to the closest possible location where they are. I suppose the workers after 1 day of work will go back to their "home base" (if not then you have to keep track of each day where the person worked). In the light of your description I can't suppose that all the people could have different location due to the "need driver" sort of things, so they have to come together to a location and that one is called the "home base". Then you can't have 2 workers assigned to the same job coming from different locations:
forall(i,j in nbWorkers: workers[i].location != workers[j].location)
assigned[i] != assigned[j];
the goal function could be complicated if you don't introduce a location selection, that is you have to decide which location you serve the job. so you have a depot array (say with 3 different location) and this variable array has the domain of jobs (so 1..5). Then you have to align this decision with the workers decision, like if the location of the a worker and a depo is different the worker and the depo can't serve the same job.
forall(d in nbDepots, i in nbWorkers: depoLocation[d] != workers[i].location)
depot[d] != assigned[i];
then the goal is easy:
sum(d in nbDepots, k in nbJobs) (jobs[k].location - depoLocation[d])*(depot[d]==k);
in OPL/CPLEX you don't need to define indicator variables (e.g. depot[d]==k is a boolean var with false if the equation is false and true if the equation is satsified) it is taken care of by OPL/CPLEX. In other modeling systems/engines you may have to define separate indicator variables.
I hope it helps
cheers
#DecisionOptimization#MathematicalProgramming-General