문제

How to bind a 2D array to a parameter in Solver Foundation? Have tried defining the array as double(,); as double()() and as a list of tuples(double, i, j).

I have also tried to implement the extension methods to SetBinding, suggested here; http://blogs.msdn.com/b/solverfoundation/archive/2010/06/28/simpler-data-binding-using-linq-and-extension-methods.aspx

Currently fails at third line to bottom; m_cov.SetBinding(CovMatrix), with error "This method is only valid when called on parameters with 0 indexes"

I'm using latest version and working in vb.net. Any help appreciated.

Thanks, Yug

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
도움이 되었습니까?

해결책

The helper class provided by Nathan Brixius makes SetBinding way easier. His helper class is in C#, so I went ahead and converted the particular helper function you will need into VB (see below).

The exception is telling you that the SetBinding function needs to know the indices for the data passed in. MSF is built to handle generic domains, meaning it does not abide by normal array indices. You have to explicitly point out the index information.

The problem with your code is that you are trying to pass in raw arrays without any extra index data. To remedy this on a normal 1D array, you would add indices using KeyValuePair(Of Integer, Double). In this case for a matrix you need a list of Tuple (index1, index2, Double). Essentially, you need to flatten the 3x3 matrix into 9 triples, specifying each value according to a pair of indices.

Here is the VB function to convert your matrix into a list as such:

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

Include this function in your class, and then change the SetBinding line of code like so:

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

Notice the ordering of the Tuple items! By MSF convention, the value field comes before the indices. The same ordering is returned in the Solution output (important to note when you are looking to iterate over the Decisions on the result set).

If you convert the rest of Nathan's helper class, he makes it even easier by overloading the SetBinding function itself to abstract away the ToIEnumerable(data) call as well as the key/value identifier ordering. Then you are able to simply call model.SetBinding(rawMatrix).

Pretty slick, eh? ;)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top