我正在尝试创建一个应用程序来计算异国情调的parimutuel下注成本。我已经找到了几种类型的赌注,但从来没有一种解决单一赌注类型的所有场景。如果我能找到一个可以计算所有可能组合的算法,我可以使用该公式来解决我的其他问题。
其他信息:
我需要计算一组数字的排列。例如;
第1组= 1,2,3
第2组= 2,3,4
第3组= 3,4,5
对于这三组数字的所有可能的排列是什么,每组排列1个数字。每个排列没有重复,这意味着一个数字不能出现在更多的1个位置。所以2,4,3是有效的,但2,4,4是无效的。
感谢您的帮助。
答案 0 :(得分:4)
与大多数有趣的问题一样,您的问题有几个解决方案。我写的算法(下面)是最简单的想法。
我发现最容易将问题想象为树搜索:第一组根,它包含每个数字的子项,其中每个子项是第二组。第二组对于它包含的每个数字都有一个第三组子项,第三组对于它包含的每个数字都有一个第四组子项。等等。您所要做的就是找到从根到叶子的所有有效路径。
然而,对于许多拥有大量数字的群体而言,这种方法在没有任何启发式的情况下会被证明是缓慢的。您可以做的一件事是按组大小排序组列表,首先按组最小组排序。这将是一种快速失败的方法,通常会发现排列不会比以后更有效。前瞻,arc-consistency和回溯是你可能想要考虑的其他事情。 [抱歉,我只能包含一个链接,因为这是我的第一篇文章,但您可以在维基百科上找到这些内容。]
## 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
答案 1 :(得分: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是基于每条腿用/分隔,每个位置用a,
分隔对于您的三连词计算,您可以通过以下方式解决: -
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(Set Unique to False)
result = explode('1,2,3/2,4,5/3,9/2,3,4', False)
stake = 2.0
cost = stake * len(result)
print cost
希望有所帮助
答案 2 :(得分:1)
这是我所知道的最简单的通用公式。
A =您首先选择的数量; B =第二个选择的数量; C =第三个选择的数量; AB =第一和第二选择的数量; AC =无。第一和第三; BC =无。第二和第三;和ABC =没有。所有第1,第2和第3选择。 公式是 (AxBxC) - (ABxC) - (ACxB) - (BCxA)+(2xABC)
所以,对于你的例子::
Group 1 = 1,2,3
Group 2 = 2,3,4
Group 3 = 3,4,5
溶液是::(3×3×3) - (2×3) - (1×3) - (2×3)+(2×1)= 14。希望有所帮助 可能有一种我不了解的更容易的方法。现在有谁知道First4的通用公式?
答案 3 :(得分:0)
作为一个下注者我可以告诉你有一个更简单的方法:
对于三连胜,您需要3种组合。假设有8个跑步者,可能的排列总数是8(总跑步者)* 7(赢家被忽略后剩余的跑步者)* 6(获胜者之后的剩余跑步者和第2个省略)= 336
对于一个精确的(有8个跑步者)8 * 7 = 56
Quinellas是一个例外,因为你只需要每次下注一次为1/2支付以及2/1所以答案是8 * 7/2 = 28
简单
答案 4 :(得分:0)
luskin提供的答案对于三连词是正确的。他提出了另一个我需要解决的关于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是如何工作的