2014-11-29

Enumerate 2-Permutations of List Elements

リスト要素の2-順列を列挙する

This is a question on how to enumerate every 2-permutation of elements in a list.
この問題は、リスト要素の全ての2-順列を列挙する方法に関するものです。
Community Answers > permute a list, output to csv

Source = [11, 22, 33]
2-Permutations = [[11, 22], [11, 33], [22, 11], [22, 33], [33, 11], [33, 22]]

I suggested these 3 ways.
次の3つの方法を提案しました。
1. ListExploder+AttributeRenamer+FeatureMerger+ListExploder+Tester
2. ListExploder+InlineQuerier (SQL statement)
3. PythonCaller (Python script)

Here, add one more way.
ここではもうひとつ追加します。
4. TclCaller (Tcl script)+ListExploder








-----
# TclCaller Script Example
proc extractPermutation {} {
    set values {}
    set range {}
    for {set i 0} {[FME_AttributeExists "List{$i}"]} {incr i} {
        lappend values [FME_GetAttribute "List{$i}"]
        lappend range $i
    }
    set index 0
    foreach i $range v1 $values {
        foreach j $range v2 $values {
            if {$i != $j} {
                FME_SetAttribute "_join{$index}.Field1" $v1
                FME_SetAttribute "_join{$index}.Field2" $v2
                incr index
            }
        }
    }
}
-----

My favorite is the SQL approach, and Tcl is also difficult to throw away. But Python could be the most efficient solution in this case.
SQLアプローチが気に入っているしTclも捨てがたいのですが、この場合はPythonが最も効率的かも知れません。
-----
# PythonCaller Script Example
import fmeobjects
class FeatureProcessor(object):
    def input(self, feature):
        L = feature.getAttribute('List{}')
        if L:
            for v1, v2 in [(v1, v2) for i, v1 in enumerate(L) for j, v2 in enumerate(L) if i != j]:
                newFeature = fmeobjects.FMEFeature()
                # If you need to retain the List{} and other attributes,
                # replace the line above with this.
                # newFeature = feature.cloneAttributes()
                newFeature.setAttribute('Field1', v1)
                newFeature.setAttribute('Field2', v2)
                self.pyoutput(newFeature)
-----

FME 2014 SP4 build 14433

=====
2014-12-01: Probably this script works a treat for enumerating general K-Permutations (K is an arbitrary number).
おそらくこのスクリプトは、一般のK-順列をうまく列挙します(Kは任意の数)。
-----
# PythonCaller Script Example
# Enumerates K-Permutations of List Elements.
# Results will be stored by a nested list named "_perm{}.item{}".
# Assume that "K" (number of items in a permutation) will be specified
# by a feature attribute called "_k".
class PermutationEnumerator(object):
    def input(self, feature):
        src = feature.getAttribute('_list{}')
        self.k = int(feature.getAttribute('_k'))
        if self.k <= len(src):
            self.i = 0
            for i in range(len(src)):
                s = src[:]
                t = [s.pop(i)]
                self.enumeratePermutation(feature, s, t, 1)
        else:
            feature.setAttribute('_rejected', 1)
        self.pyoutput(feature)
         
    def enumeratePermutation(self, feature, s, t, depth):
        if self.k <= depth:
            for j in range(self.k):
                feature.setAttribute('_perm{%d}.item{%d}' % (self.i, j), t[j])
            self.i += 1
        else:
            for i in range(len(s)):
                c, d, = s[:], t[:]
                d.append(c.pop(i))
                self.enumeratePermutation(feature, c, d, depth + 1)
-----
=====
2014-12-05: See also the ListSubsetEnumerator transformer in the FME Store.
FME Store の ListSubsetEnumerator トランスフォーマーも参照してください。

No comments:

Post a Comment