查找包含从1到K的所有数字的子列表的最小长度

时间:2019-05-15 17:54:23

标签: prolog

问题是“查找具有从1到K的所有数字的列表的最小长度”。 输入: 列表,K,N 其中N是列表的长度


我的算法(显然有点面向C):

  1. 设置最小值= N + 1
  2. 找到具有从1到K的所有数字的第一个subList(FSub)
  3. 如果没有一个,则Min = 0并完成
  4. 如果存在创建列表C,该列表C具有除第一个length(FSub)元素之外的所有初始列表元素。

找到MIN的功能(参数:FSub,C,NewList,Min)

  1. 如果length(Fsub)= K,则因为找到了子列表的最小长度,所以我们不必继续搜索
  2. 如果FSub的头位于Fsub的尾巴中,则我们从FSub中删除Head,更新min并递归,
  3. 如果不是,则将F附加到列表C的头(上面创建)并递归。

如果C等于空列表,则此操作停止

此算法似乎很耗时,在某些情况下,大列表可能会耗尽堆栈。


asked关于第一个子列表部分,并获得了此代码。

findFirstSubListHavingAllColors( NumList, List ,SubList, Len):-
    once((
         append(SubList, _, List),        % get SubList
         subtract(NumList, SubList, []),  % test whether NumList is contained in SubList
         length(SubList, Len)
  )).

我无法找到答案。


示例

列表= [1,3,1,3,1,3,3,2,2,1],K = 3,N = 10

答案应为4,因为包含数字1,2,3的最小子列表为[1,3,3,2]或[3,2,2,1]。

2 个答案:

答案 0 :(得分:0)

我认为这可行:

sublist(NumList, In, Out):-
    append([_, Out, _], In),
    forall(member(X, NumList), member(X, Out)).

minSubList(NumList, In, Out) :-
    aggregate_all(min(Len, Out1),(sublist(NumList, In, Out1), length(Out1, Len)), Out).

例如:

?- minSubList([1,2,3], [1,3,1,3,1,3,3,2,2,1], Out).
Out = min(4, [1, 3, 3, 2]).

注意:我没有尝试过很大的列表。

答案 1 :(得分:0)

这是另一种解决方案,用于测试长度增加(从K到len(L))的子列表:

min_len(L, K, M):-
  length(L, N),
  numlist(1, K, LK),
  once((
    between(K, N, M),
    length(SubL, M),
    append([_, SubL, _], L),
    subset(LK, SubL)
  )).

测试案例:

?- min_len([1,3,1,3,1,3,3,2,2,1], 3, Min).
Min = 4