2011-12-18 4 views
4

Короткий и резкий:
Учитывая две логические утверждения, что это самый простой способ вычислить уравнение их пересечения в языке, как Lua?Действуя на абстрактных фильтров (список постижение): Объединение двух фильтров

Venn Diagram
(Красный = фильтр 1, Синий = фильтр 2, Фиолетовый = Область пересечения)

Длинные и причитала:

  • Фильтр A: object.ID < 300

  • Фильтр B: object.ID < 600

Фильтр A является подмножества из Фильтра Б, то есть: фильтр Б будет содержать все согласованное с Фильтром A, плюс 0 или более объектов. На диаграмме Венна, Фильтр A будет внутри Фильтр B.

Как вычислить уравнение площади пересечения?

Более сложный пример:

  • Фильтр Х: object.Col == 'GREEN' and (object.ID == 2 or object.ID == 64 or object.ID > 9001)
  • Фильтр Y: (object.Col == 'RED' or object.Col == 'GREEN') and (object.ID == 3 or object.ID > 22)

Фильтр A пересекается с фильтром B. На диаграмме Венна они накладываются друг на друга. Уравнение для области перекрытия будет:
object.Col == 'GREEN' and (object.ID == 64 or object.ID > 9001)

Как бы это уравнение рассчитывается на языке, таких как Python или Haskell?

Я хочу в конечном итоге сделать это в Lua, но если бы Python, Haskell или другой язык предоставили функциональность, я смог бы посмотреть исходный код и преобразовать его.

Вот как я представляю фильтры в Lua:

filter = DataFilter(
    {"and", 
     {"or", 
      {"==", "Col", "RED"}, 
      {"==", "Col", "GREEN"}, 
     }, 
     {"or", 
      {"==", "ID", 3}, 
      {">" , "ID", 22}, 
     }, 
    } 
) 

Пожалуйста, мне точку в правильном направлении.

ответ

3

Дикая догадка: Приведите «фильтры» в дизъюнктивную нормальную форму и уменьшите с помощью соответствующих методов (x == 8, содержащихся в x> 5).

+0

Благодарим вас за этот намек. Сейчас я изучаю это. – Deco

+0

Я рад, что смогу помочь :) – sleeplessnerd

2

Это как-то вы можете достичь этого.Код, прокомментированный пользователем, поможет вам понять подход

#Create a Class Foo with attributes id and col 
class Foo: 
    def __init__(this,ID,COL): 
     this.id=ID 
     this.col=COL 



#Dataset 
data=["VIOLET","INDIGO","BLUE","GREEN","YELLOW","ORANGE","RED"] 
ObjList=[Foo(random.randint(1,70),random.choice(data)) for i in xrange(1,10000)] 

#Create the Filter Functions 
def FilterX(obj): 
    return obj.col == 'GREEN' and (obj.id == 2 or obj.id == 64 or obj.id > 9001) 

def FilterY(obj): 
    return (obj.col == 'RED' or obj.col == 'GREEN') and (obj.id == 3 or obj.id > 22) 

def FilterZ(obj): 
    return obj.col == 'GREEN' and (obj.id > 50) 

#Create a list of filter functions 
filters=[FilterX,FilterY,FilterZ] 

#Create a set result (that will hold the intersected data) and assign the result of 
#applying the First Filter on ObjList 
result=set(filter(filters[0],ObjList)) 

#For the Rest of the filter's apply them on the ObjList, and then intersect 
#the resultant set with the result 
for s in (set(filter(foo,ObjList)) for foo in filters[1:]): 
    result=result.intersection(s) 

#Finally Display the result 
[(obj.id,obj.col) for obj in result] 
+1

Благодарим вас за пример кода. Хотя в конечном итоге это необходимо, я не прошу этого вопроса; Мне нужно уравнение полученного набора, а не самого множества. Определенно стоит проголосовать, хотя :) – Deco

1

Я не знаю, не хватает ли здесь важного момента. Кажется, что ваши фильтры просто возвращают логическое значение в зависимости от свойств «объекта». Почему бы вам просто не использовать регулярные «и» и «или» или «функции» для их создания?

Это, как я хотел бы сделать фильтры в Lua:

function filterX(object) 
    return object.Col == 'GREEN' and 
    (object.ID == 2 or object.ID == 64 or object.ID > 9001) 
end 

function filterY(object) 
    return (object.Col == 'RED' or object.Col == 'GREEN') and 
    (object.ID == 3 or object.ID > 22) 
end 

Вы можете определить «союз» или «пересечение» этих фильтров с этими дополнительными функциями:

function union(f,g) 
    return function(...) 
    return f(...) or g(...) 
    end 
end 

function intersection(f,g) 
    return function(...) 
    return f(...) and g(...) 
    end 
end 

И вот как вы составляете:

union(filterX, filterY)(object) -- returns true or false 
intersection(filterX, filterY)(object) -- true or false 

Или, если вы хотите использовать их часто:

filterXorY = union(filterX, filterY) 
filterXandY = intersection(filterX, filterY) 

filterXorY(object) -- true or false 
filterXandY(object) -- true or false 

Надеюсь, это поможет.

+0

Мне нужно получить выражение 'filterXandY', которое невозможно получить из Lua без бинарного модуля (или string.dump) и некоторых неприятных хаков. Кроме того, это не будет упрощено. Кроме того, не было бы способа определить, пересекаются ли фильтры X и фильтр Y или являются взаимоисключающими, если только не выполнялась переборка всех возможных объектов. – Deco

+1

Я вижу. Рассматривали ли вы использование математически ориентированных языков, таких как Mathematica, R или подобные, вместо общего языка программирования? Они должны иметь большую часть того, что вам нужно встроить. – kikito

Смежные вопросы