3

我正在尝试创建一个应用程序来计算异国情调的 parimutuel 投注成本的成本。对于某些类型的赌注,我找到了几种,但从来没有一种可以解决单一赌注类型的所有情况。如果我能找到一种可以计算所有可能组合的算法,我就可以使用该公式来解决我的其他问题。

附加信息:我需要计算数字组的排列。例如;

第 1 组 = 1,2,3
第 2 组 = 2,3,4
第 3 组 = 3,4,5

这 3 组数字的所有可能排列是什么,每个排列从每个组中取 1 个数字。每个排列没有重复,这意味着一个数字不能出现在超过 1 个位置。所以 2,4,3 有效,但 2,4,4 无效。

感谢所有的帮助。

4

5 回答 5

4

像大多数有趣的问题一样,您的问题有几个解决方案。我写的算法(如下)是我想到的最简单的东西。

我发现最容易将问题想象成树搜索:第一组,即根,它包含的每个数字都有一个孩子,其中每个孩子都是第二组。第二组对于它包含的每个数字都有一个第三组子节点,第三组对于它包含的每个数字都有一个第四组子节点,等等。您所要做的就是找到从根到叶子的所有有效路径。

但是,对于许多具有大量数字的组,如果没有任何启发式方法,这种方法将被证明是缓慢的。您可以做的一件事是按组大小对组列表进行排序,首先是最小组。这将是一种快速失败的方法,通常会发现置换迟早是无效的。Look-ahead、arc-consistency和 backtracking 是您可能需要考虑的其他事情。[对不起,我只能包含一个链接,因为这是我的第一篇文章,但你可以在维基百科上找到这些东西。]

## Algorithm written in Python ##
## CodePad.org has a Python interpreter

Group1 = [1,2,3] ## Within itself, each group must be composed of unique numbers
Group2 = [2,3,4]
Group3 = [3,4,5]
Groups = [Group1,Group2,Group3] ## Must contain at least one Group

Permutations = [] ## List of valid permutations

def getPermutations(group, permSoFar, nextGroupIndex):
  for num in group:
    nextPermSoFar = list(permSoFar) ## Make a copy of the permSoFar list

    ## Only proceed if num isn't a repeat in nextPermSoFar
    if nextPermSoFar.count(num) == 0: 
      nextPermSoFar.append(num)  ## Add num to this copy of nextPermSoFar

      if nextGroupIndex != len(Groups): ## Call next group if there is one...
        getPermutations(Groups[nextGroupIndex], nextPermSoFar, nextGroupIndex + 1)
      else: ## ...or add the valid permutation to the list of permutations
        Permutations.append(nextPermSoFar)

## Call getPermutations with:
##  * the first group from the list of Groups
##  * an empty list
##  * the index of the second group
getPermutations(Groups[0], [], 1)

## print results of getPermutations
print 'There are', len(Permutations), 'valid permutations:'
print Permutations
于 2009-07-22T19:33:55.940 回答
1

几年后修改:-

一段时间后我重新登录我的 SE 帐户并注意到这个问题,并意识到我写的甚至没有回答你:-

这是一些python代码

import itertools
def explode(value, unique):
    legs = [ leg.split(',') for leg in value.split('/') ]
    if unique:
        return [ tuple(ea) for ea in itertools.product(*legs) if len(ea) == len(set(ea)) ]
    else:
        return [ tuple(ea) for ea in itertools.product(*legs) ]

调用 explode 的工作原理是每条腿用 / 隔开,每个位置用 隔开,

对于您的三重奏计算,您可以通过以下方式进行计算:-

result = explode('1,2,3/2,3,4/3,4,5', True)
stake = 2.0
cost = stake * len(result)
print cost

对于一个superfecta

result = explode('1,2,3/2,4,5/1,3,6,9/2,3,7,9', True)
stake = 2.0
cost = stake * len(result)
print cost

对于 pick4(将唯一设置为 False)

result = explode('1,2,3/2,4,5/3,9/2,3,4', False)
stake = 2.0
cost = stake * len(result)
print cost

希望有帮助

于 2011-01-24T05:22:45.323 回答
1

这是我所知道的三连胜最简单的通用公式。

A=您首先选择的数量;B=第二个选择的数量;C=第三个选择的数量;AB = 您在第一和第二中的选择数;AC=否。第一和第三;公元前=不。第 2 次和第 3 次;和 ABC = 编号。第一,第二和第三的所有选择。公式为 (AxBxC)-(ABxC)-(ACxB)-(BCxA)+(2xABC)

所以,对于你的例子::

 Group 1 = 1,2,3
 Group 2 = 2,3,4
 Group 3 = 3,4,5

解决方案是:: (3x3x3)-(2x3)-(1x3)-(2x3)+(2x1)=14。希望有帮助 可能有一种我不知道的更简单的方法。现在有人知道First4的通用公式吗?

于 2014-07-24T13:58:45.177 回答
0

作为一个下注者,我可以告诉你有一个更简单的方法:

对于三连击,您需要 3 种组合。假设有 8 名参赛者,可能的排列总数为 8(总参赛者)* 7(省略获胜者之后的剩余参赛者)* 6(省略获胜者和第二名之后的剩余参赛者)= 336

对于一个精确的(有 8 个跑步者)8 * 7 = 56

Quinellas 是一个例外,因为您只需每次下注一次,因为 1/2 支付以及 2/1 支付,所以答案是 8*7/2 = 28

简单的

于 2010-04-21T03:47:42.793 回答
0

luskin 提供的答案对于 trifectas 是正确的。他提出了另一个我需要解决的关于 First4 的问题。我到处找,但找不到公式。然而,我确实找到了一种简单的方法来确定唯一排列的数量,使用嵌套循环来排除重复序列。

    Public Function fnFirst4PermCount(arFirst, arSecond, arThird, arFourth) As Integer


Dim intCountFirst As Integer
Dim intCountSecond As Integer
Dim intCountThird As Integer
Dim intCountFourth As Integer
Dim intBetCount As Integer

'Dim arFirst(3) As Integer
'Dim arSecond(3) As Integer
'Dim arThird(3) As Integer
'Dim arFourth(3) As Integer

'arFirst(0) = 1
'arFirst(1) = 2
'arFirst(2) = 3
'arFirst(3) = 4
'
'arSecond(0) = 1
'arSecond(1) = 2
'arSecond(2) = 3
'arSecond(3) = 4
'
'arThird(0) = 1
'arThird(1) = 2
'arThird(2) = 3
'arThird(3) = 4
'
'arFourth(0) = 1
'arFourth(1) = 2
'arFourth(2) = 3
'arFourth(3) = 4

intBetCount = 0
For intCountFirst = 0 To UBound(arFirst)
    For intCountSecond = 0 To UBound(arSecond)
        For intCountThird = 0 To UBound(arThird)
            For intCountFourth = 0 To UBound(arFourth)
                If (arFirst(intCountFirst) <> arSecond(intCountSecond)) And (arFirst(intCountFirst) <> arThird(intCountThird)) And (arFirst(intCountFirst) <> arFourth(intCountFourth)) Then
                    If (arSecond(intCountSecond) <> arThird(intCountThird)) And (arSecond(intCountSecond) <> arFourth(intCountFourth)) Then
                        If (arThird(intCountThird) <> arFourth(intCountFourth)) Then
                        '    Debug.Print "First " & arFirst(intCountFirst), " Second " & arSecond(intCountSecond), "Third " & arThird(intCountThird), " Fourth " & arFourth(intCountFourth)
                            intBetCount = intBetCount + 1
                        End If
                    End If
                End If
            Next intCountFourth
        Next intCountThird
    Next intCountSecond
Next intCountFirst
fnFirst4PermCount = intBetCount

End Function

此函数为每个位置接受四个字符串数组。我留下了测试代码(已注释掉),因此您可以看到四个位置中每个位置的 1/2/3/4 是如何工作的

于 2017-07-20T00:48:01.400 回答