不断变好!在我们提供的这个答案list_long_nondecreasing_subseq__NEW/2
中,替换了之前的答案list_long_nondecreasing_subseq/2
中的-presented 。
让我们切入正题并定义list_long_nondecreasing_subseq__NEW/2
!
:- 使用模块([库(clpfd),库(列表),库(随机),库(之间)])。
list_long_nondecreasing_subseq __NEW (Zs, Xs) :-
最小值(最小值,Zs),
附加(前缀,后缀,Zs),
相同长度(后缀,Xs),
zs_skipped_subseq_taken0 ( Zs, Prefix, Xs, Min)。
zs_skipped_subseq_taken0 ( [], _, [], _)。
zs_skipped_subseq_taken0 ( [E|Es], Ps, [E|Xs], E0) :-
E0 #=< E,
zs_skipped_subseq_taken0 ( Es, Ps , Xs, E)。
zs_skipped_subseq_taken0 ( [E|Es], [_|Ps] , Xs, E0) :-
zs_skipped_subseq_taken0_min0_max0 ( Es, Ps , Xs, E0, E, E)。
zs_skipped_subseq_taken0_min0_max0 ( [], _, [], E0, _, Max) :-
最大 #< E0。
zs_skipped_subseq_taken0_min0_max0 ( [E|Es], Ps , [E|Xs], E0, Min, Max) :-
E0 #=< E,
E0 #> 最小 #\/ 最小 #> E,
E0 #> 最大 #\/ 最大 #> E,
zs_skipped_subseq_taken0 ( Es, Ps, Xs, E)。
zs_skipped_subseq_taken0_min0_max0 ( [E|Es], [_|Ps], Xs, E0, Min0, Max0) :-
最小值#= min(Min0,E),
最大值 #= 最大值 (Max0,E),
zs_skipped_subseq_taken0_min0_max0 ( Es, Ps, Xs, E0, Min, Max)。
所以......它仍然像以前一样工作吗?让我们运行一些测试并比较答案序列:
| ?- setrand(随机(29251,13760,3736,425005073)),
在(7, 23, N) 之间,
nl,
写(n = N),
写(' '),
长度(Zs,N),
在(1, 10, _) 之间,
地图列表(随机(1,N),Zs),
findall(Xs1, list_long_nondecreeasing_subseq(Zs,Xs1), Xss1),
findall(Xs2, list_long_nondecreasing_subseq__NEW(Zs,Xs2), Xss2),
( Xss1 == Xss2 -> true ; throw(up) ),
长度(Xss2,L),
写({L}),
错误的。
n=7 {3}{8}{3}{7}{2}{5}{4}{4}{8}{4}
n=8 {9}{9}{9}{8}{4}{4}{7}{5}{6}{9}
n=9 {9}{8}{5}{7}{10}{7}{9}{4}{5}{4}
n=10 {7}{12}{7}{14}{13}{19}{13}{17}{10}{7}
n=11 {14}{17}{7}{9}{17}{21}{14}{10}{10}{21}
n=12 {25}{18}{20}{10}{32}{35}{7}{30}{15}{11}
n=13 {37}{19}{18}{22}{20}{14}{10}{11}{8}{14}
n=14 {27}{9}{18}{10}{20}{29}{69}{28}{10}{33}
n=15 {17}{24}{13}{26}{32}{14}{22}{28}{32}{41}
n=16 {41}{55}{35}{73}{44}{22}{46}{47}{26}{23}
n=17 {54}{43}{38}{110}{50}{33}{48}{64}{33}{56}
n=18 {172}{29}{79}{36}{32}{99}{55}{48}{83}{37}
n=19 {225}{83}{119}{61}{27}{67}{48}{65}{90}{96}
n=20 {58}{121}{206}{169}{111}{66}{233}{57}{110}{146}
n=21 {44}{108}{89}{99}{149}{148}{92}{76}{53}{47}
n=22 {107}{137}{221}{79}{172}{156}{184}{78}{162}{112}
n=23 {163}{62}{76}{192}{133}{372}{101}{290}{84}{378}
不
所有答案序列完全相同!... 那么,运行时呢?
让我们使用 SICStus Prolog 4.3.2 运行更多查询并漂亮地打印答案!
?- 成员(N,[15,20,25,30,35,40,45,50]),
长度(Zs,N),
_NN #= N*N,
地图列表(随机(1,_NN),Zs),
call_time(once(list_long_nondecreasing_subseq(Zs, Xs)), T1),
call_time(once(list_long_nondecreasing_subseq__NEW(Zs,_Xs2)), T2),
Xs == _Xs2,
长度(Xs,L)。
N = 15,L = 4,T1 = 20,T2 = 0,Zs = [224,150,161,104,134,43,9,111,76,125,50,68,202,178,148],Xs = [104,111,125,202];
N = 20,L = 6,T1 = 60,T2 = 10,Zs = [71,203,332,366,350,19,241,88,370,100,288,199,235,343,181,90,63,149,215,285],Xs = [71,88,100,199,235];
N = 25, L = 7, T1 = 210, T2 = 20, Zs = [62,411,250,222,141,292,276,94,548,322,13,317,68,488,137,33,80,167,101,475,475,429,217,25,477], Xs = [62,250,292,322,475,475,477] ;
N = 30, L = 10, T1 = 870, T2 = 30, Zs = [67,175,818,741,669,312,99,23,478,696,63,793,280,364,677,254,530,216,291,660,218,664,476,556,678,626,75,834,578,850], Xs = [67,175,312,478,530,660,664,678,834,850] ;
N = 35, L = 7, T1 = 960, T2 = 120, Zs = [675,763,1141,1070,299,650,1061,1184,512,905,139,719,844,8,1186,1006,400,690,29,791,308,1180,819,331,482,982,81,574,1220 ,431,416,357,1139,636,591],Xs = [299,650,719,844,1006,1180,1220];
N = 40, L = 9, T1 = 5400, T2 = 470, Zs = [958,1047,132,1381,22,991,701,1548,470,1281,358,32,605,1270,692,1020,350,794,1451,11,985 ,1196,504,1367,618,1064,961,463,736,907,1103,719,1385,1026,935,489,1053,380,637,51],Xs = [132,470,605,692,794,985,1196,1367,135];
N = 45, L = 10, T1 = 16570, T2 = 1580, Zs = [1452,171,442,1751,160,1046,470,450,1245,971,1574,901,1613,1214,1849,1805,341,34 ,1923,698,156,1696,717,1708,1814,1548,463,421,1584,190,1195,1563,1772,1639,712,693,1848,1531,250,783,1654,1732,1333,717,1322, [171,442,1046,1245,1574,1613,1696,1708,1814,1848];
N = 50, L = 11, T1 = 17800, T2 = 1360, Zs = [2478,2011,2411,1127,1719,1286,1081,2042,1166,86,355,894,190,7,1973,1912,753,1411,1082 ,70,2142,417,1609,1649,2329,2477,1324,37,1781,1897,2415,1018,183,2422,1619,1446,1461,271,56,2399,1681,267,977,826,2145,2318 ,2391,137,55,1995],Xs = [86,355,894,1411,1609,1649,1781,1897,2145,2318,2391];
错误的。
当然,这个答案中显示的巴洛克式方法根本无法与确定lis的“严肃”合适的算法竞争——不过,获得 10 倍的加速总是感觉很好:)