Commit 0256135d authored by Joshua Schmidt's avatar Joshua Schmidt
Browse files

k-dominating set with co-routines and clpfd

parent 17725a5f
/* -*- Mode:Prolog; coding:iso-8859-1; indent-tabs-mode:nil; prolog-indent-width:8; prolog-paren-indent:4; tab-width:8; -*- */
:- use_module(library(lists)).
:- use_module(library(plunit)).
k_dominating_set(Graph, DominatingSet) :-
:- use_module(library(clpfd)).
:- use_module(library(mutdict)).
create_node_bit_dictionary([], [], _).
create_node_bit_dictionary([Node|NT], [Bit|BT], NodeBitDict) :-
mutdict_put(NodeBitDict, Node, Bit),
create_node_bit_dictionary(NT, BT, NodeBitDict).
k_dominating_set(Nodes, Graph, DominatingSetNodes) :-
length(Nodes, L),
length(DominatingSet, L),
domain(DominatingSet, 0, 1),
new_mutdict(NodeBitDict),
create_node_bit_dictionary(Nodes, DominatingSet, NodeBitDict),
setup_coroutines(Nodes, DominatingSet, NodeBitDict, Graph),
K in 1..L,
sum(DominatingSet, #=, K),
labeling([minimize(K)],[K|DominatingSet]),
get_dominating_set_from_dict(NodeBitDict, DominatingSetNodes),
!.
get_dominating_set_from_dict(NodeBitDict, DominatingSetNodes) :-
mutdict_items(NodeBitDict, Items),
get_dominating_set_from_dict_acc(Items, [], DominatingSetNodes).
get_dominating_set_from_dict_acc([], Acc, Acc).
get_dominating_set_from_dict_acc([Node-Bit|T], Acc, DominatingSetNodes) :-
( Bit == 0
-> get_dominating_set_from_dict_acc(T, Acc, DominatingSetNodes)
; get_dominating_set_from_dict_acc(T, [Node|Acc], DominatingSetNodes)
).
setup_coroutines([], [], _, _).
setup_coroutines([Node|TN], [Bit|TB], NodeBitDict, Graph) :-
node_is_in_dominating_bit_set(Node, Bit, NodeBitDict, Graph),
setup_coroutines(TN, TB, NodeBitDict, Graph).
:- block node_is_in_dominating_bit_set(?, -, ?, ?).
node_is_in_dominating_bit_set(_, Bit, _, _) :-
Bit == 1.
node_is_in_dominating_bit_set(Node, Bit, NodeBitDict, Graph) :-
Bit == 0,
node_is_not_in_dominating_set(Node, NodeBitDict, Graph).
node_is_not_in_dominating_set(Node, NodeBitDict, Graph) :-
findall(Adj, (member(Edge, Graph), (Edge = [Node,Adj]; Edge = [Adj,Node])), AdjacentNodes),
one_adjacent_in_dominating_set(AdjacentNodes, NodeBitDict).
one_adjacent_in_dominating_set([Node|T], NodeBitDict) :-
mutdict_get(NodeBitDict, Node, Bit),
( Bit = 1
; Bit = 0,
one_adjacent_in_dominating_set(T, NodeBitDict)
).
/*k_dominating_set(Graph, DominatingSet) :-
findall(DSet, k_dominating_set(Graph, [], DSet, Graph), DominatingSets),
minimum_length(DominatingSets, DominatingSet).
......@@ -77,43 +131,21 @@ equal([],[]) :- !.
equal([H1|T1], [H2|T2]) :-
H1 #= H2,
equal(T1, T2).
*/
:- begin_tests(k_dominating_set).
test(graph1, [true]) :-
k_dominating_set([[1,2],[2,3]], [2]).
test(graph1, [true(D == [2])]) :-
k_dominating_set([1,2,3], [[1,2],[2,3]], D).
test(graph2, [true]) :-
k_dominating_set([[1,2],[2,3],[3,4],[2,5],[5,6],[2,7],[7,8],[8,9],[9,10],[10,8]], [8,5,3,2]).
test(graph2, [true(D == [2,4,6,10])]) :-
k_dominating_set([1,2,3,4,5,6,7,8,9,10], [[1,2],[2,3],[3,4],[2,5],[5,6],[2,7],[7,8],[8,9],[9,10],[10,8]], D).
test(graph3, [true]) :-
k_dominating_set([[1,2],[3,3]],[3,1]).
test(graph3, [true(D == [2,3])]) :-
k_dominating_set([1,2,3], [[1,2],[3,3]], D).
test(graph4, [true]) :-
k_dominating_set([[1,2],[1,3],[1,4],[1,5],[5,6],[5,7],[5,8]], [5,1]).
test(graph4_fail, [fail]) :-
k_dominating_set([[1,2],[1,3],[1,4],[1,5],[5,6],[5,7],[5,8]], [5,2]).
test(graph4, [true(D == [1,5])]) :-
k_dominating_set([1,2,3,4,5,6,7,8], [[1,2],[1,3],[1,4],[1,5],[5,6],[5,7],[5,8]], D).
:- end_tests(k_dominating_set).
:- begin_tests(k_dominating_set_with_clpfd).
test(graph1, [nondet, true]) :-
k_dominating_set_with_clpfd([[1,2],[2,3]], [2]).
test(graph2, [nondet, true]) :-
k_dominating_set_with_clpfd([[1,2],[2,3],[3,4],[2,5],[5,6],[2,7],[7,8],[8,9],[9,10],[10,8]], [8,5,3,2]).
test(graph3, [nondet, true]) :-
k_dominating_set_with_clpfd([[1,2],[3,3]],[3,1]).
test(graph4, [nondet, true]) :-
k_dominating_set_with_clpfd([[1,2],[1,3],[1,4],[1,5],[5,6],[5,7],[5,8]], [5,1]).
test(graph4_fail, [fail]) :-
k_dominating_set_with_clpfd([[1,2],[1,3],[1,4],[1,5],[5,6],[5,7],[5,8]], [5,2]).
:- end_tests(k_dominating_set_with_clpfd).
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment