6

私は制約プログラミングの初心者で、C# プログラムでGoogle or-tools ライブラリを使用しています。

ソルバーに次の制約を追加します。

((t1 >= 12 && t1 <= 15) || (t2 >= 16 && t2 <= 18)) && (t1 + t2 ) < 30

したがって、C# で次のコードを記述します。

var solver = new Solver("My_CP_Colver");
var t1 = solver.MakeIntVar(12, 20,"t1");
var t2 = solver.MakeIntVar(12, 20,"t2");

solver.Add(???)//<-((t1 >= 12 && t1 <= 15)||(t2 >= 16 && t2 <= 18)) && ( t1 + t2 ) < 30

上記の制約を作成するための助けはありますか?

4

4 に答える 4

6

私の言語は python です。次の pytho コードを C# に簡単に変換できると思います。

model = cp_model.CpModel()

t1 = model.NewIntVar(12, 20, "t1")
t1_bool_ge = model.NewBoolVar("t1_bool_ge")
t1_bool_le = model.NewBoolVar("t1_bool_le")
t1_bool_and =  model.NewBoolVar("t1_bool_and")
tmp_t1 = []
tmp_t1.append(t1_bool_ge)
tmp_t1.append(t1_bool_le)
model.Add(t1 >= 12).OnlyEnforceIf(t1_bool_ge) # t1 >=12
model.Add(t1 <= 15).OnlyEnforceIf(t1_bool_le) # t1 <= 15
model.Add(t1_bool_and==1).OnlyEnforceIf(tmp_t1) # (t1 >=12)&&(t1 <= 15)

t2 = model.NewIntVar(12, 20, "t2")
t2_bool_ge = model.NewBoolVar("t2_bool_ge")
t2_bool_le = model.NewBoolVar("t2_bool_le")
t2_bool_and =  model.NewBoolVar("t2_bool_and")
tmp_t2 = []
tmp_t2.append(t2_bool_ge)
tmp_t2.append(t2_bool_le)
model.Add(t2 >= 16).OnlyEnforceIf(t2_bool_ge) # t2 >=16
model.Add(t2 <= 18).OnlyEnforceIf(t2_bool_le) # t2 <= 18
model.Add(t2_bool_and==1).OnlyEnforceIf(tmp_t2) #(t2 >=16) && (t2 <=18)

tmp_t1_t2 = []
tmp_t1_t2.append(t2_bool_and)
tmp_t1_t2.append(t1_bool_and)
model.Add(sum(tmp_t1_t2)==1) #((t1 >=12)&&(t1 <= 15))||((t2 >=16) && (t2 <=18))

model.Add(t1 + t2 < 30) # ( t1 + t2 ) < 30
于 2019-07-23T03:00:30.477 に答える
3

残念ながら、Google or-tools ライブラリは豊富な論理制約を提供していません。Java で実装を開発できる場合は、膨大な数の SAT 制約を備えた SAT ソルバーを含む Choco Solverを使用することをお勧めします。

Google or-tools で論理制約を作成する現在の方法は、論理制約を線形制約に変換することです。最初にこれを確認して変換の概念を理解してから、HakanKのWho kill Agathaの例を見てください。ここでは、論理制約に関連するこの実装の一部:

//   if (i != j) =>
//       ((richer[i,j] = 1) <=> (richer[j,i] = 0))
for(int i = 0; i < n; i++) {
  for(int j = 0; j < n; j++) {
    if (i != j) {
      solver.Add((richer[i, j]==1) - (richer[j, i]==0) == 0);
    }
  }
}

この投稿も確認できます。

于 2016-08-11T16:03:54.040 に答える
-1

まず、変数をドメインに対して定義する必要があります (例: 正の整数)。Solver次に、が解を求められる前に、制約と目的関数が定義されます。

C#次のコード例を問題に簡単に変換できます。

    string solverType = "GLPK_MIXED_INTEGER_PROGRAMMING";
    Solver solver = Solver.CreateSolver("IntegerProgramming", solverType);
    if (solver == null)
    {
      Console.WriteLine("Could not create solver " + solverType);
      return;
    }
    // x1 and x2 are integer non-negative variables.
    Variable x1 = solver.MakeIntVar(0.0, double.PositiveInfinity, "x1");
    Variable x2 = solver.MakeIntVar(0.0, double.PositiveInfinity, "x2");

    // Minimize x1 + 2 * x2.
    Objective objective = solver.Objective();
    objective.SetMinimization();
    objective.SetCoefficient(x1, 1);
    objective.SetCoefficient(x2, 2);

    // 2 * x2 + 3 * x1 >= 17.
    Constraint ct = solver.MakeConstraint(17, double.PositiveInfinity);
    ct.SetCoefficient(x1, 3);
    ct.SetCoefficient(x2, 2);

    int 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("x1 = " + x1.SolutionValue());
    Console.WriteLine("x2 = " + x2.SolutionValue());

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

ここからコピペ。


Håkan Kjellerstrandによる別の簡単な:

Solver solver = new Solver("Volsay", Solver.CLP_LINEAR_PROGRAMMING);

//
// Variables
//

Variable Gas = solver.MakeNumVar(0, 100000, "Gas");
Variable Chloride = solver.MakeNumVar(0, 100000, "Cloride");

Constraint c1 = solver.Add(Gas + Chloride <= 50);
Constraint c2 = solver.Add(3 * Gas + 4 * Chloride <= 180);

solver.Maximize(40 * Gas + 50 * Chloride);

int resultStatus = solver.Solve();

if (resultStatus != Solver.OPTIMAL) {
  Console.WriteLine("The problem don't have an optimal solution.");
  return;
}

Console.WriteLine("Objective: {0}", solver.ObjectiveValue());

Console.WriteLine("Gas      : {0} ReducedCost: {1}",
                  Gas.SolutionValue(),
                  Gas.ReducedCost());

Console.WriteLine("Chloride : {0} ReducedCost: {1}",
                  Chloride.SolutionValue(),
                  Chloride.ReducedCost());

Google OR Toolsで選言的制約を定義する方法がわかりません。

Microsoft Z3 SolverC#のAPI を使用すると、次のように実行できます。

    Context ctx = new Context();

    IntExpr t1 = ctx.MkIntConst("t1");
    IntExpr t2 = ctx.MkIntConst("t2");
    IntNum c12 = ctx.MkInt(12);
    IntNum c15 = ctx.MkInt(15);
    IntNum c16 = ctx.MkInt(16);
    IntNum c18 = ctx.MkInt(18);
    IntNum c30 = ctx.MkInt(30);

    Solver solver = ctx.MkSolver();

    BoolExpr constraintInterval12_15 = 
        ctx.MkAnd(ctx.MkLe(c12, t1), ctx.MkLe(t1, c15));
    BoolExpr constraintInterval16_18 = 
        ctx.MkAnd(ctx.MkLe(c16, t2), ctx.MkLe(t2, c18));
    BoolExpr constraintLe20 = 
        ctx.MkLt(ctx.MkAdd(t1, t2), c30);

    solver.Assert(constraintLe20);
    solver.Assert(ctx.MkOr(constraintInterval12_15, constraintInterval16_18));

    if (solver.Check() == Status.SATISFIABLE)
    {
        Model m = solver.Model;

        Console.WriteLine("t1 = " + m.Evaluate(t1));
        Console.WriteLine("t2 = " + m.Evaluate(t2));
    }
于 2015-01-07T23:14:23.627 に答える