我能夠使用@PaulHankin的指導來解決這個問題。這裏是使用Google's OR tools的解決方案。
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();
}
具有統一成本(如果您總是需要1而不是任意數字)的版本是命中集問題,這是NP難。您可以將問題表達爲ILP並使用解算器,例如GLPK。 –
我認爲你可以建立一個圖,然後用掩碼運行Dijkstra的算法,整個算法看起來太複雜了,我會嘗試解釋(這也是蠻力解決方案的優化,並且速度不夠快)。但也許它可能找到更容易的解決方案... – SashaMN
@PaulHankin - 請把你的評論作爲答案,我會把它標記爲答案。我感謝您的幫助! – randomsolutions