我有15个人在阵列
names = ["A", "B", "C", ...];
以及一个月中的日期,代表星期一,星期二,星期三,星期四和星期日
days = [1, 2, 3, 4, 7, 8 ..., 31];
我必须在一个月内随机分发这些人至少2次,但有一些条件。
有些人有偏好,说他们喜欢哪个工作日。
我如何存储他们的偏好以及如何在所有日子分发这些人,所以每天都有人?
我想我必须经历这些日子并随机选择其中一个人,在选择这个人之前,我必须检查他/她的偏好是否正常。如果该人已被使用过两次,他/她应该从阵列中删除,因此他/她不能再次使用。
这是解决问题的正确方法吗?
到目前为止我的代码
function getDaysArray(year, month) {
var personNames = ["A", "B", "C"];
var numDaysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var daysInWeek = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
var daysIndex = { 'Mon': 0, 'Tue': 1, 'Wed': 2, 'Thu': 3, 'Fri': 4, 'Sat': 5, 'Sun': 6 };
var index = daysIndex[(new Date(year, month - 1, 1)).toString().split(' ')[0]];
var indexExceptions = [100];
var daysArray = [];
var personName, date, weekdayName;
// loop through all days in month
for (i = 0, length = numDaysInMonth[month - 1]; i < length; i++) {
personName = personNames[Math.floor( Math.random() * personNames.length )];
date = i + 1;
weekdayName = daysInWeek[index++]
daysArray.push(date + '. ' + weekdayName + ': ' + personName);
// reset to new week
if (index == 7) index = 0;
}
return daysArray;
}
console.log(getDaysArray(2015, 10));
答案 0 :(得分:1)
在2之后删除它们,那么你的功能将在15个月的第31个月失败。我会用你的方法再加几点。
var failCount=0;
var maxFail=15;
function randomPerson(personsArray){
return(Math.floor(Math.random() * personsArray.length));
}
function makeSchedule(personsArray, calendarArray){
var shiftsPerPerson=Math.floor(calendarArray.length/personsArray.length);
var extraShifts=calendarArray.length-(shiftsPerPerson*personsArray.length);
for(i=0; i<calendarArray.length-extraShifts; i++){
var calendarDay=calendarArray[i];
var selectedPerson=personsArray[randomPerson(personsArray)];
loopBreak==false;
while(selectedPerson.availability[calendarDay.dayOfWeek]==false || selectedPerson.shifts > shiftsPerPerson-1 && loopBreak==false){
selectedPerson=randomPerson(personsArray);
if(failCount>maxFail){
selectedPerson=failSafe(calendarDay)
if(selectedPerson==false){
return false;
}else{
loopBreak=true;
}
}
failCount++;
}
loopBreak=false;
failCount=0;
calendarDay.selectedPerson=selectedPerson;
selectedPerson.shifts++;
}
for(i=0; i<extraShifts; i++){
var calendarDay=calendarArray[i+calendarArray.length-extraShifts];
var selectedPerson=personsArray[randomPerson(personsArray)];
while(selectedPerson.availability[calendarDay.dayOfWeek]==false || selectedPerson.shifts > shiftsPerPerson){
selectedPerson=randomPerson(personsArray);
}
calendarDay.selectedPerson=selectedPerson;
selectedPerson.shifts++;
}
}
function failSafe(calendarDay){
var canWork=[];
var isPossible=false;
for(j=0; j<personsArray.length; j++){
person=personsArray[j];
if(person.shifts<shiftsPerPerson && person.availability[calendarDay.dayOfWeek]==true){
canWork.push[j];
isPossible=true;
}
}
if(isPossible){
if(canWork.length>1){
var selectedPerson=canWork[randomPerson(canWork)];
return selectedPerson
}else{
selectedPerson=canWork[0];
}
}else{
for(j=0; j<personsArray.length; j++){
person=personsArray[j];
if(person.shifts<shiftsPerPerson+1 && person.availability[calendarDay.dayOfWeek]==true){
canWork.push[j];
isPossible=true;
}
}
if(isPossible){
if(canWork.length>1){
var selectedPerson=canWork[randomPerson(canWork)];
return selectedPerson
}else{
selectedPerson=canWork[0];
}
}
}
return false;
基本上没有一个名字数组,我有一组人物对象和天对象数组。
我们有多少人和人。姓名=人名 person.Availability是一周中的几天,如果它们能够或不能工作,则为真或假。 person.shifts在开始时当然是0,并且随着给定的每个班次递增。第一个循环经历了可以在您的员工中均匀分配的天数,然后第二个循环为少数人提供1个额外的班次以填充所需的任何额外空间。然后将选中的每个人作为calendarDay.selectedPerson
放入日期对象中虽然您的方法是一个良好的开端,但这样可以灵活地添加和删除阵列中的人员并在一个月内的任意天数工作而无需重新编码。希望它工作,没有测试下面的代码,所以可能有语法错误,但概念应该工作!
我添加了failSafe功能,基本上如果该功能未能找到可用员工预定次数,它将搜索所有可用员工,然后随机分配其中一个。如果未找到,则将从make schedule函数返回false。
var person = {
Name:"Persons Name",
shifts:0,
availability :[{
Monday: true,
Tuesday:true,
Wednesday:true,
Thursday:true,
Friday:true,
Saturday:true,
Sunday:true
}]};
personsArray.push(person);
//DO THIS FOR EACH PERSON
var calendarDay= {
Day:1,
dayOfWeek:Monday,
SelectedPerson=null
};
calendarArray.push(calendarDay);
//DO THIS FOR EACH DAY OR BUILD LOOP TO DO THIS FOR YOU