2014-10-16 2 views
2

Я пытаюсь создать расписание для центра обработки вызовов, где я пытаюсь максимизировать штат в периоды высоких вызовов и свести к минимуму на низких периодах. Для простоты, это будет выглядеть примерно так:Microsoft Solver Foundation бросает ArgumentNullException при добавлении ограничения

Simple Call Centre Schedule

У меня есть следующий код:

var startTimes = BuildStartTimes(); 
var employees = BuildEmployees(); 
ConstraintSystem solver = ConstraintSystem.CreateSolver(); 
CspDomain wrkTime = solver.CreateIntegerSet(startTimes); 
CspTerm[][] scheduleMatrix = solver.CreateVariableArray(wrkTime, "Schedule", employees.Length, startTimes.Length); 

//iterate through times adding column constraints 
for (int i = 0; i < startTimes.Length -1; i++) 
{ 
    //add constraint for employees numbers 
    for (int emp = 0; emp < employees.Length; emp++) 
    { 
     //for simplistic sake, the Ids i to 9 represent employee Ids 
     scheduleMatrix[emp][i].Model.CreateIntegerSet(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }); 
    } 

    solver.AddConstraints(
      //add constraint that the employee can be added just once 
      solver.GreaterEqual(NumberOfWorkersRequiredForShift(i, employees), GetColumn(scheduleMatrix, i)), 
      //employee can only list once 
      solver.Unequal(GetColumn(scheduleMatrix,i)) 
     ); 
} 

for (int i = 0; i < employees.Length -1; i++) 
{ 
    solver.AddConstraints(
      //employee can only listed nine consecutive 36 times maximum 
      //4 * 15 minutes * 9 hours == 4 * 9 == 36 
      solver.Equal(36,GetRow(scheduleMatrix,i)) 
     ); 
} 

private static CspTerm[] GetColumn(CspTerm[][] matrix, int column) 
{ 

    CspTerm[] slice = new CspTerm[matrix.Length]; 
    for (int row = 0; row < matrix.Length; row++) 
     slice[row] = matrix[row][column]; 

    return slice; 
} 

private static CspTerm[] GetRow(CspTerm[][] matrix, int row) 
{ 
    CspTerm[] slice = new CspTerm[matrix[0].Length]; 
    for (int col = 0; col < matrix.Length; col++) 
     slice[col] = matrix[row][col]; 

    return slice; 
} 

Я получаю ArgumentNullException на ограничение предельного работника до 9 часов (например, 4 пятнадцать минут * 9 часов = 36 раз).

Вот трассировки стека:


на Microsoft.SolverFoundation.Solvers.ConstraintSystem.ValidateInputs (CspTerm [] входы) в Microsoft.SolverFoundation.Solvers.ConstraintSystem.Equal (Int32 константа, CspTerm [] в CSPCallCenterDemo.Program.Main (String [] args) в c: \ Users \ wdniels \ Documents \ Visual Studio 2012 \ Projects \ CSPCallCenterDemo \ CSPCallCenterDemo \ Program.cs: строка 40 в системе .AppD omain._nExecuteAssembly (RuntimeAssembly сборки, String [] арг) в System.AppDomain.ExecuteAssembly (String assemblyFile, Evidence assemblySecurity, String [] арг) при Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() в System.Threading .ThreadHelper.ThreadStart_Context (состояние объекта) при System.Threading.ExecutionContext.RunInternal ( исполнения ExecutionContext ExecutionContext, ContextCallback обратного вызова, состояние объекта, логическое preserveSyncCtx) при System.Threading.ExecutionContext.Run (ExecutionContext ExecutionContext, ContextCallback обратного вызова, объект state, Boolean preserveSyncCtx) в System.Threading.ExecutionContext.Run (ExecutionContext ExecutionContext, ContextCallback обратного вызова, объект состояния) в System.Threading.ThreadHelper.ThreadStart()


Также кто-нибудь знает, как я могу добавить ограничение, которое гарантирует, что работник будет работать 36 подряд 15-минутные интервалы?

+0

Существует очевидная опечатка в GetRow(). Защитите код и используйте slice.Length. Бросание в пару утверждений, которые подтверждают, что массивы с зубчатыми массивами имеют одинаковую длину, а их элементы не являются нулевыми, никогда не повредит. –

ответ

3

Вы получаете исключение ArgumentException из-за того, что код GetRow полностью не заполнил CspTerm. Вы должны переписать так:

private static CspTerm[] GetRow(CspTerm[][] matrix, int row) 
    { 
     CspTerm[] slice = new CspTerm[matrix[0].Length]; 
     for (int col = 0; col < matrix[0].Length; col++) 
      slice[col] = matrix[row][col]; 

     return slice; 
    } 

 Смежные вопросы

  • Нет связанных вопросов^_^