简体   繁体   中英

Microsoft Solver Foundation Throws ArgumentNullException When Adding a Constraint

I'm trying to create a schedule for a call centre where I am trying to maximize staff on high call periods and minimize on low periods. For simplicity, it would look something like:

简单的呼叫中心时间表

I have the following code:

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;
}

I am getting a ArgumentNullException on the constraint of limiting the employee to 9 hours (eg 4 fifteen minutes section * 9 hours = 36 times).

Here's the stack trace:


at Microsoft.SolverFoundation.Solvers.ConstraintSystem.ValidateInputs(CspTerm[] inputs) at Microsoft.SolverFoundation.Solvers.ConstraintSystem.Equal(Int32 constant, CspTerm[] inputs) at CSPCallCenterDemo.Program.Main(String[] args) in c:\\Users\\wdniels\\Documents\\Visual Studio 2012\\Projects\\CSPCallCenterDemo\\CSPCallCenterDemo\\Program.cs:line 40 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionC ontext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()


Also does anyone know how I can add a constraint that ensures that the employee will work 36 consecutive 15 minute intervals?

You get ArgumentException because of you GetRow code did't completely fill CspTerm. You have to rewrite it like this:

    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;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM