There is an undirected graph (V,E), weights on the edges w : E → N, a target k ∈ N, and a threshold O ∈ N. Find a k-vertices tree of the graph of weight less than the threshold. In other words, select k vertices and k - 1 edges from V and E respectively such that they constitute a tree, and the sum of the weights of the selected edges are less than O.
Write an ASP program that takes V , E, w, k, and O as input, and finds a selection of edges satisfying the constraints, or outputs ‘unsatisfiable’ if the constraints cannot be satisfied. Selecting the edges implicitly induces a selection of the vertices, so there is no need for the selected vertices to be explicitly displayed.
An instance to this problem is provided through predicates vertex/1, weight/3, target/1, and threshold/1. All edges have weights, so statements of the form weight(a, b, 10). can be used to declare the existence of an edge between vertices a and b at the same time as declaring their weight, and there is no need for any redundant edge/2 predicate.
I tried the following:
% instance
vertex ( v1 ). vertex ( v2 ). vertex ( v3 ).
vertex ( v4 ). vertex ( v5 ). vertex ( v6 ).
vertex ( v7 ). vertex ( v8 ). vertex ( v9 ).
weight ( v1 , v2 ,3). weight ( v1 , v3 ,3).
weight ( v2 , v4 ,1). weight ( v2 , v5 ,5).
weight ( v3 , v4 ,3). weight ( v3 , v6 ,4).
weight ( v4 , v5 ,4). weight ( v4 , v7 ,1).
weight ( v5 , v7 ,7).
weight ( v6 , v7 ,2). weight ( v6 , v8 ,2).
weight ( v7 , v9 ,3).
weight ( v8 , v9 ,2).
target (4).
threshold (4).
% encoding
(P-1) {select(X, Y) : weight(X, Y, Z)} (Q-1) :- target(P), target(Q).
sum(S) :- S = #sum {W,X,Y : select(X,Y), weight(X,Y,W); W,X,Z : select(X,Z), weight(X,Z,W) }.
:- sum(S),threshold(M), S > M.
:- select(A,B), select(C,D), A == C ; A == D ; B == C ; B == D.
#show select/2.
And I get the following output:
clingo version 5.5.0
Reading from stdin
Solving...
Answer: 1
select(v2,v4) select(v4,v7) select(v6,v7)
Answer: 2
select(v2,v4) select(v4,v7) select(v6,v8)
Answer: 3
select(v2,v4) select(v4,v7) select(v8,v9)
SATISFIABLE
Models : 3
Calls : 1
Time : 0.013s (Solving: 0.00s 1st Model: 0.00s Unsat: 0.00s)
CPU Time : 0.000s
I was expecting just
select(v2,v4) select(v4,v7) select(v6,v7)
because the others clearly are not tress.
I think this is because of the problematic line:
:- select(A,B), select(C,D), A == C ; A == D ; B == C ; B == D.
How do I correct this?