在Python中,我正在寻找一个想法,但我不确定如何正确实现它。
我有一个26个字母的池('A' - 'Z'),每个字母可以根据需要多次使用。我想用这些字母创建列表;每个列表长10个字母,里面没有重复,我想保证如果我比较生成的任何两个列表,就会有正好一个字母。
问题:
任何有关材料的指示都将受到赞赏;我不需要在某个地方实现我的阿基米德杠杆(读作:我需要一个基础才能构建我的想法)。
“给我一个站立的地方,我会移动地球。” - 阿基米德
更新:我认为字母表足够合适,我多么天真。让我们将池扩展为300个符号,但保持列表的长度为10.这有用吗?
答案 0 :(得分:6)
只有26个字母可供选择,只能生成两个列表。
随机选择一个字母并将其放入两个列表中。然后选择18个不同的字母,并在每个列表中随机放置9个字母。然后您的列表将如下所示:
ABCDEFGHIJ
AKLMNOPQRS
如果添加第三个列表,则无法满足您的约束,因为只有七个未使用的字母。第三个列表必须与其他一个列表共享至少两个字母,您不允许这样做。
<强>更新强>
这只会部分回答您更新的问题,但我会发布它,因为它可能会帮助您或其他人找到最佳解决方案。
通常使用n
符号和长度为x
的列表,您可以使用上述算法轻松生成至少floor((n-1)/(x-1))
个列表(选择1个字母并将其添加到所有列表中)所以300个符号和长度为10的列表给出了33个列表。
但是可以通过使用不同的算法来改进这一点。例如,如果n为10且x为4,则上述算法仅给出三个列表:
ABCD
AEFG
AHIJ
但是更有效地重复使用字母的算法可以产生五个列表:
ABCD
AEFG
BEHI
CFHJ
DGIJ
我使用贪婪算法生成这些列表:对于每个新列表,从先前列表中重用尽可能多的不同字母,这意味着您添加尽可能少的新字母。
第二个列表重用第一个列表中的一个字母,并添加三个新字母。第三个列表重复使用前两个列表中每个列表的不同字母,因此仅引入两个新字母。第四个列表重用之前已经出现的三个字母,并再添加一个新字母。最终列表现在可以重复使用以前每个列表中的一个字母,而不需要添加任何新字母。
更新2
贪心算法肯定不是最佳解决方案。
我们试试:n = 26,x = 2
简单的解决方案提供了最佳的25个列表:
AB
AC
AD
..
AZ
然而,贪心算法只生成3个列表:
AB
AC
BC
现在不可能在不破坏其中一条规则的情况下添加更多列表。
答案 1 :(得分:1)
这是我为Set和Line Length的所有值找到的一般解决方案。第一个假设您不需要两个解决方案来共享相同的公共元素,但您希望每个解决方案都有一个与其他解决方案相同的元素。给定一个无限的池选择形式,解决方案的总数受每个解决方案的长度限制。
SET_LENGTH = 10
CHOICE_LENGTH = 300
data = set(range(CHOICE_LENGTH))
solutions =[]
solution_sets = []
used = set()
while True:
new_solution = []
#Try to get unique values from each previous set
try:
for sol_set in solution_sets:
while True:
candidate = sol_set.pop()
if not candidate in used:
new_solution.append(candidate)
used.update([candidate])
break
except KeyError, e:
print e
break
#Fill with new data until the line is long enough
try:
while len(new_solution) < SET_LENGTH:
new_solution.append(data.pop())
except KeyError, e:
print e
break
solutions.append(new_solution)
solution_sets.append(set(new_solution))
#Show the results
for solution in solutions:
print solution
print "Orphans %s" % len(data)
例如n = 300 x = 10得率:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 10, 11, 12, 13, 14, 15, 16, 17, 18]
[1, 10, 19, 20, 21, 22, 23, 24, 25, 26]
[2, 11, 19, 27, 28, 29, 30, 31, 32, 33]
[3, 12, 20, 32, 34, 35, 36, 37, 38, 39]
[4, 13, 21, 33, 34, 40, 41, 42, 43, 44]
[5, 14, 22, 27, 36, 40, 45, 46, 47, 48]
[6, 15, 23, 28, 37, 41, 45, 49, 50, 51]
[7, 16, 24, 29, 38, 42, 47, 49, 52, 53]
[8, 17, 25, 30, 39, 43, 48, 50, 52, 54]
[9, 18, 26, 31, 35, 44, 46, 51, 53, 54]
Orphans 245
如果您不关心有多少解决方案共享相同的公共元素,那么它就更容易了:
SET_LENGTH = 2
CHOICE_LENGTH = 300
data = set(range(CHOICE_LENGTH))
solutions =[]
alpha = data.pop()
while True:
new_solution = [alpha]
try:
[new_solution.append(data.pop()) for x in range(SET_LENGTH-1)]
except KeyError, e:
break
solutions.append(new_solution)
for solution in solutions:
print solution
print "Solutions: %s" % len(solutions)
print "Orphans: %s" % len(data)