代码之家  ›  专栏  ›  技术社区  ›  Yugmorf

将替身的二维数组绑定到MS Solver Foundation中的参数

  •  1
  • Yugmorf  · 技术社区  · 12 年前

    如何将二维数组绑定到解算器基础中的参数?已尝试将数组定义为double(,);作为double()和元组列表(double,i,j)。

    我还尝试实现了这里建议的SetBinding的扩展方法; http://blogs.msdn.com/b/solverfoundation/archive/2010/06/28/simpler-data-binding-using-linq-and-extension-methods.aspx

    目前在倒数第三行失败;m_cov.SetBinding(CovMatrix),错误为“此方法仅在对具有0个索引的参数调用时有效”

    我使用的是最新版本,在vb.net中工作。如有任何帮助,不胜感激。

    谢谢 是的

    Public Sub ERC()
    
            Dim m_i = New [Set](Domain.Any, "I")
            Dim m_j = New [Set](Domain.Any, "J")
            'Dim m_allocation As Decision
            Dim CovMatrix As Double()() = {New Double() {0.1, 0.15, 0.4}, New Double() {0.3, 0.5, 0.8}, New Double() {0, 0.33, 0.05}}
    
            Dim m_context As SolverContext = SolverContext.GetContext()
            Dim m_model As Model = m_context.CreateModel()
            m_model.Name = "ERC"
    
            ' Create a Parameter for Cov
            Dim m_cov = New Parameter(Domain.Real, "Cov", m_i, m_j)
            m_model.AddParameter(m_cov)
                ' Create a Decision for Allocation
            Dim m_allocation As Decision = New Decision(Domain.RealRange(-1.0, 1.0), "Allocation", m_i)
            m_model.AddDecision(m_allocation)
            ' Add Constraint for SumWts
            m_model.AddConstraint("SumWts", (Model.Sum(Model.ForEach(m_i, Function(i_1) Model.Abs(Model.Sum(m_allocation(i_1)))))) = 1.0)
            ' Add Goal for Variance
            m_model.AddGoal("Variance", GoalKind.Minimize, Model.Sum(Model.ForEach(m_i, Function(i_2) Model.ForEach(m_j, Function(j_3) Model.Power((Model.Abs(Model.Sum(Model.ForEach(m_j, Function(j_4) Model.Product(m_cov(i_2, j_4), m_allocation(j_4), m_allocation(i_2))))) - Model.Abs(Model.Sum(Model.ForEach(m_j, Function(j_6) Model.Product(m_cov(j_3, j_6), m_allocation(j_6), m_allocation(j_3)))))), 2.0)))))
    
            m_cov.SetBinding(CovMatrix)
            m_context.Solve()
            Debug.Print(m_allocation.GetValuesByIndex().ToString)
    End Sub
    
    1 回复  |  直到 12 年前
        1
  •  1
  •   Chronozoa    12 年前

    The helper class provided by Nathan Brixius 使SetBinding方式更容易。他的助手类是用C#编写的,所以我继续将您需要的特定助手函数转换为VB(见下文)。

    例外情况是告诉您 SetBinding 函数需要知道传入数据的索引。MSF是为处理泛型域而构建的,这意味着它不遵守正常的数组索引。您必须明确指出索引信息。

    代码的问题在于,您试图在没有任何额外索引数据的情况下传入原始数组。要在普通1D数组上解决此问题,可以使用添加索引 KeyValuePair(Of Integer, Double) .在这种情况下,对于矩阵,您需要一个列表 Tuple (index1, index2, Double) 。本质上,您需要将3x3矩阵展平为9个三元组,根据一对索引指定每个值。

    以下是VB函数,用于将矩阵转换为列表:

    Private Function ToIEnumerable(Of T)(matrix As IEnumerable(Of IEnumerable(Of T))) As IEnumerable(Of Tuple(Of Integer, Integer, T))
        Dim m = matrix.[Select](Function(row, i) row.[Select](Function(cell, j) New Tuple(Of Integer, Integer, T)(i, j, cell)))
        Dim cells = From cell In m.SelectMany(Function(c) c)
        Return cells
    End Function
    

    在类中包含此函数,然后更改代码的SetBinding行,如下所示:

    m_cov.SetBinding(ToIEnumerable(CovMatrix), "Item3", "Item1", "Item2")
    

    请注意 Tuple 项目!根据MSF惯例,值字段位于索引之前。在解决方案输出中返回相同的顺序(当您希望对结果集上的Decisions进行迭代时,需要注意的一点很重要)。

    如果您转换Nathan的助手类的其余部分,他会通过重载SetBinding函数本身来抽象掉 ToIEnumerable(data) 调用以及键/值标识符排序。然后你可以简单地打电话 model.SetBinding(rawMatrix)

    相当圆滑,是吗?)

    推荐文章