Skip to content

Commit

Permalink
Fix solve_in_exp_time_with_correctness/1 output result to satisfy all
Browse files Browse the repository at this point in the history
  • Loading branch information
ajfAfg committed Jan 3, 2024
1 parent b857a78 commit 4252721
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 17 deletions.
51 changes: 38 additions & 13 deletions src/core/all_local_minimum_vertex_splitters_solver.erl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
-type take_all_local_minimum_vertex_splitters() ::
fun((dependency_digraph:t()) -> [[dependency_digraph:vertex()]]).

%% ===================================================================
%% Public API
%% ===================================================================
% NOTE:
% The argument graph is assumed to be a connected DAG.
% To reduce computation time, do not check whether `ConnectedDAG` is a connected DAG.
Expand Down Expand Up @@ -39,31 +42,38 @@ solve_in_exp_time_with_correctness(ConnectedDAG) ->
digraph:vertices(ConnectedDAG)),
dependency_digraph:is_vertex_splitter(ConnectedDAG, Vertices)],
Candidates2 =
lists:usort(
maps:values(
begin
MinimumVertexSplittersForEveryExitVertex =
lists:foldl(fun(VertexSplitter, Acc) ->
lists:foldl(fun(ExitVertex, Acc2) ->
maps:update_with(ExitVertex,
fun(VertexSplitter2) ->
case length(VertexSplitter)
< length(VertexSplitter2)
fun(VertexSplitters) ->
case
compare(length(VertexSplitter),
length(hd(VertexSplitters)))
of
true -> VertexSplitter;
false -> VertexSplitter2
less -> [VertexSplitter];
greater -> VertexSplitters;
equal ->
[VertexSplitter
| VertexSplitters]
end
end,
Acc2)
end,
Acc,
[V
|| V <- VertexSplitter,
digraph:out_degree(ConnectedDAG, V) =:= 0])
is_exit_vertex(ConnectedDAG, V)])
end,
maps:from_keys([V
|| V <- digraph:vertices(ConnectedDAG),
digraph:out_degree(ConnectedDAG, V) =:= 0],
digraph:vertices(ConnectedDAG)),
Candidates))),
maps:from_keys(exit_vertices(ConnectedDAG),
[digraph:vertices(ConnectedDAG)]),
Candidates),
lists:usort(
lists:map(fun lists:sort/1,
my_lists:flatten(
maps:values(MinimumVertexSplittersForEveryExitVertex))))
end,
[S1
|| S1 <- Candidates2,
not
Expand All @@ -72,3 +82,18 @@ solve_in_exp_time_with_correctness(ConnectedDAG) ->
sets:from_list(S2), sets:from_list(S1))
end,
lists:delete(S1, Candidates2))].

%% ===================================================================
%% Private API
%% ===================================================================
-spec compare(term(), term()) -> less | greater | equal.
compare(X, Y) when X < Y -> less;
compare(X, Y) when X > Y -> greater;
compare(_, _) -> equal.

-spec exit_vertices(digraph:graph()) -> [digraph:vertex()].
exit_vertices(Digraph) ->
[V || V <- digraph:vertices(Digraph), is_exit_vertex(Digraph, V)].

-spec is_exit_vertex(digraph:graph(), digraph:vertex()) -> boolean().
is_exit_vertex(Digraph, Vertex) -> digraph:out_degree(Digraph, Vertex) =:= 0.
66 changes: 62 additions & 4 deletions test/all_local_minimum_vertex_splitters_solver_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ solve_in_polynomial_time_without_correctness_test_() ->

solve_in_exp_time_with_correctness_test_() ->
{inparallel,
[{"Critical test cases",
[{"Satisfy all",
fun() ->
G1 = my_digraph:create(
lists:seq(1, 6), [{1, 3}, {1, 4}, {2, 4}, {2, 5}, {3, 6}, {4, 6}, {5, 6}]),
Expand All @@ -51,10 +51,68 @@ solve_in_exp_time_with_correctness_test_() ->
lists:map(fun lists:sort/1,
all_local_minimum_vertex_splitters_solver:solve_in_exp_time_with_correctness(G2)))),
G3 = my_digraph:create(
lists:seq(1, 3), [{1, 2}, {2, 3}]),
lists:seq(1, 12),
[{1, 4},
{1, 6},
{2, 1},
{2, 6},
{3, 1},
{5, 1},
{6, 7},
{8, 6},
{8, 10},
{9, 8},
{11, 10},
{12, 9}]),
?assertEqual(lists:sort(
lists:map(fun lists:sort/1, [[1, 2, 3]])),
lists:map(fun lists:sort/1, [[6, 7], [10]])),
lists:sort(
lists:map(fun lists:sort/1,
all_local_minimum_vertex_splitters_solver:solve_in_exp_time_with_correctness(G3)))),
G4 = my_digraph:create(
lists:seq(1, 18),
[{1, 2},
{2, 3},
{2, 4},
{4, 5},
{5, 6},
{7, 3},
{8, 9},
{9, 6},
{10, 1},
{10, 11},
{10, 12},
{13, 14},
{14, 12},
{14, 15},
{15, 11},
{15, 16},
{15, 17},
{18, 17}]),
?assertEqual(lists:sort(
lists:map(fun lists:sort/1, [[3], [6], [11, 12], [17]])),
lists:sort(
lists:map(fun lists:sort/1,
all_local_minimum_vertex_splitters_solver:solve_in_exp_time_with_correctness(G4)))),
G5 = my_digraph:create(
lists:seq(1, 14),
[{1, 2},
{1, 5},
{1, 7},
{2, 3},
{4, 2},
{6, 5},
{7, 8},
{9, 10},
{10, 11},
{10, 12},
{12, 13},
{13, 8},
{13, 14},
{14, 8}]),
?assertEqual(lists:sort(
lists:map(fun lists:sort/1, [[2, 3], [5], [8]])),
lists:sort(
lists:map(fun lists:sort/1,
all_local_minimum_vertex_splitters_solver:solve_in_exp_time_with_correctness(G3))))
all_local_minimum_vertex_splitters_solver:solve_in_exp_time_with_correctness(G5))))
end}]}.

0 comments on commit 4252721

Please sign in to comment.