Неэкспоненциальное решение проблемы с лабиринтом?

Проблема в том, что вы сравниваете тензор с формой [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]]})) 

14
задан Mike Douglas 11 February 2009 в 08:38
поделиться

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++;
}
11
ответ дан 1 December 2019 в 13:10
поделиться

Можно попробовать оптимизацию колонии муравьев. Это быстро приводит к очень хорошим результатам, которые являются очень близко к идеальному решению.

3
ответ дан 1 December 2019 в 13:10
поделиться

Я вполне уверен, это может быть сделано в полиномиальное время. Я запустил бы с пустое множество и затем цикл через строки, от начала до конца. Я собираюсь пропустить любой вид кода и показать Вам, на что состояние было бы похоже на каждом шаге, необходимо смочь соединить алгоритм оттуда. Я вполне уверен, лучший случай немного хуже, чем 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

5
ответ дан 1 December 2019 в 13:10
поделиться

Одна оптимизация для решения Kevin Loney могла бы быть должна объединить частичные пути, которые содержат те же элементы в том же столбце. Необходимо было бы отметить количество слияний с путем, если Вы хотите знать количество решений в конце.

Пример: В Вашем 5x5 пример, когда Вы прибываете в третью строку, третий столбец, имеет три продвижения путей к нему, которые содержат (1 2 5) в некотором порядке. Вы не должны следовать за ними отдельно от этой точки, но можете объединить их. Если Вы хотите знать количество решений в конце, просто необходимо скорректировать структуру данных пути, например, три (1 (1 2 5)) объединился бы с (3 (1 2 5)).

1
ответ дан 1 December 2019 в 13:10
поделиться

Ищите* поиск. Это - Ваш друг.

0
ответ дан 1 December 2019 в 13:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: