2012-08-23 6 views
1

Solver Foundation에서 매개 변수에 2D 배열을 바인딩하는 방법은 무엇입니까? 배열을 double (,)으로 정의 해 보았습니다. double()() 및 튜플 (double, i, j)의 목록으로 사용됩니다.MS Solver Foundation의 매개 변수에 2D 배열 배열 바인딩하기

또한 여기에 제안 된 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에서 작업하고 있습니다. 어떤 도움을 주셔서 감사합니다.

감사합니다, 하기 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 

답변

1

The helper class provided by Nathan Brixius는 SetBinding 방법이 쉬워집니다. 그의 헬퍼 클래스는 C#에 있습니다. 그래서 나는 앞서 가서 VB에서 필요한 헬퍼 함수를 ​​변환했습니다 (아래 참조).

SetBinding 함수가 전달 된 데이터의 인덱스를 알아야한다는 예외는 있습니다. MSF는 일반 도메인을 처리하도록 만들어져 일반 배열 인덱스를 따르지 않습니다. 인덱스 정보를 명시 적으로 지적해야합니다.

코드에 문제가 있으면 추가 인덱스 데이터없이 원시 배열을 전달하려고합니다. 이것을 정상적인 1D 배열로 해결하려면 KeyValuePair(Of Integer, Double)을 사용하여 인덱스를 추가합니다. 매트릭스의 경우이 경우 Tuple (index1, index2, Double)의 목록이 필요합니다. 본질적으로, 3x3 행렬을 9 개의 트리플로 전개해야하며, 한 쌍의 인덱스에 따라 각 값을 지정해야합니다.

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") 
을 여기

같은 목록으로 행렬을 변환 할 VB 기능입니다

Tuple 품목 주문에주의하십시오! MSF 협약에 의해, 값 필드는 인덱스 앞에옵니다. 솔루션 출력에 동일한 순서가 반환됩니다 (결과 집합의 의사 결정을 반복 할 때주의해야합니다). 당신은 나단의 헬퍼 클래스의 나머지 부분을 변환하면

, 그는 ToIEnumerable(data) 전화뿐만 아니라 키/값 식별자 순서를 추상화에 SetBinding 기능 자체를 오버로드하여도 쉬워집니다. 그런 다음 model.SetBinding(rawMatrix)으로 전화하면됩니다.

꽤 매끄러운가? ;)