2016-10-14 5 views
0

Microsoft Solver Framework으로 작업을 예약하고 싶습니다. 지금은 최소한의 프로젝트 시간을 얻을 수 있도록 대기열에서 작업을 주문하는 간단한 목표를 가지고 있습니다. (나중에 내가 하나 이상의 대기열을 갖고 싶어).MS Solver Framework에서 C# 예약 작업

  • 결정 :
    • projectFinish
    • 시작
    • 마무리
  • 매개 변수 :
      나는 다음과 같은 설정으로이 접근을 시도
    • 기간은
  • 제약 :
    • 시작 + 시간 = 모든 작업이
  • 목표를 완료
  • projectFinish 후 한 번에
  • 에서 하나 이상의 작업을 완료 :
    • 이제 문제는 단지 3 작업과 1 큐 있지만 (이제까지이 문제를 해결하는 데 걸리는 것입니다 여기에

내 코드 지금까지

static void Main(string[] args) { 
     var data = new List<Task>() { 
      new Task(){ Duration = 1, Name = "task0"}, 
      new Task(){ Duration = 1, Name = "task1"}, 
      new Task(){ Duration = 1, Name = "task2"}, 
     }; 

     SolveScheduling(data); 
    } 

    public class Task { 
     private static int id_counter = 0; 
     public Task() { ID = id_counter++; } 
     public int ID { get; private set; } 
     public string Name { get; set; } 
     public double Duration { get; set; } 
    } 

    private static void SolveScheduling(IEnumerable<Task> data) { 

     SolverContext context = SolverContext.GetContext(); 
     Model model = context.CreateModel(); 

     var set = new Set(Domain.Any,"TaskSet"); 


     var projectFinish = new Decision(Domain.IntegerNonnegative, "projectFinish"); 
     model.AddDecision(projectFinish); 

     var taskSet = new Set(Domain.Any, "tasks"); 

     var durations = new Parameter(Domain.RealNonnegative, "durations", taskSet); 
     durations.SetBinding(data, "Duration", "Name"); 
     var ids = new Parameter(Domain.Integer, "ids", taskSet); 
     ids.SetBinding(data, "ID", "Name"); 
     var starts = new Decision(Domain.RealNonnegative, "starts", taskSet); 
     var finishs = new Decision(Domain.RealNonnegative, "finishs", taskSet); 

     model.AddDecisions(starts, finishs); 
     model.AddParameters(durations, ids); 

     // Constraints 

     // start + duration = finish 
     model.AddConstraint("constraint0", Model.ForEach(taskSet, (t) => starts[t] + durations[t] == finishs[t])); 
     // Tasks after each other 
     model.AddConstraint("constraint1", Model.ForEach(taskSet, t => 
      Model.ForEachWhere(taskSet, t2 => Model.Or(finishs[t] < starts[t2] , starts[t] > finishs[t2]), (t2) => ids[t] != ids[t2]))); 
     // projectFinish after all tasks finished 
     model.AddConstraint("constraint2", Model.ForEach(taskSet, t => projectFinish >= finishs[t])); 

     // Goals 
     model.AddGoal("goal0", GoalKind.Minimize, projectFinish); 


     Solution solution = context.Solve();//new SimplexDirective()); 

     Report report = solution.GetReport(); 
     Console.WriteLine(@"===== report ====="); 
     Console.Write("{0}", report); 
     Console.ReadLine(); 
    } 

입니다 projectFinish을 최소화). 내가 여기서 무엇을 놓치고 어떻게 해결 속도를 향상시킬 수 있을까요?

업데이트

나는 내 문제에 대한 해결책을 발견했다. 개선 사항이 있으면 언제든지 의견을 말하십시오. 여기 내 코드는 다음과 같습니다.

 SolverContext context = SolverContext.GetContext(); 
     Model model = context.CreateModel(); 

     // === Sets === 
     var taskSet = new Set(0,data.Count(), 1); 

     // === Parameters === 
     var duration = new Parameter(Domain.RealNonnegative, "durations", taskSet); 
     var id = new Parameter(Domain.RealNonnegative, "id", taskSet); 
     duration.SetBinding(data, "Duration", "ID"); 
     id.SetBinding(data, "ID", "ID"); 

     model.AddParameters(duration, id); 

     // === Decisions === 
     var projectFinish = new Decision(Domain.RealNonnegative, "projectFinish"); 
     var start = new Decision(Domain.RealNonnegative, "starts", taskSet); 
     var finish = new Decision(Domain.RealNonnegative, "finishs", taskSet); 

     model.AddDecisions(projectFinish, start, finish); 

     // === Constraints === 
     model.AddConstraint("constraint0", start[0] == 0); 
     // start + duration = finish 
     model.AddConstraint("constraint1", Model.ForEach(taskSet, (t) => start[t] + duration[t] == finish[t]));   
     // projectFinish after all tasks finished 
     model.AddConstraint("constraint2", Model.ForEach(taskSet, t => projectFinish >= finish[t])); 
     // not more than one task at a time 
     model.AddConstraint("constraint3", Model.ForEach(taskSet, t => 
      Model.ForEachWhere(taskSet, t2 => Model.Or(finish[t] < start[t2], start[t] > finish[t2]), (t2) => id[t] != id[t2]))); 


     // === Goals === 
     model.AddGoal("goal0", GoalKind.Minimize, projectFinish); // minimieren der projekt zeit 

     // === Solve === 
     context.CheckModel(); 
     Solution solution = context.Solve(); 

답변

0

나를 위해 적합한 해결책을 찾았습니다. 나는 taskSet에게

var taskSet = new Set(0, data.Count(), 1); 

을 변경하고 내가 질문

업데이트

model.AddConstraint("constraint", starts[0] == 0); 

새로운 제약 조건을 추가