我正在尝试为呼叫中心制定一个时间表,我试图在高呼叫时段最大化员工,并在低时段最小化。为简单起见,它看起来像:
我有以下代码:
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;
}
我在将雇员限制为9小时(例如4个15分钟* 9小时= 36次)的约束下得到ArgumentNullException。
这是堆栈跟踪:
在 Microsoft.SolverFoundation.Solvers.ConstraintSystem.ValidateInputs(CspTerm [] 输入) Microsoft.SolverFoundation.Solvers.ConstraintSystem.Equal(的Int32 CSPCallCenterDemo.Program.Main(String []中的常量,CspTerm []输入) args)在c:\ Users \ wdniels \ Documents \ Visual Studio中 2012 \ Projects \ CSPCallCenterDemo \ CSPCallCenterDemo \ Program.cs:第40行 在System.AppDomain._nExecuteAssembly(RuntimeAssembly程序集, System.AppDomain.ExecuteAssembly上的String [] args)(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,ContextCallback回调,对象状态,布尔值 preserveSyncCtx)at System.Threading.ExecutionContext.Run(执行上下文 executionContext,ContextCallback回调,对象状态,布尔值 preserveSyncCtx)at System.Threading.ExecutionContext.Run(执行上下文 executionContext,ContextCallback回调,对象状态)at System.Threading.ThreadHelper.ThreadStart()
也有人知道如何添加一个约束来确保员工连续工作36 <连续 15分钟?
答案 0 :(得分: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;
}