Java 在ojAlgo中检测导致无界优化问题的成本/变量
我使用ojAlgo线性/二次解算器via来解决绘图库中图形元素的布局,以便它们整齐地适应屏幕边界。具体地说,我想解决缩放和平移问题,这样散点图的坐标就会填满屏幕空间。我通过声明Java 在ojAlgo中检测导致无界优化问题的成本/变量,java,optimization,linear-programming,ojalgo,Java,Optimization,Linear Programming,Ojalgo,我使用ojAlgo线性/二次解算器via来解决绘图库中图形元素的布局,以便它们整齐地适应屏幕边界。具体地说,我想解决缩放和平移问题,这样散点图的坐标就会填满屏幕空间。我通过声明expressionbasedModel的缩放和平移变量来实现这一点,并使用这些变量将散点图坐标转换到屏幕上,然后构建线性约束,转换后的坐标应投影到屏幕内。我还为比例变量添加了一个负成本,这样它们就被最大化了,散点图覆盖了尽可能多的屏幕空间我的问题是,在某些特殊情况下,例如,如果我只有一个点要绘制,这将导致一个无界问题,其
expressionbasedModel
的缩放和平移变量来实现这一点,并使用这些变量将散点图坐标转换到屏幕上,然后构建线性约束,转换后的坐标应投影到屏幕内。我还为比例变量添加了一个负成本,这样它们就被最大化了,散点图覆盖了尽可能多的屏幕空间我的问题是,在某些特殊情况下,例如,如果我只有一个点要绘制,这将导致一个无界问题,其中比例趋于无穷大,没有任何约束处于活动状态我如何检测可能发生这种情况的比例变量,并将其固定到一些默认值
为了说明上述问题,我构建了一个玩具绘图库(我正在处理的完整库太大,无法容纳这个问题)。为了帮助布局图形元素,我有一个问题类:
class Problem {
private ArrayList<Variable> _scale_variables = new ArrayList<Variable>();
private ExpressionsBasedModel _model = new ExpressionsBasedModel();
Variable freeVariable() {
return _model.addVariable();
}
Variable scaleVariable() {
Variable x = _model.addVariable();
x.lower(0.0); // Negative scale not allowed
_scale_variables.add(x);
return x;
}
Expression expr() {
return _model.addExpression();
}
Result solve() {
for (Variable scale_var: _scale_variables) {
// This is may result in unbounded solution for degenerate cases.
Expression expr = _model.addExpression("Encourage-larger-scale");
expr.set(scale_var, -1.0);
expr.weight(1.0);
}
return _model.minimise();
}
}
respectBounds
方法用于将散点图中单个点的约束添加到前面提到的问题
类中。要添加散点图的所有点,我有以下功能:
void addScatterPoints(
double[] xy_pairs,
// How much space every marker occupies
double marker_size,
Transform2d transform_to_screen,
// Screen size
double width, double height,
Problem problem) {
int data_count = xy_pairs.length/2;
for (int i = 0; i < data_count; i++) {
int offset = 2*i;
double x = xy_pairs[offset + 0];
double y = xy_pairs[offset + 1];
transform_to_screen.respectBounds(x, y, marker_size, width, height, problem);
}
}
它打印出解决方案:最优-81.0958904109589@{0,81.0958904109589795.9999999966,-158.1917808219794}
这就是退化情况的样子,使用相同的y坐标绘制两个点:
它显示Solution:UNBOUNDED-596.0@{88.444444596,0,0}
。
如前所述,我的问题是:我如何检测负成本将导致无界解的比例变量,并将其约束为某个默认值,以便我的解不是无界的?在这种情况下,“只有一个点绘制”您想要什么解?在这种情况下,我想确定有问题的比例变量(走向无穷大并导致无界解),并添加等式约束,即它们应取值1。我想要的解决方案是这个带有附加等式约束的改进优化问题的解决方案。当点之间只有1个x值或1个y值时,问题不是这样吗?如果是这样的话,那么在生成模型并进行调整之前检查一下。是的,这是一个可能导致它的问题。然而,在现实中,绘图可能以更复杂的方式构建,具有更多坐标系、坐标系之间的约束等,这将使这种退化情况更难检测。我还没有真正研究过ojAlgo的实现,但是我认为也许API可以从最终的simplex表中指出这些问题。检测此问题的最简单方法是在尺度变量上设置一个巨大的上界,使问题有界,并帮助识别无界尺度变量。ojAlgo将告诉您LP是无界的还是不可行的,除了原始变量外,您还可以得到双变量的result.getMultipliers()“仅绘制一个点”您想要什么解决方案?在这种情况下,我想确定有问题的比例变量(走向无穷大并导致无界解决方案)并添加相等约束,使其取值为1。我想要的解决方案是使用添加的相等约束解决此修改优化问题。当点之间只有1个x值或1个y值时,这不是问题吗?如果是,则在生成模型并进行调整之前检查。是的,这是一个可能导致这种情况的问题。但实际上,绘图可能会以更复杂的方式构建,具有更多的坐标系、坐标系之间的约束等,这将使这种退化情况更难检测。我没有真正研究ojAlgo的实现,但认为API可能指向o但这些问题可能来自最终的单纯形表。检测这个问题的最简单的方法是在尺度变量上设置一个巨大的上界,使问题有界,并帮助识别无界尺度变量。ojAlgo将告诉您LP是无界的还是不可行的,您可以得到对偶变量的结果。getMultiplier除了原始的。
void addScatterPoints(
double[] xy_pairs,
// How much space every marker occupies
double marker_size,
Transform2d transform_to_screen,
// Screen size
double width, double height,
Problem problem) {
int data_count = xy_pairs.length/2;
for (int i = 0; i < data_count; i++) {
int offset = 2*i;
double x = xy_pairs[offset + 0];
double y = xy_pairs[offset + 1];
transform_to_screen.respectBounds(x, y, marker_size, width, height, problem);
}
}
Problem problem = new Problem();
double marker_size = 4;
double width = 800;
double height = 600;
double[] data_to_plot = new double[] {
1.0, 2.0,
4.0, 9.3,
7.0, 4.5};
Transform2d transform = new Transform2d(problem);
addScatterPoints(data_to_plot, marker_size, transform, width, height, problem);
Result result = problem.solve();
System.out.println("Solution: " + result);
Problem problem = new Problem();
double marker_size = 4;
double width = 800;
double height = 600;
double[] data_to_plot = new double[] {
1, 1,
9, 1
};
Transform2d transform = new Transform2d(problem);
addScatterPoints(data_to_plot, marker_size, transform, width, height, problem);
Result result = problem.solve();
System.out.println("Solution: " + result);