如何使用Solver Foundation Services将“元素”设置为“约束”中的系数 [英] How to use Set elements as coefficients in Constraint using Solver Foundation Services

查看:117
本文介绍了如何使用Solver Foundation Services将“元素”设置为“约束”中的系数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个Decision变量x,参数ABSCISSA和ORDINATE都有ABSCISSA.IndexSets.Count == ORDINATE.IndexSets.Count == 1,我试图建立一个近似于分段线性的SOS2约束由坐标
(ABSCISSA [i],ORDINATE [i])给出的实值函数,i在ABSCISSA.IndexSets [0]中。 ABSCISSA值保证按严格单调递增的顺序排序,但可能会 包含值0.0。因此,ABSCISSA不能用于"参考行"。因为系数只允许非零值

Given a Decision variable x, and Parameter ABSCISSA and ORDINATE both of which have ABSCISSA.IndexSets.Count == ORDINATE.IndexSets.Count == 1, I am trying to set up a SOS2 constraint that approximates piecewise linear a real-valued function given by coordinates (ABSCISSA[i],ORDINATE[i]), i in ABSCISSA.IndexSets[0]. The ABSCISSA values are guaranteed to be sorted in strictly monotonically increasing order, but may  contain the value 0.0. Hence ABSCISSA cannot be used in the "Reference-Row" as only non-zero values for the coefficients are allowed.

因此我编码:

决策sos_dummy =新决策(域名。 RealRange(0.0,1.0)," sos_dummy");
$
决定sos_x =新决策(Domain.Real," sos_x",ABSCISSA.IndexSets [0]);

决定fx =新决策(Domain.Real," fx");

model.AddDecisions(sos_dummy,sos_x,sos_fx);

¥ b $ b //参考行

model.AddConstraint(" RefRowCnstr",

    Model.Sos2(sos_dummy == Model.Sum(Model) .ForEach(ABSCISSA.IndexSets [0],k =>
(k + 1) * sos_x [k])));



//横坐标行

model.AddConstraint(" AbscissaRowCnstr",&
    x == Model.Sum(Model.ForEach) (ABSCISSA.IndexSets [0],k => ABSCISSA [k] * sos_x [k])));
$


//纵坐标行

model.AddConstraint(" OrdinateRowCnstr",

    fx == Mod el.Sum(Model.ForEach(ABSCISSA.IndexSets [0],k => ORDINATE [k] * sos_x [k])));
$


//凸性行(不确定我是否需要它)

model.AddConstraint(" ConvexityRowCnstr",&
    1.0 == Model.Sum(Model.ForEach(ABSCISSA.IndexSets [0],k => sos_x [k] )));
$


术语objectiveTerm = fx;

Decision sos_dummy = new Decision(Domain.RealRange(0.0, 1.0), "sos_dummy");
Decision sos_x = new Decision(Domain.Real, "sos_x", ABSCISSA.IndexSets[0]);
Decision fx = new Decision(Domain.Real, "fx");
model.AddDecisions(sos_dummy, sos_x, sos_fx);

// Reference row
model.AddConstraint("RefRowCnstr",
    Model.Sos2(sos_dummy == Model.Sum(Model.ForEach(ABSCISSA.IndexSets[0], k => (k+1) * sos_x[k])));

// Abscissa row
model.AddConstraint("AbscissaRowCnstr",
    x == Model.Sum(Model.ForEach(ABSCISSA.IndexSets[0], k => ABSCISSA[k] * sos_x[k])));

// Ordinate row
model.AddConstraint("OrdinateRowCnstr",
    fx == Model.Sum(Model.ForEach(ABSCISSA.IndexSets[0], k => ORDINATE[k] * sos_x[k])));

// Convexity row (not sure that I need that at all)
model.AddConstraint("ConvexityRowCnstr",
    1.0 == Model.Sum(Model.ForEach(ABSCISSA.IndexSets[0], k => sos_x[k])));

Term objectiveTerm = fx;

 

我遇到的问题是"参考行"和"参考行"。粗体位:索引
k
不能用作参考行中的系数。因此我想创建一个新变量

The problem I run into is with the "Reference-Row" bit in bold: The index k cannot not be used as the coefficient in the reference row. Hence I would like to create a new variable

参数INDEX = new Parameter(Domain.IntegerNonnegative," INDEX",ABSCISSA.IndexSets [0]);

Parameter INDEX = new Parameter(Domain.IntegerNonnegative, "INDEX", ABSCISSA.IndexSets[0]);

然后我可以绑定到整数数组

which I then could bind to an Integer array

int [] index = new int [ABSCISSA.IndexSets [0] .Size]; //或Count或NumElements或其他

int[] index = new int[ABSCISSA.IndexSets[0].Size]; // or Count or NumElements or whatever

并将其初始化为

for(int i = 0; i< ABSCISSA.IndexSets [0] .Size; ++ i)

{

    index [i] =(i + 1);

}

for(int i = 0; i < ABSCISSA.IndexSets[0].Size; ++i)
{
    index[i] = (i + 1);
}

INDEX.SetBinding(index);       &NBSP;&NBSP;&NBSP;&NBSP;&NBSP; //注意我有BindingUtilities可用,它将SetBinding扩展为int []和double []。

INDEX.SetBinding(index);            // note I have the BindingUtilities available that extents the SetBinding to int[] and double[].

参考行将是:

//参考行

model.AddConstraint(" RefRowCnstr",

    Model.Sos2(sos_dummy == Model.Sum(Model.ForEach( ABSCISSA.IndexSets [0],k =>
INDEX [k] * sos_x [k])));

// Reference row
model.AddConstraint("RefRowCnstr",
    Model.Sos2(sos_dummy == Model.Sum(Model.ForEach(ABSCISSA.IndexSets[0], k => INDEX[k] * sos_x[k])));

代替。

Unfortunatley.Microsoft.SolverFoundation.Services.Set没有任何方法或属性可以获取给定集合中的元素数量。我怎么能实现这种行为?任何提示都表示赞赏。

Unfortunatley. Microsoft.SolverFoundation.Services.Set does not have any method or property that allows to get at the number of elements in a given set. How could I achieve this behaviour? Any hint appreciated.

 

推荐答案

为ABSCISSA设置的索引是否被声明为Any?如果是,将其更改为Real应解决您的问题。当该集声明为Any时,求解器基础服务将拒绝尝试使用索引元素进行数学运算,因为他们可能不是数字。
声明为Real或Integer将允许您使用原始尝试,而无需经历创建额外参数的麻烦。

Is the index set for ABSCISSA declared as Any? If it is, changing it to Real should fix your problem. When the set is declared as Any, the solver foundation services will reject attempts to do math with the index elements, since they might not be numbers. Declaring it as Real or Integer will let you use your original attempt without going through the hassle of creating an extra parameter.

Ross


这篇关于如何使用Solver Foundation Services将“元素”设置为“约束”中的系数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆