Определите две функции с множественными значениями:
N(d1...dn): The subset of the image where members start with a particular sequence of digits d0...dn.
D(d1...dn): The subset of the inputs that produce N(d1...dn).
Тогда, когда последовательности пусты, у нас есть полная проблема:
D(): The entire domain.
N(): The entire image.
Из полного домена мы можем определить два подмножества:
D(0) = The subset of D() such that F(x)[1]==0 for any x in D().
D(1) = The subset of D() such that F(x)[1]==1 for any x in D().
Этот процесс может быть применен рекурсивно для генерации D для каждой последовательности.
D(d1...d[m+1]) = D(d1...dm) & {x | F(x)[m+1]==d[m+1]}
Затем мы можем определить N (x) для полных последовательностей:
N(d1...dn) = 0 if D(d1...dn) = {}
N(d1...dn) = 1 if D(d1...dn) != {}
Родительские узлы могут быть получены от двух дочерних элементов, пока мы не создадим N ().
Если в какой-то момент мы определим, что D (d1 ... dm) пусто, то мы знаем,
что N (d1 ... dm) также пусто, и мы можем избежать обработки этой ветви.
Это основная оптимизация.
Следующий код (в Python) описывает процесс:
def createImage(input_set_diagram,function_diagrams,index=0):
if input_set_diagram=='0':
# If the input set is empty, the output set is also empty
return '0'
if index==len(function_diagrams):
# The set of inputs that produce this result is non-empty
return '1'
function_diagram=function_diagrams[index]
# Determine the branch for zero
set0=intersect(input_set_diagram,complement(function_diagram))
result0=createImage(set0,function_diagrams,index+1)
# Determine the branch for one
set1=intersect(input_set_diagram,function_diagram)
result1=createImage(set1,function_diagrams,index+1)
# Merge if the same
if result0==result1:
return result0
# Otherwise create a new node
return {'index':index,'0':result0,'1':result1}