1

如何将二维数组绑定到 Solver Foundation 中的参数?尝试将数组定义为 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
4

1 回答 1

1

Nathan Brixius 提供的帮助器类使 SetBinding 更容易。他的助手类在 C# 中,所以我继续将您需要的特定助手函数转换为 VB(见下文)。

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

您的代码的问题是您试图在没有任何额外索引数据的情况下传入原始数组。要在正常的一维数组上解决此问题,您可以使用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 约定,值字段位于索引之前。解决方案输出中返回相同的顺序(当您希望迭代结果集上的决策时,请务必注意)。

ToIEnumerable(data)如果您转换 Nathan 的辅助类的其余部分,他会通过重载 SetBinding 函数本身以抽象出调用以及键/值标识符排序,从而使其变得更加容易。然后你就可以简单地调用model.SetBinding(rawMatrix).

很光滑,嗯?;)

于 2013-06-08T12:32:54.223 回答