2016-10-14 3 views
0

Microsoftソルバーフレームワークでタスクをスケジュールします。今のところ私は単純な目標を待ち行列に並べるだけで、プロジェクトの時間を最小限に抑えることができます。 (後で私は複数のキューを持っていたい)。MSソルバーフレームワークでのC#スケジューリングタスク

  • 決定:
    • projectFinish
    • 開始
    • 仕上げ
  • パラメータ:
      私は次のセットアップでこれにアプローチしようとしました
    • 期間は
  • 制約:
    • 開始+持続=すべてのタスクが
  • ゴールを終え
  • 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(); 
    } 

です)。私はここで何が欠けていますか、どのようにして解決のスピードを上げることができますか?

更新

私は私の問題の解決策を見つけました。改善があれば、気軽にコメントしてください。ここに私のコードです:

 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

私のために働く解決策が見つかりました。私は質問

を更新

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

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

タスクセット

を変更し、新しい制約を追加しました
関連する問題