2015-10-21 50 views
0

我有一個數組分佈在天

names = ["A", "B", "C", ...]; 

15人及日期在一個月內,較週一,週二,週三,週四和週日

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

店裏的人作爲對象,添加名稱和偏好性。但似乎還有一些必要的邏輯(如將月份的日數與週日數相關聯)。你可以在代碼片段或[fiddle](http://jsfiddle.net/)中提供你的當前代碼。這樣,它可以幫助更具體。 – dakab

+0

這也是我在使用人物對象數組和日期對象數組中的建議波紋管 – PC3TJ

回答

1

通過2之後刪除他們,那麼你的功能將無法在本月31日與15人。我會用你的方法和其他幾點。

var failCount=0; 
 
var maxFail=15; 
 

 
     function randomPerson(personsArray){ 
 
\t \t \t 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){ 
 
\t \t \t \t \t \t selectedPerson=failSafe(calendarDay) 
 
\t \t \t \t \t \t if(selectedPerson==false){ 
 
\t \t \t \t \t \t \t return false; 
 
\t \t \t \t \t \t }else{ 
 
\t \t \t \t \t \t \t loopBreak=true; 
 
\t \t \t \t \t \t } 
 
\t \t \t \t \t } 
 
        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){ 
 
\t \t \t 
 
\t \t \t var canWork=[]; 
 
\t \t \t var isPossible=false; 
 
\t \t \t for(j=0; j<personsArray.length; j++){ 
 
\t \t \t \t person=personsArray[j]; 
 
\t \t \t \t if(person.shifts<shiftsPerPerson && person.availability[calendarDay.dayOfWeek]==true){ 
 
\t \t \t \t \t canWork.push[j]; 
 
\t \t \t \t \t isPossible=true; 
 
\t \t \t \t } 
 
\t \t \t } 
 
\t \t \t if(isPossible){ 
 
\t \t \t \t if(canWork.length>1){ 
 
\t \t \t \t \t var selectedPerson=canWork[randomPerson(canWork)]; 
 
\t \t \t \t \t return selectedPerson 
 
\t \t \t \t \t 
 
\t \t \t \t }else{ 
 
\t \t \t \t \t selectedPerson=canWork[0]; 
 
\t \t \t \t } 
 
\t \t \t \t 
 
\t \t \t }else{ 
 
\t \t \t \t \t for(j=0; j<personsArray.length; j++){ 
 
\t \t \t \t person=personsArray[j]; 
 
\t \t \t \t if(person.shifts<shiftsPerPerson+1 && person.availability[calendarDay.dayOfWeek]==true){ 
 
\t \t \t \t \t canWork.push[j]; 
 
\t \t \t \t \t isPossible=true; 
 
\t \t \t \t } 
 
\t \t \t \t 
 
\t \t \t \t 
 
\t \t \t } 
 
\t \t \t 
 
\t \t \t if(isPossible){ 
 
\t \t \t \t if(canWork.length>1){ 
 
\t \t \t \t \t var selectedPerson=canWork[randomPerson(canWork)]; 
 
\t \t \t \t \t return selectedPerson 
 
\t \t \t \t \t 
 
\t \t \t \t }else{ 
 
\t \t \t \t \t selectedPerson=canWork[0]; 
 
\t \t \t \t } 
 
\t \t } 
 
\t } 
 
\t return false; 
 
\t \t \t

基本上而不是有名字的數組我有對象的人,爲天對象數組的數組。

,我們有人員和person.Name =者的數組名 person.Availability是星期幾的數組,是真的還是假的,如果他們能或不能工作。 person.shifts在開始的時候當然是0,並且隨着每個班次的增加而增加。第一個循環經歷了可以在員工中平均分配的天數,然後第二個循環向另外幾個人提供額外的班次,以填補所需的額外空間。然後選擇每個人作爲日曆對象作爲calendarDay.selectedPerson

雖然你的方法是一個好的開始,這將允許靈活地添加和刪除陣列中的人,並在任何月份的任何天數沒有重新編碼工作。希望它的工作原理,沒有測試下面的代碼,所以可能有語法錯誤,但這個概念應該工作!

我添加了failSafe函數,基本上,如果函數找不到可用員工預定次數,它將搜索所有可用員工,然後隨機分配其中一個員工。如果沒有發現任何錯誤將從make schedule函數返回。

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

+0

看起來非常好,但我仍然不確定什麼personsArray和calendarArray應該看起來像。你能舉一個非常基本的例子嗎?當然是 – Jamgreen

+0

。我jsut張貼編輯與2陣列的聲明。它們只是一個簡單的對象數組,使其更易於處理數據。你也可以使用數組或數組並行數組,但在我看來這是最乾淨的方法,以至於所有的東西都有混淆名稱,因爲javascript不允許ASSOC數組 – PC3TJ

+0

如上所述,這些日期和人的建築物對象是個人預設,如果你更熟悉另一種存儲和訪問數據的方式,然後使用任何你喜歡的方法。上面的方法可以用任何形式的數組或類似的方法來實現。 – PC3TJ