python - 在 Python 中实现蒙特卡罗马尔可夫链时出现错误

标签 python python-2.7 numpy probability

我正在尝试使用 numpy 在 Python 2.7 中实现一个简单的马尔可夫链蒙特卡罗。目标是找到“背包问题”的解决方案,其中给定一组 m 个值(value)为 vi 、重量为 wi 的物体,以及一个容量为 b 的袋子,您可以找到可以放入袋子中的最大值(value)的物体,以及这些对象是什么。我从夏天开始编码,我的知识非常不平衡,所以如果我遗漏了一些明显的东西,我很抱歉,我是自学的,一直在到处跳跃。

系统的代码如下(我将其分成几部分,试图找出问题所在)。

import numpy as np
import random


def flip_z(sackcontents): 
    ##This picks a random object, and changes whether it's been selected or not.
    pick=random.randint(0,len(sackcontents)-1)
    clone_z=sackcontents
    np.put(clone_z,pick,1-clone_z[pick])
    return clone_z

def checkcompliance(checkedz,checkedweights,checkedsack):
    ##This checks to see whether a given configuration is overweight
    weightVector=np.dot(checkedz,checkedweights)
    weightSum=np.sum(weightVector)
    if (weightSum > checkedsack):
        return False
    else:
        return True

def getrandomz(length):
    ##I use this to get a random starting configuration.
    ##It's not really important, but it does remove the burden of choice.       
    z=np.array([])
    for i in xrange(length):
        if random.random() > 0.5:
            z=np.append(z,1)
        else:
            z=np.append(z,0)
    return z

def checkvalue(checkedz,checkedvalue):
    ##This checks how valuable a given configuration is.
    wealthVector= np.dot(checkedz,checkedvalue)
    wealthsum= np.sum(wealthVector)
    return wealthsum

def McKnapsack(weights, values, iterations,sack): 
    z_start=getrandomz(len(weights))
    z=z_start
    moneyrecord=0.
    zrecord=np.array(["error if you see me"])
    failures=0.
    for x in xrange(iterations):
        current_z= np.array ([])
        current_z=flip_z(z)
        current_clone=current_z
        if (checkcompliance(current_clone,weights,sack))==True:
            z=current_clone
            if checkvalue(current_z,values)>moneyrecord:
                moneyrecord=checkvalue(current_clone,values)
                zrecord= current_clone
        else:failures+=1
    print "The winning knapsack configuration is %s" %(zrecord)
    print "The highest value of objects contained is %s" %(moneyrecord)

testvalues1=np.array([3,8,6])
testweights1= np.array([1,2,1])

McKnapsack(testweights1,testvalues1,60,2.)

应该发生的情况如下:最大承载能力为2,它应该在不同的潜在袋子承载配置之间随机切换,其中有2^3=8个以及我喂给它的测试重量和值,z 中的每个 1 或 0 表示具有或不具有给定的项目。它应该丢弃权重过大的选项,同时跟踪具有最高值和可接受权重的选项。正确答案是将 1,0,1 视为配置,将 9 视为最大值。每次当我使用中等大量的迭代时,我都会得到九个值,但配置似乎完全随机,并且以某种方式打破了权重规则。我已经用大量测试数组仔细检查了我的“checkcompliance”函数,它似乎有效。这些错误的、超重的配置是如何通过我的 if 语句并进入我的 zrecord 的?

最佳答案

诀窍是 z(因此还有 current_zzrecord)最终总是引用内存中完全相同的对象。 flip_z 通过 np.put 就地修改此对象。

一旦找到可以增加您的金钱记录的新组合,您就可以设置对它的引用 - 但随后在后续迭代中您可以继续更改同一引用处的数据。

换句话说,像这样的行

current_clone=current_z
zrecord= current_clone

不要复制,它们只会为内存中的相同数据创建另一个别名。

解决此问题的一种方法是在发现该组合获胜后显式复制该组合:

if checkvalue(current_z, values) > moneyrecord:
    moneyrecord = checkvalue(current_clone, values)
    zrecord = current_clone.copy()

关于python - 在 Python 中实现蒙特卡罗马尔可夫链时出现错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32577228/

相关文章:

python - Pandas:如何将 MultiIndex DataFrame 与单个索引 DataFrame 连接起来,以及自定义排序

python-2.7 - python 2.7 : Area opening and closing binary image in Python not so accurate

mysql - Python 2.7 + Django + MySQL-python错误

python - 在 iPython notebook 中调试的正确方法是什么?

numpy - 如何查找数组中的任何列是否有重复值

python - 找出哪些 PIP 模块真正在使用

python - 如何在Python中创建一个矩形矩阵?

python - 获取没有 XPath 的 WebElement 的兄弟元素 [Python/Selenium]

python-3.x - optimize.fmin_tnc 没有在 scipy.optimize 中给出正确的答案?

python-2.7 - DICT() 和 MATPLOTLIB?