Microsoft Solver Foundation выдает ArgumentNullException при добавлении ограничения

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

Простое расписание Call-центра

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

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) \Users\wdniels\Documents\Visual Studio 2012\Projects\CSPCallCenterDemo\CSPCallCenterDemo\Program.cs: строка 40 в System.AppDomain._nExecuteAssembly(сборка RuntimeAssembly, аргументы String []) в System.AppDomain.ExecuteAssembly(сборка String assemblyFile,, String[] args) в Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() в System.Threading.ThreadHelper.ThreadStart_Context(состояние объекта) в System.Threading.ExecutionContext.RunInternal (вызов ExecutionContext executeContext, StateCallbackCallBackSeclectCallBackbackClextCallBackbackCallBallCallBackbackCallBackbackCallBackbackCallBackbackCallBackbackCallBackbackCallBackbackCallBackbackCallBackbackCallBackbackCallBackbackCallBackbackCallBallCall)) в System.Threading.ExecutionContext.Run(ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта, логический preserveSyncCtx) в System.Threading.ExecutionContext.Run (ExecutionC ontext executeContext, обратный вызов ContextCallback, состояние объекта) в System.Threading.ThreadHelper.ThreadStart()


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

1 ответ

Решение

Вы получаете 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;
    }
Другие вопросы по тегам