Рассчитать сумму суммы в Clingo
Я пытаюсь решить следующую проблему:
Данный
k
нейроны n1,...,nk связаны предикатом
arc
дано на входе. Первый
h
нейроны являются входными и не имеют входящих дуг, они имеют логическое значение. Каждая дуга
(i,j)
имеют вес w(i,j) , которые имеют значение
[-2, ..., +2]
.
Выход узла (не входной) получается, как всегда, суммой по всем входящим дугам веса дуги, умноженной на выходное значение нейрона на другом конце дуги.
Определить веса сети, которые максимизируют сумму абсолютных значений разницы между весами n k-1 и n k для всех заданных конфигураций во входных данных. Рассматривайте только ациклические графы.
Подготовьте батарею эталонных экземпляров следующим образом. Для каждого
k = 10, 15, 20, 25, 30
а также
h~k/3
: генерировать случайным образом 20 разных экземпляров (дуга). Всего 100 экземпляров
Часть, в которой говорится, что входные узлы имеют логические значения, означает, что для каждой конфигурации у нас есть другой набор входных узлов, например, у нас есть:
Это означает, что в первой конфигурации входные узлы ложны (т.е. не учитываются), во второй истинны только первые и т.д...
Я нахожусь в точке, где я не знаю, куда идти. Я нашел решение, которое хорошо работает для
k = 5
а также
h = 2
но в тот момент, когда я пытаюсь
k = 10
а также
h = 3
заземление занимает много времени . Поэтому я подозреваю, что делаю что-то не так с суммой, чтобы вычислить вес каждого выходного узла.
Вот код, с которым я работаю:
#const n = 5. % nodes
#const h = 2. % input nodes h~k/3
#const n_config = 2**h.
node(1..n).
weight(-2;-1;0;1;2).
% arc predicate
arc(1,3). arc(2,3). arc(3,4;3,5).
% arcs for k = 10
% arc(1,4;1,5;1,8). arc(2,4;2,5;2,8;2,10). arc(3,4;3,5;3,7;3,9). arc(4,5). arc(5,8;5,10). arc(6,8;6,9;6,10). arc(7,9;7,10). arc(8,9;8,10).
% Configurations
config(1..2**h).
% differentiate between input and output nodes
node_out(X) :- node(X), X>h.
node_in(X) :- node(X), X<=h.
% The input node don't have any input edge
:- node_in(X), node(Y), arc(Y,X).
% Assign one weight to each arc using a choice rule
1 {weight_arc(X,Y,W) : weight(W)}1 :- arc(X, Y).
% input layer
{weight_node(C,X,1) : node_in(X)}:- config(C).
% output nodes
weight_node(C,X, 1) :- node_out(X), config(C).
%%% Now we eliminate all the configurations we do not want to also speed up the aggregate sum
% the number of 1 need to be the half af all number of 0s and 1s
:- #count{C,V:weight_node(C,X,V)}!=(2**h)/2, node_in(X).
% At least one config has all at 1 or 0
:- #count{C:weight_node(C,X,V), node_in(X)}!=(2**h)-1.
% First config always at 0
:- #count{C:weight_node(C,X,V), node_in(X), C=1} != 0.
% Last config always at 1
:- #count{X:weight_node(C,X,V), node_in(X), C=2**h} < h.
% The other are always different from 0 and 1
:- #count{X:weight_node(C,X,V), node_in(X)}=0, config(C), C!=1, C!=h**2.
% give an order to the succession of input nodes
:- T1=#count{X1:weight_node(C1,X1,V), node_in(X1)},
T2=#count{X2:weight_node(C2,X2,V), node_in(X2)},
config(C1), config(C2), C1<C2, T1=T2,
MaxC1 = #max{X1:weight_node(C1,X1,V), node_in(X1)},
MaxC2 = #max{X2:weight_node(C2,X2,V), node_in(X2)},
MaxC1>MaxC2.
:- T1=#count{X1:weight_node(C1,X1,V), node_in(X1)}, T2=#count{X2:weight_node(C2,X2,V), node_in(X2)}, config(C1), config(C2), C1<C2, T1>T2.
weight_nodexarc(C,X,Y,S*Wa) :- weight_node(C, X, S), weight_arc(X,Y,Wa), node_in(X).
weight_nodexarc(C,X,Y,S*Wa) :- out_weight_node(C, X, S), weight_arc(X,Y,Wa), node_out(X).
out_weight_node(C, Y, Wn) :- Wn=#sum{W,X: weight_nodexarc(C,X,Y,W)}, node_out(Y), config(C), C>1.
out_weight_node(C, Y, Wn) :- Wn=0, node_out(Y), config(C), C=1.
result_config(C,|R|) :- out_weight_node(C,n,O1), out_weight_node(C,n-1,O2), R=O1-O2, config(C),C>1.
% the first configuration is always at 0 because it doeas not have any input nodes
result_config(1,0).
% It has sense only of the first config is at 0
:- result_config(C,R), C!=1, R=0.
:- result_config(C1,R1), result_config(C2,R2), C1<C2, R1>R2.
%result(T) :- T = #sum{R,C:result_config(C,R), config(C)}.
#maximize {R,C:result_config(C,R)}.