F # все перестановки класса C #

У меня есть класс C # MyClass.

И мне нужно было бы реализовать метод f #, возвращающий все возможные перестановки элементов в IList

Проблема в том, что MyClass содержит метод bool CheckOrder (предшественники IList), возвращающий истину, если экземпляр MyClass может быть помещен в перестановку после экземпляров MyClass в параметре. В противном случае этот метод возвращает false.

Пожалуйста, кто-нибудь может посоветовать мне, как реализовать правильную функцию F #.

Обновление: Пожалуйста, не могли бы вы обрисовать F # код теста метода, учитывая, что мой класс C # имеет метод: bool CheckOrder (предшественники IList)


person dargorar    schedule 07.04.2011    source источник
comment
Это может быть интересно: stackoverflow.com/questions/286427/; stackoverflow.com/questions/1526046/f-permutations   -  person Daniel    schedule 07.04.2011
comment
Еще один: stackoverflow.com/q/4495597   -  person ildjarn    schedule 07.04.2011
comment
С этим интерфейсом кажется, что единственное решение - создать и протестировать, т.е. создать все перестановки, а затем отфильтровать их. Это может быть непрактично для больших списков. При более явном представлении упорядочивающих ограничений должна быть возможна эффективная реализация с использованием методов планирования и программирования ограничений. Может быть, взгляните на Microsoft Solver Foundation.   -  person wmeyer    schedule 07.04.2011


Ответы (1)


Ваш метод CheckOrder ожидает IList<MyClass>, поэтому нам, возможно, следует работать с массивами на F #, поскольку массивы реализуют интерфейс IList.

Для каждого элемента в кандидате на перестановку нам нужно проверить, все ли его предшественники в массиве законны. На мой взгляд, это похоже на задание для fold операции, в которой параметр состояния fold представляет собой кортеж из «массива до сих пор» и логического флага успеха.

let checkPermutation (permutation:MyClass[]) =
   let prefix, success =
      permutation
      |> Array.fold (fun (prefix:MyClass[], success) element ->
                        if not success then
                           (Array.empty, false) // once failed, the result is false
                        else
                           (Array.append [|element|] prefix, element.CheckOrder prefix)
                    )
                    (Array.empty, true)
   success

Array.append, вероятно, довольно неэффективен. Если это слишком медленно, вам следует подумать об использовании вместо этого ResizeArray (который совпадает с C # List).

person wmeyer    schedule 11.04.2011