在某些情况下,Microsoft求解器基金会无法求解我的模型

本文关键字:基金会 我的 模型 情况下 Microsoft | 更新日期: 2023-09-27 18:32:50

我正在从事一个生产计划项目,所以我想在某些机器(A,B(中找到订单生产开始时间。

为了简化起见,我想我有 2 台机器(机器 A 和机器 B(我有以下限制:

  • 每台机器只能在一天中的某些时间工作(A_TimeLimitationB_TimeLimitation(为了简化起见,我认为

    • 机器 A 可以在以下范围内工作:

      (2014/12/4

    • 00:00:00 - 2014/12/4 02:00:00( 或 (2014/12/4 04:00:00 - 2014/12/4 06:00:00(
    • 机器B可以在以下范围内工作:

      (2014/12/4 02:00:00 - 2014/12/4 04:00:00( 或 (2014/12/4 05:00:00

      - 2014/12/4 07:00:00(

  • 每个产品必须经过机器 A,然后经过机器 B。

  • 每种产品在每台机器中都需要一些时间(在我的样品中为 60 分钟(。
  • 机器 B 应该在机器 A 完成它的工作后启动。
  • B 最多可以在 A 完成工作后 10 分钟开始工作。[更新]
  • 目标是最大限度地减少订单生产时间。

我使用以下代码将DateTime转换为分钟:

var minutes = new TimeSpan(dateTime.Ticks).TotalMinutes;

因此,使用上面的代码,我的DateTime范围转换为Double范围。

我正在使用Microsoft求解基础来解决问题,所以我使用了以下代码:

var context = SolverContext.GetContext();
var model   = context.CreateModel();
var a_OperationTime = 60;
var b_OperationTime = 60;
var tolerance = 10;
//Decision
Decision A_StartTime = new Decision(Domain.IntegerNonnegative, "A_StartTime");
model.AddDecision(A_StartTime);
Decision B_StartTime = new Decision(Domain.IntegerNonnegative, "B_StartTime");
model.AddDecision(B_StartTime);
 //Constraints
model.AddConstraint("A_TimeLimitations" ,
                 (1059220800 <= A_StartTime <= 1059220860) | 
                 (1059221160 <= A_StartTime <= 1059221220));
model.AddConstraint("B_TimeLimitations" , 
                 (1059220920 <= B_StartTime <= 1059220980) | 
                 (1059221100 <= B_StartTime <= 1059221160));
model.AddConstraint("B_ContiguousLimitations" , 
                 B_StartTime - (A_StartTime + 60) <= tolerence);
//Goal
var A_StartTime = model.Decisions.First(x => x.Name == "A_StartTime");
var B_StartTime = model.Decisions.First(x => x.Name == "B_StartTime");
model.AddGoals("OrderDuration", GoalKind.Minimize, B_StartTime - A_StartTime);
//Solve
var directive = new ConstraintProgrammingDirective();
//directive.TimeLimit = 10000;
var solution = context.Solve(directive);

但是当我运行代码时,它似乎进入了一个无限循环,当我为我的directive指定TimeLimit时,在 10000 毫秒后,solution.Quality Unknown这意味着MSF找不到任何解决方案,如果我删除机器中的第二个DateTime范围A代码可以找到解决方案。

有谁知道问题出在哪里?

在某些情况下,Microsoft求解器基金会无法求解我的模型

我发现了问题

  1. 我应该在我的模型中定义更多约束
  2. 我的时间限制非常大,我在汉坎克指导下将DateTime更改为double转换方法

所以最终的解决方案在这里:

//extention method for converting DateTime to normalized double
public static double ToMinutes(this DateTime value)
{
   return (value-new DateTime(2014, 12, 3)).TotalMinutes;
}
var a1_start = new DateTime(2014, 12, 4).ToMinutes();
var a1_finish = new DateTime(2014, 12, 4, 2, 0, 0).ToMinutes();
var a2_start = new DateTime(2014, 12, 4, 4, 0, 0).ToMinutes();
var a2_finish = new DateTime(2014, 12, 4, 6, 0, 0).ToMinutes();
var b1_start = new DateTime(2014, 12, 4,1,0,0).ToMinutes();
var b1_finish = new DateTime(2014, 12, 4, 1, 55, 0).ToMinutes();
var B2_start = new DateTime(2014, 12, 4, 5, 0, 0).ToMinutes();
var B2_finish = new DateTime(2014, 12, 4, 6, 0, 0).ToMinutes();
var context = SolverContext.GetContext();
var model = context.CreateModel();
var a_OperationTime = 60;
var b_OperationTime = 60;
var tolerance = 10;
//Decision
Decision A_StartTime = new Decision(Domain.IntegerNonnegative,"A_StartTime");
model.AddDecision(A_StartTime);
Decision B_StartTime = new Decision(Domain.IntegerNonnegative,"B_StartTime");
model.AddDecision(B_StartTime);
//Constraints
model.AddConstraint("A_TimeLimitations",
                        ((a1_start <= A_StartTime <= a1_finish) & 
                         (a1_start + 60 <= A_StartTime + 60 <= a1_finish)) |
                        ((a2_start <= A_StartTime <= a2_finish) & 
                         (a2_start + 60 <= A_StartTime + 60 <= a2_finish)));
model.AddConstraint("B_TimeLimitations",
                       ((b1_start <= B_StartTime <= b1_finish) & 
                        ((b1_start + 60 <= B_StartTime + 60 <= b1_finish))) |
                       ((B2_start <= B_StartTime <= B2_finish) & 
                        (B2_start + 60 <= B_StartTime + 60 <= B2_finish)));
model.AddConstraint("B_ContiguousLimitations",
                          B_StartTime - (A_StartTime + 60) <= tolerance);
model.AddConstraint("B_GreaterThan_A",
                     B_StartTime >= A_StartTime + 60);
//Goal
A_StartTime = model.Decisions.First(x => x.Name == "A_StartTime");
B_StartTime = model.Decisions.First(x => x.Name == "B_StartTime");
model.AddGoals("OrderDuration",GoalKind.Minimize, B_StartTime - A_StartTime);
//Solve
var directive = new ConstraintProgrammingDirective();
var solution = context.Solve(directive);