我有一個很好的規劃工作,我只是不能左右我的頭(除了蠻力,這是太大處理)。我們正在組織12人的高爾夫之旅。我們打4天的高爾夫球。每天有3班航班。 (所以共有12個航班)。如何防止36K X 36K X 36K的排列來計算
我們希望:
- 最大化,在飛行打對方唯一的玩家數量,
- 但也希望儘量減少(2名球員打得比一次對方更多雙OCCURENCES數量)。
由於每個航班有12名玩家和4名玩家,我可以每天每個航班大致創建36k玩家組合,因此它變得非常計算密集。有沒有更聰明的方法來解決這個問題?我的直覺告訴斐波那契可以提供幫助,但不知道具體如何。
這是我的代碼至今:
import random
import itertools
import pandas as pd
def make_player_combi(day):
player_combis = []
for flight in day:
#print flight
for c in itertools.combinations(flight,2):
combi = list(sorted(c))
player_combis.append('-'.join(combi))
return player_combis
def make_score(a,b,c):
df = pd.DataFrame(a + b + c,columns=['player_combi'])['player_combi']
combi_counts = df.value_counts()
pairs_playing = len(combi_counts)
double_plays = combi_counts.value_counts().sort_index()
return pairs_playing, double_plays
players = ['A','B','C', 'D', 'E', 'F', 'G', 'H', 'I', 'J','K','L']
available_players = players[:]
n = 0
combinations_per_day = []
for players_in_flight_1 in itertools.combinations(players,4):
available_players_flight_1 = players[:]
available_players_flight_2 = players[:]
available_players_flight_3 = players[:]
for player in players_in_flight_1:
# players in flight1 can no longer be used in flight 2 or 3
available_players_flight_2.remove(player)
available_players_flight_3.remove(player)
for players_in_flight_2 in itertools.combinations(available_players_flight_2,4):
players_in_flight_3 = available_players_flight_3[:]
for player in players_in_flight_2:
players_in_flight_3.remove(player)
n = n + 1
print str(n), players_in_flight_1,players_in_flight_2,tuple(players_in_flight_3)
combinations_per_day.append([players_in_flight_1,players_in_flight_2,tuple(players_in_flight_3)])
n_max = 100 # limit to 100 entries max per day to save calculations
winning_list = []
max_score = 0
for day_1 in range(0,len(combinations_per_day[0:n_max])):
print day_1
for day_2 in range(0,len(combinations_per_day[0:n_max])):
for day_3 in range(0,len(combinations_per_day[0:n_max])):
a = make_player_combi(combinations_per_day[day_1])
b = make_player_combi(combinations_per_day[day_2])
x,y = make_score(a,b,c)
if x >= max_score:
max_score = x
my_result = {'pairs_playing' : x,
'double_plays' : y,
'max_day_1' : day_1,
'max_day_2' : day_2,
'max_day_3' : day_3
}
winning_list.append(my_result)
對數學的評論:對於單次飛行,有'多項式[12; 4,4,4] = 34650'的可能性。對於12次航班,可以重複選擇12次。這使得[二項式[34650 + 12 - 1; 12]'](https://www.wolframalpha.com/input/?i=Binomial%5B34650+%2B+12+-+1,+12%5D)設置12個航班的可能性。對於蠻力來說太多了;-) – davidhigh
我的第一個猜測是,這可能是一個整數編程問題。整數編程是一種各種約束優化,其中解決方案必須以整數形式存在。有各種軟件包來解決這些問題。我已經使用免費軟件GLPK解決相關問題,並且對我來說效果很好。您需要用特定領域的語言來表達您的問題,然後由GPLK進行處理。表達問題通常要比找到解決方案簡單得多,因此這是一個巨大的勝利。 –
你能否通過「最大限度地發揮在一次飛行中相互扮演的獨特玩家的數量」來闡明你的意思?我不明白。另外,我是否正確理解您爲每個航班選擇了一個新的4人團隊?或者你每天只選擇新的團隊?感謝您的澄清。 –