Algorithm 完成任务的最佳方式

Algorithm 完成任务的最佳方式,algorithm,graph-algorithm,Algorithm,Graph Algorithm,为了获得“技能”,我必须完成与该技能相关的一定数量的“任务” Skill 1: Need 1 of A, B, C, D, or E Skill 2: Need 2 of B, F, or G Skill 3: Need 1 of X, Y, or Z Skill 4: Need 2 of F or X 假设所有“任务”成本相同: Optimal Answer: 1 Task B 1 Task F 1 Task X 当任务的成本并不总是相同时,有没有关于高效算法的建议来帮助找到最佳输出?我

为了获得“技能”,我必须完成与该技能相关的一定数量的“任务”

Skill 1: Need 1 of A, B, C, D, or E 
Skill 2: Need 2 of B, F, or G
Skill 3: Need 1 of X, Y, or Z
Skill 4: Need 2 of F or X
假设所有“任务”成本相同:

Optimal Answer:
1 Task B
1 Task F
1 Task X

当任务的成本并不总是相同时,有没有关于高效算法的建议来帮助找到最佳输出?

我可以通过@PaulHankin的指导来解决这个问题。下面是使用的解决方案


具有统一成本的版本(如果您总是需要1而不是任意数字)是命中集问题,这是NP难问题。你可以将问题表述为ILP并使用解算器,例如GLPK。我认为你可以构建一个图,然后使用位掩码运行Dijkstra的算法,整个算法看起来太复杂了,我将尝试解释(这也是蛮力解的优化,速度不够快)。但也许找到更简单的解决办法是可能的…@PaulHankin-请把你的评论作为答案,我会把它标记为已回答。我感谢你的帮助!
  static void Main()
  {
      var solver = Solver.CreateSolver("IntegerProgramming", "CBC_MIXED_INTEGER_PROGRAMMING");
      // all are integer non-negative variables.
      var a = solver.MakeIntVar(0.0, double.PositiveInfinity, "a");
      var b = solver.MakeIntVar(0.0, double.PositiveInfinity, "b");
      var c = solver.MakeIntVar(0.0, double.PositiveInfinity, "c");
      var d = solver.MakeIntVar(0.0, double.PositiveInfinity, "d");
      var e = solver.MakeIntVar(0.0, double.PositiveInfinity, "e");
      var f = solver.MakeIntVar(0.0, double.PositiveInfinity, "f");
      var g = solver.MakeIntVar(0.0, double.PositiveInfinity, "g");
      var x = solver.MakeIntVar(0.0, double.PositiveInfinity, "x");
      var y = solver.MakeIntVar(0.0, double.PositiveInfinity, "y");
      var z = solver.MakeIntVar(0.0, double.PositiveInfinity, "z");

      // Minimize a + b + c + d + e + f + g + x + y + z
      var objective = solver.Objective();
      objective.SetMinimization();
      objective.SetCoefficient(a, 1);
      objective.SetCoefficient(b, 1);
      objective.SetCoefficient(c, 1);
      objective.SetCoefficient(d, 1);
      objective.SetCoefficient(e, 1);
      objective.SetCoefficient(f, 1);
      objective.SetCoefficient(g, 1);
      objective.SetCoefficient(x, 1);
      objective.SetCoefficient(y, 1);
      objective.SetCoefficient(z, 1);

      // Skill 1: a + b + c + d + e >= 1
      var skill1 = solver.MakeConstraint(1, double.PositiveInfinity);
      skill1.SetCoefficient(a, 1);
      skill1.SetCoefficient(b, 1);
      skill1.SetCoefficient(c, 1);
      skill1.SetCoefficient(d, 1);
      skill1.SetCoefficient(e, 1);

      // Skill 2: b + f + g >= 2
      var skill2 = solver.MakeConstraint(2, double.PositiveInfinity);
      skill2.SetCoefficient(b, 1);
      skill2.SetCoefficient(f, 1);
      skill2.SetCoefficient(g, 1);

      // Skill 3: x + y + z >= 1
      var skill3 = solver.MakeConstraint(1, double.PositiveInfinity);
      skill3.SetCoefficient(x, 1);
      skill3.SetCoefficient(y, 1);
      skill3.SetCoefficient(z, 1);

      // Skill 4: f + x >= 2
      var skill4 = solver.MakeConstraint(2, double.PositiveInfinity);
      skill4.SetCoefficient(f, 1);
      skill4.SetCoefficient(x, 1);

      var resultStatus = solver.Solve();

      // Check that the problem has an optimal solution.
      if (resultStatus != Solver.OPTIMAL)
      {
          Console.WriteLine("The problem does not have an optimal solution!");
          return;
      }

      Console.WriteLine("Problem solved in " + solver.WallTime() + " milliseconds");

      // The objective value of the solution.
      Console.WriteLine("Optimal objective value = " + objective.Value());

      // The value of each variable in the solution.
      Console.WriteLine("a = " + a.SolutionValue());
      Console.WriteLine("b = " + b.SolutionValue());
      Console.WriteLine("c = " + c.SolutionValue());
      Console.WriteLine("d = " + d.SolutionValue());
      Console.WriteLine("e = " + e.SolutionValue());
      Console.WriteLine("f = " + f.SolutionValue());
      Console.WriteLine("g = " + g.SolutionValue());
      Console.WriteLine("x = " + x.SolutionValue());
      Console.WriteLine("y = " + y.SolutionValue());
      Console.WriteLine("z = " + z.SolutionValue());

      Console.WriteLine("Advanced usage:");
      Console.WriteLine("Problem solved in " + solver.Nodes() + " branch-and-bound nodes");
      Console.ReadKey();
  }