Los*_*oul 52 python java algorithm machine-learning data-mining
我正在学习编程(Python和算法),并且正在尝试处理我感兴趣的项目.我已经创建了一些基本的Python脚本,但我不确定如何处理我正在尝试构建的游戏的解决方案.
以下是游戏的工作方式:
将为用户提供具有值的项目.例如,
Apple = 1
Pears = 2
Oranges = 3
Run Code Online (Sandbox Code Playgroud)
然后他们将有机会选择他们喜欢的任何组合(即100个苹果,20个梨和一个橙色).计算机获得的唯一输出是总值(在此示例中,它当前为143美元).电脑会试着猜猜他们有什么.显然,第一回合无法正确使用.
Value quantity(day1) value(day1)
Apple 1 100 100
Pears 2 20 40
Orange 3 1 3
Total 121 143
Run Code Online (Sandbox Code Playgroud)
下一轮用户可以修改他们的数量但不超过总数量的5%(或者我们可能选择的其他百分比.例如,我将使用5%).水果价格可以随意变化,因此总价值也可能因此而变化(为简单起见,本例中我没有改变水果价格).使用上面的例子,在游戏的第2天,用户在第3天返回$ 152和$ 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
Run Code Online (Sandbox Code Playgroud)
*(我希望表格显示正确,我必须手动分隔它们,所以希望它不仅仅是在我的屏幕上进行,如果它不起作用,请告诉我,我会尝试上传截图.)
我试图看看我是否可以计算出一段时间内的数量(假设用户有耐心继续输入数字).我现在知道我唯一的限制是总价值不能超过5%所以我现在不能达到5%的准确度,所以用户将永远进入它.
到目前为止我做了什么
到目前为止,这是我的解决方案(不多).基本上,我采取所有的价值观并找出他们所有可能的组合(我完成了这一部分).然后我拿出所有可能的组合并将它们作为字典放入数据库中(例如,对于143美元,可能有一个字典条目{apple:143,Pears:0,Oranges:0} ..一直到{apple :0,Pears:1,Oranges:47}.每次我得到一个新号码时都这样做,所以我列出了所有可能性.
这就是我被困的地方.在使用上述规则时,我如何找出最佳解决方案?我想我需要一个健身功能,可以自动比较两天的数据,并消除前几天数据差异超过5%的任何可能性.
问题:
所以我的问题是用户改变总数而我有一个所有概率的列表,我该如何处理?我需要学习什么?是否有任何算法或我可以使用的理论适用?或者,为了帮助我理解我的错误,你能否建议我可以添加哪些规则以使这个目标可行(如果它不在当前状态.我正在考虑添加更多水果并说他们必须选择至少3个等等.) ?另外,我对遗传算法只有模糊的理解,但我认为我可以在这里使用它们,如果有什么我可以使用的吗?
我非常非常渴望学习,所以任何建议或提示将不胜感激(只是请不要告诉我这个游戏是不可能的).
更新:获得这很难解决的反馈.所以我认为我会在游戏中添加另一个条件,它不会干扰玩家正在做的事情(游戏对他们保持不变),但每天水果的价值会随机变化(随机).这会让它更容易解决吗?因为在5%的运动和某些果实值变化中,随着时间的推移可能只有少数组合.
第1天,任何事都有可能并且获得足够接近的范围几乎是不可能的,但随着水果价格的变化而用户只能选择5%的变化,那么不应该(随着时间的推移)范围变窄和变窄.在上面的例子中,如果价格足够波动,我想我可以强行推出一个解决方案给我一个范围来猜测,但我想弄清楚是否有一个更优雅的解决方案或其他解决方案来保持缩小这个范围时间.
更新2:在阅读并询问后,我相信这是一个隐藏的马尔可夫/维特比问题,它跟踪水果价格的变化以及总和(加权最后的数据点最重).我不知道如何应用这种关系.我认为情况确实如此,但至少我开始怀疑这是某种类型的机器学习问题.
更新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
Run Code Online (Sandbox Code Playgroud)
Lio*_*gan 12
我们将图论与概率结合起来:
在第一天,建立一套所有可行的解决方案.Lets表示设置为A1 = {a1(1),a1(2),...,a1(n)}的解.
在第二天,您可以再次构建解决方案集A2.
现在,对于A2中的每个元素,您需要检查是否可以从A1的每个元素到达(给定x%容差).如果是这样 - 将A2(n)连接到A1(m).如果无法从A1(m)中的任何节点到达 - 您可以删除此节点.
基本上我们正在构建一个连通的有向无环图.
图中的所有路径都具有相同的可能性.只有当存在从Am到Am + 1的单个边缘时(从Am中的节点到Am + 1中的节点),才能找到精确解.
当然,一些节点出现在比其他节点更多的路径中.可以基于包含该节点的路径的数量直接推导出每个节点的概率.
通过为每个节点分配权重(等于通向此节点的路径数),不需要保留所有历史记录,而只需保留前一天.
另外,看看非负值线性diphantine方程 - 我刚才问过的一个问题.接受的答案是在每个步骤中对所有组合进行enumarte的好方法.
这个问题是不可能解决的.
假设你确切地知道物品的比例增加了多少,而不仅仅是最大比例是多少.
一个用户有N个水果,你有D天的猜测.
在每一天你得到N个新变量然后你有总共D*N个变量.
对于每一天,您只能生成两个方程式.一个等式是n_item*价格的总和,而另一个是基于已知比率.如果它们都是独立的,那么总共有2*D个方程式.
所有N> 2的2*D <N*D.
免责声明:我暂时删除了我的答案并仔细阅读了问题,因为我误解了问题的一些关键部分,因此我的答案发生了显着变化.虽然仍然引用类似的主题和算法,但在我尝试用C#自己解决一些问题之后,答案得到了极大的改善.
首先,我想说明我看到的两个主要问题:
绝大多数可能的解决方案.仅知道项目的数量和总值,例如3和143,将产生许多可能的解决方案.另外,如果没有不可避免地尝试无效解决方案(总计不等于143),那么选择有效解决方案的算法并不容易.
当找到给定日D i的可能解决方案时,必须找到一种消除潜在解决方案的方法,其中添加的信息由{D i + 1 .. D i + n }给出.
让我们为即将到来的例子奠定一些基础:
为了更容易地解决这个问题,我冒昧地改变了一个约束,这使得算法收敛得更快:
此规则使我们能够更轻松地排除解决方案.并且,对于非小范围,渲染回溯算法仍然无用,就像您原来的问题和规则一样.
在我看来,这个规则不是游戏的本质,而只是一个促进者,使计算机能够解决问题.
对于初学者,可以使用蒙特卡罗算法来解决问题1.以找到一组潜在的解决方案.技术很简单:为项目值和数量生成随机数(在各自可接受的范围内).对所需数量的项目重复此过程.验证解决方案是否可接受.这意味着验证项目是否具有不同的值,并且总数等于我们的目标总数(例如,143.)
虽然这种技术具有易于实现的优点,但它有一些缺点:
如何克服这些缺点?好...
请注意,限制范围的越多,蒙特卡罗算法的有用性就越小,因为在合理的时间内几乎没有足够的有效解决方案来迭代它们.对于约束{3,[1-10],[0-100]},有大约741,000,000个有效解(不限于目标总值).蒙特卡罗在那里可用.对于{3,[1-5],[0-10]},只有大约80,000.无需使用蒙特卡罗; 蛮力for循环会做得很好.
我相信问题1就是你所谓的约束满足问题(或CSP).
鉴于问题1是CSP,我会继续调用问题2,而问题一般是动态CSP(或DCSP).
当以某种方式改变问题的原始表述时,[DCSP]是有用的,通常是因为要考虑的一组约束因环境而发展.DCSP被视为一系列静态CSP,每个CSP都是前一个CSP的变换,其中可以添加(限制)或删除(松弛)变量和约束.
与CSP一起使用的一种可能对此问题有用的技术称为约束记录:
为此,您需要每天获得一套新的可能解决方案; 使用蛮力或蒙特卡罗.然后,比较D i到D i-1的解决方案,并且只保留能够在不违反约束的情况下成功解决前几天解决方案的解决方案.
您可能必须保留解决方案导致其他解决方案(可能在有向图中)的历史记录.约束记录使您能够记住可能的添加 - 删除数量并拒绝基于此的解决方案.
可以采取许多其他步骤来进一步改进您的解决方案.以下是一些想法:
鉴于所有这些,尝试找出基于解决方案和启发式的出现的排名系统来确定候选解决方案.
| 归档时间: |
|
| 查看次数: |
3399 次 |
| 最近记录: |