Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/prolog/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog 分组_Prolog - Fatal编程技术网

Prolog 分组

Prolog 分组,prolog,Prolog,数据库包含一个团队列表,每个团队按位置(西队、东队等)分开。有两类事实可以描述这一点。团队(团队编号,损失)和区域(团队编号,区域)。例如: team(1, 10). team(2, 11). team(3, 12). team(4, 13). region(1, east). region(2, west). region(3, east). region(4, southeast). 注意:球队名单并不总是从最少的损失到最多的损失排序 我试着将一组球队组合在一起,这样损失最高的球队与损失

数据库包含一个团队列表,每个团队按位置(西队、东队等)分开。有两类事实可以描述这一点。团队(团队编号,损失)和区域(团队编号,区域)。例如:

team(1, 10).
team(2, 11).
team(3, 12).
team(4, 13).

region(1, east).
region(2, west).
region(3, east).
region(4, southeast).
注意:球队名单并不总是从最少的损失到最多的损失排序

我试着将一组球队组合在一起,这样损失最高的球队与损失最低的球队组合,然后损失第二高的球队与损失第二低的球队组合,然后埃塞特拉埃塞特拉。规则是,在同一区域内结对团队是一个优先事项。在上面的例子中,第3队和第1队将配对在一起,因为他们都是东部队。现在,剩下的队伍是第2队和第4队。但是因为没有其他球队在他们的地区,第2和第4队是相互匹配的

现在,我在想我可以写什么函数来配对团队。我已经编写了一个函数,将一个区域内的所有不同团队组合到一个对应的列表中。我还编写了一个函数来获取最小值和最大值(最高和最低损失)


如何编写一个函数,将同一区域内的所有团队配对,然后创建一个新列表,将该列表中的所有剩余团队粘在一起?

好的,我已经尝试过了。我认为所有团队将提供一个列表,其中包括您所描述的所有已配对团队,以及一个剩余团队(如果团队数量为奇数)


我正确理解你的要求了吗?

好的,我已经试过了。我认为所有团队将提供一个列表,其中包括您所描述的所有已配对团队,以及一个剩余团队(如果团队数量为奇数)

我正确理解你的要求了吗

我还编写了一个函数来获取最小值和最大值(最高和最低损失)

Prolog和其他声明性语言与过程性语言在一些令人惊讶的方面有所不同,其中之一是频繁地做一点工作,期望从某种循环结构中重用它,这并不完全是正确的方法。这在SQL中更为明显,在SQL中,您应该始终以集合的形式进行处理,但在Prolog中,我们所使用的几个显式循环结构并没有被大量使用

在程序环境中匹配得分低和得分高的团队的问题最好通过以下过程解决:

def match(teams):
  while we have teams:
    remove the lowest scoring team from teams
    remove the highest scoring team from teams
    save this pair
  return the list of pairs
match_lowest_highest(SortedList, Pairs) :-
  length(SortedList, N2),
  N is N2 div 2,
  length(TopHalf, N),
  append(TopHalf, BottomHalf, SortedList),
  reverse(BottomHalf, BottomHalfFlipped),
  pair_off(TopHalf, BottomHalfFlipped, Pairs).
使其更具功能性的简单方法是使用递归:

def match(teams):
  if teams is empty: return empty list
  otherwise:
    remove the lowest scoring team
    remove the highest scoring team
    return this pair appended to match(teams without these two items)
实际上,您可以不费吹灰之力将其转换为外观合理的序言:

match([], []).
match(Teams, [Lowest-Highest|Pairs]) :-
  lowest(Teams, Lowest),
  highest(Teams, Highest),
  select(Lowest, Teams, TeamsWithoutLowest),
  select(Highest, TeamsWithoutLowest, RemainingTeams),
  match(RemainingTeams, Pairs).
这不太可能是有效的,因为在
select/3
中有大量重复的列表扫描和大量列表重建,但它可能更具声明性

另一种方法是对团队列表进行排序,然后将其自身折叠,以获得最低和最高的配对。视觉上:

[1, 2, 3, 4, 5, 6]
[1, 2, 3],  [4, 5, 6]
[1, 2, 3],  [6, 5, 4]

[1,     2,     3]
[6,     5,     4]
-------------------
[1-6], [2-5], [3-4]
我们可以在Prolog中直接执行此操作,但首先我们需要一种将两个列表配对的方法:

pair_off([], _, []).
pair_off([L|Ls], [R|Rs], [L-R|Rest]) :- pair_off(Ls, Rs, Rest).
然后,算法进入Prolog,如下所示:

def match(teams):
  while we have teams:
    remove the lowest scoring team from teams
    remove the highest scoring team from teams
    save this pair
  return the list of pairs
match_lowest_highest(SortedList, Pairs) :-
  length(SortedList, N2),
  N is N2 div 2,
  length(TopHalf, N),
  append(TopHalf, BottomHalf, SortedList),
  reverse(BottomHalf, BottomHalfFlipped),
  pair_off(TopHalf, BottomHalfFlipped, Pairs).
这仍然不是非常有效,但是
reverse/2
内置的可能使用了差异列表,所以它不应该太贵;通过使用
append/3
和一个已经具体化的未知列表,我们保存了一堆临时列表结构,这些临时列表结构将被丢弃。因此,我不认为这会是非常低效的,但我相信还有其他更有效的方法

我还编写了一个函数来获取最小值和最大值(最高和最低损失)

Prolog和其他声明性语言与过程性语言在一些令人惊讶的方面有所不同,其中之一是频繁地做一点工作,期望从某种循环结构中重用它,这并不完全是正确的方法。这在SQL中更为明显,在SQL中,您应该始终以集合的形式进行处理,但在Prolog中,我们所使用的几个显式循环结构并没有被大量使用

在程序环境中匹配得分低和得分高的团队的问题最好通过以下过程解决:

def match(teams):
  while we have teams:
    remove the lowest scoring team from teams
    remove the highest scoring team from teams
    save this pair
  return the list of pairs
match_lowest_highest(SortedList, Pairs) :-
  length(SortedList, N2),
  N is N2 div 2,
  length(TopHalf, N),
  append(TopHalf, BottomHalf, SortedList),
  reverse(BottomHalf, BottomHalfFlipped),
  pair_off(TopHalf, BottomHalfFlipped, Pairs).
使其更具功能性的简单方法是使用递归:

def match(teams):
  if teams is empty: return empty list
  otherwise:
    remove the lowest scoring team
    remove the highest scoring team
    return this pair appended to match(teams without these two items)
实际上,您可以不费吹灰之力将其转换为外观合理的序言:

match([], []).
match(Teams, [Lowest-Highest|Pairs]) :-
  lowest(Teams, Lowest),
  highest(Teams, Highest),
  select(Lowest, Teams, TeamsWithoutLowest),
  select(Highest, TeamsWithoutLowest, RemainingTeams),
  match(RemainingTeams, Pairs).
这不太可能是有效的,因为在
select/3
中有大量重复的列表扫描和大量列表重建,但它可能更具声明性

另一种方法是对团队列表进行排序,然后将其自身折叠,以获得最低和最高的配对。视觉上:

[1, 2, 3, 4, 5, 6]
[1, 2, 3],  [4, 5, 6]
[1, 2, 3],  [6, 5, 4]

[1,     2,     3]
[6,     5,     4]
-------------------
[1-6], [2-5], [3-4]
我们可以在Prolog中直接执行此操作,但首先我们需要一种将两个列表配对的方法:

pair_off([], _, []).
pair_off([L|Ls], [R|Rs], [L-R|Rest]) :- pair_off(Ls, Rs, Rest).
然后,算法进入Prolog,如下所示:

def match(teams):
  while we have teams:
    remove the lowest scoring team from teams
    remove the highest scoring team from teams
    save this pair
  return the list of pairs
match_lowest_highest(SortedList, Pairs) :-
  length(SortedList, N2),
  N is N2 div 2,
  length(TopHalf, N),
  append(TopHalf, BottomHalf, SortedList),
  reverse(BottomHalf, BottomHalfFlipped),
  pair_off(TopHalf, BottomHalfFlipped, Pairs).

这仍然不是非常有效,但是
reverse/2
内置的可能使用了差异列表,所以它不应该太贵;通过使用
append/3
和一个已经具体化的未知列表,我们保存了一堆临时列表结构,这些临时列表结构将被丢弃。因此,我不认为这会非常低效,但我相信还有其他方法可以更有效地完成这项工作。

我认为没有一个答案是充分的?是的,我看了一下,但它没有告诉我如何根据最高的赢/输规则配对。这不是@Capelical的
%先拿后拿
行的功能吗?哦,我一定错过了他的功能。但我甚至不知道他的
%takefirst和last
到底在做什么。你能解释一下吗?我想我会在…之后结束这个问题。我想如果你能找出所有这些问题,并且你真的想学习Prolog,你应该试着学习