constraint-programming - 使用 Java 计算在区间中找到的变量的值
问题描述
我试图找到x和y可能采用的值,因此以下不等式成立:
1/24 < 1/15*y < 1/10*x < 2/24 < 2/15*y < 3/24
有没有办法在Java中制定这样的问题?约束编程可能会解决这样的问题,但有替代方法吗?
如果约束编程是唯一的方法,这看起来如何?
以下是我使用or-tools进行约束编程的尝试。如何制定严格的不等式?
MPSolver solver = new MPSolver(
"SimpleMipProgram", MPSolver.OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING);
// [END solver]
// [START variables]
double infinity = java.lang.Double.POSITIVE_INFINITY;
// x and y are float/double variables.
MPVariable x = solver.makeNumVar(0,1,"x"); //makeIntVar(0.0, infinity, "x");
MPVariable y = solver.makeNumVar(0,1,"y"); //makeIntVar(0.0, infinity, "y");
System.out.println("Number of variables = " + solver.numVariables());
// [END variables]
// [START constraints]
// x + 7 * y <= 17.5.
/*MPConstraint c0 = solver.makeConstraint(-1, 17.5, "c0");
c0.setCoefficient(x, 1);
c0.setCoefficient(y, 7);
// x <= 3.5.
MPConstraint c1 = solver.makeConstraint(-infinity, 3.5, "c1");
c1.setCoefficient(x, 1);
c1.setCoefficient(y, 0);*/
// 1/24 < 1/15*y ---> -1/15 * y < -1/24
MPConstraint c0 = solver.makeConstraint(-1000,-1/24.0,"c0");
c0.setCoefficient(y,-1/15.0);
// 1/15*y < 1/10*x ---> 1/15*y - 1/10*x < 0
MPConstraint c1 = solver.makeConstraint(-1000,0,"c1");
c1.setCoefficient(y,1/15.0);
c1.setCoefficient(x,-1/10.0);
// 1/10*x < 2/24 ---> 1/10*x < 2/24
MPConstraint c2 = solver.makeConstraint(-1000,2/24.0,"c2");
c2.setCoefficient(x,1/10.0);
// 2/24 < 2/15*y ---> -2/15*y < -2/24
MPConstraint c3 = solver.makeConstraint(-1000, -2/24.0);
c3.setCoefficient(y,-2/15.0);
// 2/15*y < 3/24 ---> 2/15*y < 3/24
MPConstraint c4 = solver.makeConstraint(-1000,3/24.0);
c4.setCoefficient(y,2/15.0);
解决方案
这是使用整数求解器的工作代码
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from ortools.sat.python import cp_model
model = cp_model.CpModel()
scale = 1000
x = model.NewIntVar(0, scale, 'x')
y = model.NewIntVar(0, scale, 'y')
# 1/24 < 1/15*y < 1/10*x < 2/24 < 2/15*y < 3/24
model.Add(5 * scale < 8 * y)
model.Add(8 * y < 12 * x)
model.Add(12 * x < 10 * scale)
model.Add(10 * scale < 16 * y)
model.Add(16 * y < 15 * scale)
solver = cp_model.CpSolver()
solver.parameters.log_search_progress = True
status = solver.Solve(model)
if status == cp_model.FEASIBLE:
print('x =', solver.Value(x) * 1.0 / scale)
print('y =', solver.Value(y) * 1.0 / scale)
当 scale = 1000 时,它输出:
x = 0.418
y = 0.626
使用 scale = 100,它输出:
x = 0.43
y = 0.63
scale = 10,它输出
x = 0.5
y = 0.7
推荐阅读
- java - 使用 java Marshaller 更改命名空间根名称
- javascript - Firebase 数据库 - 过滤和排序查询
- c# - 如何在 C# 键中使用“int?”在字典中设置键 null?
- c# - C# - 难以在我的字符串冒泡排序算法中查找错误
- python - 在 pandas 中命名依赖于函数的列
- java - ArrayList 是可变的吗?
- javascript - React Router 必须重新加载页面才能更改 url
- notifications - 更新通知进度的正确方法(android)
- c# - 如何为facebook messenger的英雄卡中的每个项目添加分享按钮 - Bot framework c#
- reactjs - `setState` 时重新生成多个 dom 标签