potassco / clingo

🤔 A grounder and solver for logic programs.
https://potassco.org/clingo
MIT License
599 stars 79 forks source link

Can I optimize and groupby? #411

Closed light-and-salt closed 1 year ago

light-and-salt commented 1 year ago

Question: Is there a way to express "for each (valid) node X, find the shortest path from the root to X?"

Attempt: This is what I have so far:

% run with --opt-mode=OptN

% priority 2: maximize node diversity
#maximize { 100 @2, X : valid_node(X) }.

% priority 1: minimize the sum of edge cost
#minimize { 3 @1, X, I : valid_node(X), edge_cost(I) }.

When I only include #maximize { 100 @2, X : valid_node(X) }., I get thousands of solutions, each containing one valid_node(X).

When I include both #maximize and #minimize, I get 2 optimum solutions -- the two shortest paths among all the paths leading to all valid X. All the other solutions, even though they contain valid X, were considered non-optimal because their paths are longer. This is not what I want... I want to find all valid X, and find the shortest path for each X. Wondering how I could achieve this...

rkaminsk commented 1 year ago

I would not know how to map this to optimization constraints. It sounds possible in two steps though. You can probably enumerate valid nodes. And for each valid node compute a shortest path (if there is one path to a node then there is also a shortest one). You might also want to have a look at asprin. Maybe it allows you to write this nicely. Otherwise, this sounds like a problem that could be formulated using a disjunctive program. But such an approach is both cumbersome to implement and does not scale well.

light-and-salt commented 1 year ago

Thank you so much @rkaminsk! That answers my question