球员人数有限,网球场数量也有限。在每个回合中,最多只能有场比赛。没有人不间断地进行两轮比赛。每个人都与其他人比赛。产生需要尽可能少的回合的时间表。(由于每个人的回合之间都必须休息的规则,因此可能会有不比赛的回合。)5个球员和2个球场的输出可能是:
| 1 2 3 4 5
-|-------------------
2| 1 -
3| 5 3 -
4| 7 9 1 -
5| 3 7 9 5 -
在此输出中,列和行是玩家编号,矩阵内的数字是这两个玩家竞争的轮数。
问题是找到一种算法,可以在可行的时间内对较大的实例执行此操作。我们要求在Prolog中执行此操作,但是任何语言的(伪)代码都将很有用。
我的第一个尝试是贪婪算法,但结果却带来了太多回合。然后,我提出了一个迭代的加深深度优先搜索,我的一个朋友实施了该搜索,但是在小到7个玩家的实例上仍然花费了太多时间。
(这是来自一个古老的考试问题。我没有与之交谈的人有任何解决方案。)
在Prolog中, CLP(FD)约束 是解决此类计划任务的正确选择。
有关更多信息,请参见 clpfd 。
在这种情况下,我建议使用强大的global_cardinality/2
约束条件来限制每个回合的 发生次数
,具体取决于可用法院的数目。我们可以使用 迭代加深 来找到允许的回合的最小数量。
免费提供的Prolog系统足以令人满意地解决该任务。商业级系统的运行速度将提高数十倍。
:- use_module(library(clpfd)).
tennis(N, Courts, Rows) :-
length(Rows, N),
maplist(same_length(Rows), Rows),
transpose(Rows, Rows),
Rows = [[_|First]|_],
chain(First, #<),
length(_, MaxRounds),
numlist(1, MaxRounds, Rounds),
pairs_keys_values(Pairs, Rounds, Counts),
Counts ins 0..Courts,
foldl(triangle, Rows, Vss, Dss, 0, _),
append(Vss, Vs),
global_cardinality(Vs, Pairs),
maplist(breaks, Dss),
labeling([ff], Vs).
triangle(Row, Vs, Ds, N0, N) :-
length(Prefix, N0),
append(Prefix, [-|Vs], Row),
append(Prefix, Vs, Ds),
N #= N0 + 1.
breaks([]).
breaks([P|Ps]) :- maplist(breaks_(P), Ps), breaks(Ps).
breaks_(P0, P) :- abs(P0-P) #> 1.
查询示例:2个球场上的5名球员:
?- time(tennis(5, 2, Rows)), maplist(writeln, Rows).
% 827,838 inferences, 0.257 CPU in 0.270 seconds (95% CPU, 3223518 Lips)
[-,1,3,5,7]
[1,-,5,7,9]
[3,5,-,9,1]
[5,7,9,-,3]
[7,9,1,3,-]
指定的任务, 在2个球场上有6名球员 ,在1分钟的时间内解决了好问题:
?-time(网球(6,2,行)),
maplist(format(“〜t〜w〜3 +〜t〜w〜3 +〜t〜w〜3 +〜t〜w〜3 +〜t〜w〜3 +〜t〜w〜3 + \ n” ),行)。
%6,675,665推论,在0.977秒内获得0.970 CPU(99%CPU,6884940 Lips)
-1 3 5 7 10
1-6 9 11 3
3 6-11 9 1
5 9 11-2 7
7 11 9 2-5
10 3 1 7 5-
进一步的示例:5个球场上的7名球员:
?-time(网球(7,5,行)),
maplist(format(“(t〜t〜w〜3 +〜t〜w〜3 +〜t〜w〜3 +〜t〜w〜3 +〜t〜w〜3 +〜t〜w〜3 +〜t〜 w〜3 + \ n“),行)。
%125,581,090推论,18.208秒内17.476 CPU(96%CPU,7185927 Lips)
-1 3 5 7 9 11
1-5 3 11 13 9
3 5-9 1 7 13
5 3 9-13 13 7
7 11 1 13-5 3
9 13 7 11 5-1
11 9 13 7 3 1-
使用以下用于兼容性的其他定义, 同一 程序也可以在SICStus Prolog中运行:
:-use_module(library(lists))。
:-use_module(library(between))。
:-op(700,xfx,ins)。
Vs ins D:-maplist(in_(D),Vs)。
in_(D,V):-D中的V。
链([],_)。
链([L | Ls],Pred):-
chain_(Ls,L,Pred)。
chain _([],_,_)。
chain _([L | Ls],Prev,Pred):-
呼叫(Pred,Prev,L),
chain_(Ls,L,Pred)。
pair_keys_values(Ps,Ks,Vs):-keys_and_values(Ps,Ks,Vs)。
foldl(Pred,Ls1,Ls2,Ls3,S0,S):-
foldl_(Ls1,Ls2,Ls3,Pred,S0,S)。
foldl _([],[],[],_,S,S)。
foldl _([L1 | Ls1],[L2 | Ls2],[L3 | Ls3],Pred,S0,S):-
呼叫(Pred,L1,L2,L3,S0,S1),
foldl_(Ls1,Ls2,Ls3,Pred,S1,S)。
时间(目标):-
统计信息(运行时,[T0 | _]),
呼叫(目标),
统计信息(运行时,[T1 | _]),
T#= T1-T0,
格式(“%运行时:〜Dms \ n”,[T])。
主要区别:SICStus是带有严重CLP(FD)系统的商业级Prolog,在此用例及其他类似情况下,其 速度 比SWI-Prolog 快得多
。
指定的任务,在2个场上有6名球员:
?-time(网球(6,2,行)),
maplist(format(“〜t〜w〜3 +〜t〜w〜3 +〜t〜w〜3 +〜t〜w〜3 +〜t〜w〜3 +〜t〜w〜3 + \ n” ),行)。 **运行时**
百分比 **:34毫秒(!)**
-1 3 5 7 10
1-6 11 9 3
3 6-9 11 1
5 11 9-2 7
7 9 11 2-5
10 3 1 7 5-
较大的示例:
| ?-time(网球(7,5,行)),
maplist(format(“(t〜t〜w〜3 +〜t〜w〜3 +〜t〜w〜3 +〜t〜w〜3 +〜t〜w〜3 +〜t〜w〜3 +〜t〜 w〜3 + \ n“),行)。 **运行时**
百分比 **:884ms**
-1 3 5 7 9 11
1-5 3 9 7 13
3 5-1 11 13 7
5 3 1-13 13 9
7 9 11 13-3 1
9 7 13 11 3-5
11 13 7 9 1 5-
在这两个系统中,global_cardinality/3
您都可以指定选项来更改全局基数约束的传播强度,从而启用较弱且可能更有效的过滤。为特定示例选择正确的选项可能会比选择Prolog系统产生更大的影响。
9.1.3 编程案例:乒乓球比赛模拟 众所周知,中国乒乓球项目的技术水平世界第一,以至于所有比赛的冠军几乎都由中国球员包办。为了增强乒乓球运动的吸引力,提高其他国家的人对这项运动的兴趣,国际乒联 想了很多办法来削弱中国球员的绝对优势,例如扩大乒乓球的直径、禁用某些种类的球拍、 改变赛制等等。在本节中,我们将编写程序来模拟乒乓球比赛,以便研究一项针对中国球员 的规则改革是否真的有效。这项改革是:从
本文向大家介绍Android自定义控件实现球赛比分条效果,包括了Android自定义控件实现球赛比分条效果的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Android实现球赛比分条效果的具体代码,供大家参考,具体内容如下 效果图如下所示: 该控件需要输入两个参数,左边的得分数和右边的的分数 然后根据两边的得分的比例绘制中间的比分条 首先将控件的宽度平均分配为10分,第一份和最后一份
比赛速度功能有助于您保持稳定配速,并在设定距离内达到您的目标时间。定义某段距离的目标时间 - 例如将 10 公里跑步的目标时间设定为 45 分钟,并跟踪对比实际用时与这个预设目标的差距。 您可以在手表上设置比赛速度,或者可以在 Flow 网络服务或应用程序中设置比赛速度目标,并同步至手表。 如果您已计划好当天的比赛速度目标,手表会在进入训练准备模式时建议您启动该目标。 在手表上创建比赛速度目标 您
比赛速度功能有助于您保持稳定配速,并在设定距离内达到您的目标时间。定义某段距离的目标时间 - 例如将 10 公里跑步的目标时间设定为 45 分钟,并跟踪对比实际用时与这个预设目标的差距。 您可以在手表上设置比赛速度,或者可以在 Flow 网络服务或应用中设置比赛速度目标,并同步至手表。 如果您已计划好当天的比赛速度目标,手表会在进入训练准备模式时建议您启动该目标。 在手表上创建比赛速度目标 您可以
所以我试着在处理过程中对乒乓球进行编码,一切正常,我可以完美地上下移动球拍,但是,当你试图同时移动两个球拍时,他们不动/它不让你动(我将把这变成一个两人游戏,这样两个人可以使用同一个键盘,但不同的按键可以玩不同的桨)。 我认为这是使用“key”或“keyPressed”的问题,因为我认为它不能同时检测这两个或其他东西?但我似乎不知道如何解决这个问题或任何替代方案。(请记住,我知道如何移动桨叶,只是
问题内容: 这是带有潜在竞争条件的Django视图的简单示例: 竞争条件应该非常明显:用户可以两次发出此请求,并且该应用程序可能同时执行,从而导致其中一个请求覆盖另一个请求。 假设函数相对复杂,并且基于无法放置在单个存储过程中并且难以放置在存储过程中的各种奇怪的东西进行计算。 所以这是我的问题:django可使用哪种锁定机制来处理类似的情况? 问题答案: Django 1.4+支持select_f
我使用模式验证来验证响应,值返回一个数字或“NA”,下面是响应和模式验证。 收到错误消息: 如何纠正匹配表达式?
问题内容: 我在此乒乓球游戏中做了一个边框,屏幕上的桨可以越过它。我之前在另一段代码中已经做到了,但是现在一切都不同了。我有一个主要的想法如何做,您可能需要一个if语句,但是我没有所有的东西。 您可以删除“ pygame.load.image()”,因为您需要在文件夹中包含带有代码的图像,因此可以将其删除。会更好,因为您可以在python上尝试一下 问题答案: 为了使球拍保持在场地上,请在游戏循环