更新(2020 年 7 月):问题已有 9 年历史,但仍然是我非常感兴趣的问题。从那以后,机器学习(RNN、CNN、GANS 等)、新方法和廉价 GPU 的兴起使新方法成为可能. 我认为重新审视这个问题以查看是否有新方法会很有趣。
我正在学习编程(Python 和算法),并试图从事一个我觉得有趣的项目。我已经创建了一些基本的 Python 脚本,但我不确定如何为我正在尝试构建的游戏找到解决方案。
以下是游戏的运作方式:
用户将获得具有值的项目。例如,
Apple = 1
Pears = 2
Oranges = 3
然后他们将有机会选择他们喜欢的任何组合(即 100 个苹果、20 个梨和一个橙子)。计算机获得的唯一输出是总值(在本例中,当前为 143 美元)。计算机将尝试猜测他们拥有什么。显然它无法在第一回合正确地获得。
Value quantity(day1) value(day1)
Apple 1 100 100
Pears 2 20 40
Orange 3 1 3
Total 121 143
下一回合,用户可以修改他们的数字,但不超过总量的 5%(或者我们可能选择的其他百分比。我将使用 5% 为例。)。水果的价格可以(随机)变化,因此总价值也可能基于此变化(为简单起见,我在此示例中没有更改水果价格)。使用上面的例子,在游戏的第 2 天,用户返回值 152 美元,在第 3 天返回 164 美元。下面是一个例子:
Quantity (day2) %change (day2) Value (day2) Quantity (day3) %change (day3) Value(day3)
104 104 106 106
21 42 23 46
2 6 4 12
127 4.96% 152 133 4.72% 164
*(我希望表格显示正确,我必须手动将它们隔开,所以希望它不仅仅是在我的屏幕上进行,如果它不起作用,请告诉我,我会尝试上传屏幕截图。)
我想看看我是否能弄清楚随着时间的推移数量是多少(假设用户有耐心继续输入数字)。我现在知道我唯一的限制是总值不能超过 5%,所以我现在不能达到 5% 的准确度,所以用户将永远输入它。
到目前为止我做了什么
到目前为止,这是我的解决方案(不多)。基本上,我获取所有值并找出它们的所有可能组合(我已经完成了这部分)。然后我将所有可能的组合作为字典放入数据库中(例如,对于 143 美元,可能有一个字典条目 {apple:143, Pears:0, Oranges:0}.. 一直到 {apple :0, Pears:1, Oranges:47}. 每次我得到一个新号码时我都会这样做,这样我就有了所有可能性的列表。
这就是我卡住的地方。在使用上述规则时,我怎样才能找出最好的解决方案?我想我需要一个适应度函数来自动比较这两天的数据,并消除任何与前几天数据的方差超过 5% 的可能性。
问题:
所以我的问题是用户更改总数并且我有一个所有概率的列表,我应该如何解决这个问题?我需要学习什么?是否有任何适用的算法或我可以使用的理论?或者,为了帮助我理解我的错误,你能建议我可以添加哪些规则来使这个目标可行(如果它不是当前状态。我在考虑添加更多水果并说他们必须至少选择 3 个,等等。) ? 另外,我对遗传算法只有模糊的了解,但我认为我可以在这里使用它们,如果有什么我可以使用的吗?
我非常非常渴望学习,所以任何建议或提示将不胜感激(只是请不要告诉我这个游戏是不可能的)。
更新:得到反馈,这很难解决。所以我想我会在游戏中添加另一个不会干扰玩家正在做的事情的条件(游戏对他们来说保持不变)但是每天水果的价值都会改变价格(随机)。这样会更容易解决吗?因为在 5% 的移动和某些水果值的变化内,随着时间的推移,只有少数组合是可能的。
第 1 天,一切皆有可能,获得足够接近的范围几乎是不可能的,但随着水果价格的变化,用户只能选择 5% 的变化,那么(随着时间的推移)范围不应该越来越窄。在上面的例子中,如果价格波动足够大,我想我可以暴力破解一个给我一个猜测范围的解决方案,但我试图弄清楚是否有更优雅的解决方案或其他解决方案来不断缩小这个范围时间。
UPDATE2:在阅读和询问之后,我相信这是一个隐藏的马尔科夫/维特比问题,它跟踪水果价格的变化以及总和(最后一个数据点的权重最重)。我不确定如何应用这种关系。我认为情况就是这样,可能是错误的,但至少我开始怀疑这是某种机器学习问题。
更新 3:我创建了一个测试用例(数字较小)和一个生成器来帮助自动化用户生成的数据,我正在尝试从中创建一个图表以查看更有可能发生的情况。
这是代码,以及用户实际水果数量的总值和评论。
#!/usr/bin/env python
import itertools
# Fruit price data
fruitPriceDay1 = {'Apple':1, 'Pears':2, 'Oranges':3}
fruitPriceDay2 = {'Apple':2, 'Pears':3, 'Oranges':4}
fruitPriceDay3 = {'Apple':2, 'Pears':4, 'Oranges':5}
# Generate possibilities for testing (warning...will not scale with large numbers)
def possibilityGenerator(target_sum, apple, pears, oranges):
allDayPossible = {}
counter = 1
apple_range = range(0, target_sum + 1, apple)
pears_range = range(0, target_sum + 1, pears)
oranges_range = range(0, target_sum + 1, oranges)
for i, j, k in itertools.product(apple_range, pears_range, oranges_range):
if i + j + k == target_sum:
currentPossible = {}
#print counter
#print 'Apple', ':', i/apple, ',', 'Pears', ':', j/pears, ',', 'Oranges', ':', k/oranges
currentPossible['apple'] = i/apple
currentPossible['pears'] = j/pears
currentPossible['oranges'] = k/oranges
#print currentPossible
allDayPossible[counter] = currentPossible
counter = counter +1
return allDayPossible
# Total sum being returned by user for value of fruits
totalSumDay1=26 # Computer does not know this but users quantities are apple: 20, pears 3, oranges 0 at the current prices of the day
totalSumDay2=51 # Computer does not know this but users quantities are apple: 21, pears 3, oranges 0 at the current prices of the day
totalSumDay3=61 # Computer does not know this but users quantities are apple: 20, pears 4, oranges 1 at the current prices of the day
graph = {}
graph['day1'] = possibilityGenerator(totalSumDay1, fruitPriceDay1['Apple'], fruitPriceDay1['Pears'], fruitPriceDay1['Oranges'] )
graph['day2'] = possibilityGenerator(totalSumDay2, fruitPriceDay2['Apple'], fruitPriceDay2['Pears'], fruitPriceDay2['Oranges'] )
graph['day3'] = possibilityGenerator(totalSumDay3, fruitPriceDay3['Apple'], fruitPriceDay3['Pears'], fruitPriceDay3['Oranges'] )
# Sample of dict = 1 : {'oranges': 0, 'apple': 0, 'pears': 0}..70 : {'oranges': 8, 'apple': 26, 'pears': 13}
print graph