Проблема в том, что вы сравниваете тензор с формой [None, 5]
(ранг 2) со скейлером (ранг 0), что невозможно при tf.greater
или tf.less
[116 ]. Вместо этого вы можете использовать tf.math...
, которые поддерживают вещание.
Вот одно из возможных решений для реализации этой функции:
import tensorflow as tf
x = tf.placeholder(dtype=tf.float32, shape=[1, 5])
cond1 = tf.cast(tf.math.greater(x, 2.0), tf.float32)
cond2 = tf.cast(tf.math.logical_and(tf.math.less_equal(x, 2.0), tf.math.greater_equal(x, 0.0)), tf.float32)
cond3 = tf.cast(tf.math.logical_and(tf.math.less(x, 0.0), tf.math.greater_equal(x, -2.0)), tf.float32)
cond4 = tf.cast(tf.math.less(x, -2.0), tf.float32)
a = tf.math.multiply(cond1, 1.0)
b = tf.math.multiply(cond2, (x - tf.square(x) / 4))
c = tf.math.multiply(cond3, (x + tf.square(x) / 4))
d = tf.math.multiply(cond4, -1.0)
f = a + b + c + d
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(f, feed_dict={x: [[-1.0, -5, 1.5, -1.5, 5]]}))
Эта проблема полна NP, и таким образом, не известно, существует ли полиномиально-разовое решение. (Стандарт provisos того, чтобы возможно быть легким на практике, и т.д., все применяются.) Одно возможное сокращение от 3SAT.
Предположим, что мы имеем 3SAT экземпляр, такой как (∨ b ∨ c) ∧ (¬a ∨ ¬b ∨ ¬c). Я покажу, как использовать "гаджеты" для создания экземпляра из проблемы. Прежде чем мы начнем, перепишем 3SAT проблема как (a1 ∨ b1 ∨ c1) ∧ (¬a2 ∨ ¬b2 ∨ ¬c2) вместе с a1 = a2, b1 = b2, и c1 = c2; то есть, сделайте каждое возникновение переменной уникальным, но затем добавьте условие, что различные случаи той же переменной должны быть равными.
Во-первых, мы удостоверяемся, что необходимо выбрать номер 0 в первой строке, так, чтобы мы могли использовать его позже в качестве "сигнальной метки", которой необходимо избежать.
0 0 0
Теперь, мы создаем гаджет, который осуществляет a1 = a2 правило: (Подчеркивание _
вот новое уникальное число в каждом использовании этого гаджета),
0 _ 0
a1 0 ¬a1
a2 0 ¬a2
Из-за первой строки необходимо избежать 0s. Это означает или взятие пути "a1, a2" или пути "¬a1, ¬a2"; первый будет соответствовать (немного смутно) установке a ко лжи, в то время как последний будет соответствовать установке a к истинному. Это вызвано тем, что наш гаджет пункта действительно легок затем, потому что мы просто записываем пункт, например, (снова _
вот является новая переменная каждым разом):
0 _ 0
a1 b1 b2
или
0 _ 0
¬a1 ¬b1 ¬b2
Наконец, так как Вы только использовали один из a1 и ¬a1, и т.д., мы позволяем Вам взять тех, Вы не использовали свободно:
0 _ 0
a1 ¬a1 0
Теперь, это не вполне работает, потому что один из a1 и ¬a1, возможно, использовался в переменном гаджете выбора, в то время как другой, возможно, использовался в пункте. Так, мы включаем новую переменную @i
для каждого пункта, который можно взять вместо одной из переменных. Таким образом, если переменная a1 появляется в пункте 1, мы имеем
0 _ 0
a1 ¬a1 @1
Вот полный вывод перевода исходного 3SAT пункта (выделяющий соответствие пути установке a и b к истинному, c ко лжи и выбору из первого пункта), с числами слева и блеском справа. Гаджеты переупорядочиваются (первые гаджеты пункта, затем для каждой переменной, гаджета равенства и затем неиспользованного гаджета), но это не имеет значения, так как они независимы так или иначе.
0 0 < 0 . . < .
0 8 < 0 . _ < .
2 < 4 6 a1 < b1 c1
0 16 < 0 . _ .
11 13 15 < -a2 -b2 -c2<
0 17 < 0 . _ < .
2 0 3 < a1 . -a1<
10 0 11 < a2 . -a2<
0 18 < 0 . _ < .
2 3 1 < a1 -a1 @1 <
0 19 < 0 . _ .
10 < 11 9 a2 < -a2 @2
0 20 < 0 . _ < .
4 0 5 < b1 . -b1<
12 0 13 < b2 . -b2<
0 21 < 0 . _ < .
4 < 5 1 b1 < -b1 @1
0 22 < 0 . _ < .
12 < 13 9 b2 < -b2 @2
0 23 < 0 . _ < .
6 < 0 7 c1 < . -c1
14 < 0 15 c2 < . -c2
0 24 < 0 . _ < .
6 7 < 1 c1 -c1< @1
0 25 < 0 . _ < .
14 15 9 < c2 -c2 @2 <
(Если Вы хотите, чтобы все это было квадратным, просто включайте набор нулей в конце каждой строки.) Интересно видеть, неважно, как Вы решаете это, в глубине души, решение этого 3SAT проблема.
В конце моего сообщения торопливо записанная программа Perl, которая генерирует одну из Ваших проблем от входа формы
a b c
-a -b -c
Количество переменных в результирующем экземпляре Вашей проблемы 11C + V + 1
. Дайте программу -r
переключитесь для создания блеска вместо чисел.
# Set useful output defaults
$, = "\t"; $\ = "\n";
# Process readability option and force sentinel
my $r = "0";
if( $ARGV[0] =~ /-r/ ) { shift; $r = "."; }
print $r, $r, $r;
# Clause gadgets
my( %v, %c, $m, $c );
$m = 1;
while( <> ) {
my( @v, @m );
$c = $m++;
chomp; @v = split;
for my $v ( @v ) {
push @{$v{strip($v)}}, -1; # hack, argh!
push @m, ($r ? $v.@{$v{strip($v)}} : $m + neg($v));
$c{($r ? (strip($v).@{$v{strip($v)}}) : $m)} = $c;
$v{strip($v)}->[-1] = ($r ? (strip($v).@{$v{strip($v)}}) : $m);
$m += 2 unless $r;
}
print $r, newv(), $r;
print @m;
}
# Variable gadget
for my $v ( sort keys %v ) {
# Force equal
print $r, newv(), $r;
for my $n ( @{$v{$v}} ) {
print $n, $r, ($r ? "-".$n : $n+1);
}
# Unused
for my $n ( @{$v{$v}} ) {
print $r, newv(), $r;
print $n, ($r ? "-".$n : $n+1), ($r ? "\@".$c{$n} : $c{$n});
}
}
# Strip leading -
sub strip {
my( $v ) = @_;
return substr $v, neg($v);
}
# Is this variable negative?
sub neg {
my( $v ) = @_;
return "-" eq substr( $v, 0, 1 );
}
# New, unused variable
sub newv {
return "_" if $r;
return $m++;
}
Можно попробовать оптимизацию колонии муравьев. Это быстро приводит к очень хорошим результатам, которые являются очень близко к идеальному решению.
Я вполне уверен, это может быть сделано в полиномиальное время. Я запустил бы с пустое множество и затем цикл через строки, от начала до конца. Я собираюсь пропустить любой вид кода и показать Вам, на что состояние было бы похоже на каждом шаге, необходимо смочь соединить алгоритм оттуда. Я вполне уверен, лучший случай немного хуже, чем O (n^2) использование изменения поиска в ширину и отслеживания текущих хороших путей в таблице.
Править: Если это все еще не достаточно быстро, можно улучшить его путем применения оптимизации Harlequin.
Например:
1 2 3
3 2 1
1 2 1
Состояние 0: R = 0//строка P = {}//Набор Пути
// {{Path so far}, Column}
P' = {
{{1}, 0}
{{2}, 1}
{{3}, 2}
}
P = P'
Состояние 1: R = 1//СТРОКА P = {{{1}, 0} {{2}, 1} {{3}, 2}}
P' = {
{{1 3}, 0}
{{1 2}, 1}
{{2 3}, 0}
{{2 1}, 2}
{{3 2}, 1}
{{3 1}, 2}
}
Состояние 2: R = 2 P = {{ {1 3}, 0} {{1 2}, 1} {{2 3}, 0} {{2 1}, 2} {{3 2}, 1} {{3 1}, 2 }}
P' = {
{{1 3 2}, 1}
{{2 3 1}, 0}
{{3 2 1}, 0}
{{3 2 1}, 2}
{{3 1 2}, 1}
}
Результат:
Количество пути: 5
S1 1 3 2 F2
S2 2 3 1 F1
S3 3 2 1 F1
S3 3 2 1 F3
S3 3 1 2 F2
Одна оптимизация для решения Kevin Loney могла бы быть должна объединить частичные пути, которые содержат те же элементы в том же столбце. Необходимо было бы отметить количество слияний с путем, если Вы хотите знать количество решений в конце.
Пример: В Вашем 5x5 пример, когда Вы прибываете в третью строку, третий столбец, имеет три продвижения путей к нему, которые содержат (1 2 5) в некотором порядке. Вы не должны следовать за ними отдельно от этой точки, но можете объединить их. Если Вы хотите знать количество решений в конце, просто необходимо скорректировать структуру данных пути, например, три (1 (1 2 5)) объединился бы с (3 (1 2 5)).