首页 > 编程语言 >运筹学练习Python精解——决策论

运筹学练习Python精解——决策论

时间:2024-06-16 13:11:34浏览次数:18  
标签:10 0.29 状态 Python print np 精解 stationary 运筹学

练习1

某地区有甲、乙、丙三家食品厂生产同一种食品,有一千个用户(或购货点),假定在研究期间无新用户加入也无老用户退出,只有用户的转移,已知 2006 年 5 月份有 500 户是甲厂的顾客;400 户是乙厂的顾客;100 户是丙厂的顾客。6 月份,甲厂有 400 户原来的顾客,上月的顾客有 50 户转乙厂,50 户转丙厂;乙厂有 300 户原来的顾客,上月的顾客有 20 户转甲厂,80 户转丙厂;丙厂有 80 户原来的顾客,上月的顾客有 10 户转甲厂,10 户转乙厂。计算其状态转移概率与平稳分布。
由题意得 6 月份顾客转移表,如下:

厂名 合计
400 50 50 500
20 300 80 400
10 10 80 100
合计 430 360 210 1000
import numpy as np

# 原始数据矩阵
data = np.array([
    [400, 50, 50],
    [20, 300, 80],
    [10, 10, 80]
])

# 每行的合计数
row_totals = np.array([500, 400, 100]).reshape(-1, 1)

# 将数据矩阵每行除以合计数,归一化处理为转移矩阵
P = data / row_totals

print("转移矩阵 P:")
print(np.round(P, 2))

# 计算平稳分布
eigvals, eigvecs = np.linalg.eig(P.T)
eigvec1 = eigvecs[:, np.isclose(eigvals, 1)]

# 将特征向量归一化以使其总和为1
stationary = eigvec1 / eigvec1.sum()
stationary = stationary.real.flatten()
stationary = np.round(stationary, 2)

print("\n平稳分布:")
print(stationary)
#[0.29 0.29 0.43]

练习2

计算机运行状态的预测。设一随机系统状态空间, 总共有4种状态, 记录观测系统所处状态如下:

\[\begin{array}{llllllllll} 4 & 3 & 2 & 1 & 4 & 3 & 1 & 1 & 2 & 3 \\ 2 & 1 & 2 & 3 & 4 & 4 & 3 & 3 & 1 & 1 \\ 1 & 3 & 3 & 2 & 1 & 2 & 2 & 2 & 4 & 4 \\ 2 & 3 & 2 & 3 & 1 & 1 & 2 & 4 & 3 & 1 \end{array} \]

若该系统可用马尔科夫模型描述, 且当前系统处于状态4 , 则下一步最可能是状态为何?

求解思路:

  • 求解一步转移概率: 从状态 \(i\) 到状态 \(j\) 的概率的估计值为

\[\hat{p}_{i j}=\frac{n_{i j}}{\sum_{j=1}^4 n_{i j}} \]

例如, 从状态1可以转移到状态 \(1 、 2 、 3 、 4\), 那么状态1转移到其他状态的总次数, 就是观测到的数据中, 出现 “ 11 ”" 12 ”"13" "14" 的总次数, 也就是公式中的分母。
从状态 \(i\) 到状态 \(j\) 的次数统计(不需要手算, 代码部分会讲)

1 2 3 4 $$\sum_{j=1}^4 n_{ij}$$
1 4 4 1 1 10
2 3 2 4 2 11
3 4 4 2 1 11
4 0 1 4 2 7
  • 求出一步转移矩阵:

\[P=\left[\begin{array}{cccc} 2 / 5 & 2 / 5 & 1 / 10 & 1 / 10 \\ 3 / 11 & 2 / 11 & 4 / 11 & 2 / 11 \\ 4 / 11 & 4 / 11 & 2 / 11 & 1 / 11 \\ 0 & 1 / 7 & 4 / 7 & 2 / 7 \end{array}\right] \]

其中第 \(i\) 行第 \(j\) 列的数, 代表着从状态 \(i\) 一步转移到状态 \(j\) 的概率的估计值。题目说当前状态为 4 , 则下一步的状态最有可能是3。

  • 则第 \(\mathrm{n}\) 步的状态的概率分布为:
    初始概率分布行向量(即初始时每种状态出现的概率)记做 \(P^{(0)}\), 一步转移概率矩阵记做 \(P\)。

\[P^{(n)}=P^{(0)} P^n \]

注意是把矩阵\(P\)乘 \(n\) 次。
系统初始化后运行到第2步的概率分布: \(P^{(2)}=P^{(0)} P^2=[0.291,0.289,0.271,0.149]\)
系统初始化后运行到第5步的概率分布: \(P^{(5)}=P^{(0)} P^5=[0.294,0.289,0.268,0.149]\)

  • 代码求解
    求一步转移矩阵:一般需要根据已知数据,求出一步转移矩阵的估计值;
    需要遍历已知数据,统计每一组相邻两个状态的数量(找出有多少个 "1 1",“12",..... );
    如果题目所定的系统状态是文字(例如张三的四种状态),那么在写代码时,可以自行定义不同状态对应的数字,给出一步转移概率和转移矩阵:

\[\hat{p}_{i j}=\frac{n_{i j}}{\sum_{j=1}^4 n_{i j}} \]

import numpy as np

# 原始数据矩阵(去掉最后一列)
data = np.array([
    [4, 4, 1, 1],
    [3, 2, 4, 2],
    [4, 4, 2, 1],
    [0, 1, 4, 2]
])

# 计算每行的总和
sums = data.sum(axis=1)

# 计算状态转移矩阵 P
P = data / sums[:, None]

print("状态转移矩阵P:")
print(np.round(P, 2))

# 计算 P 的 2 次方
P2 = np.linalg.matrix_power(P, 2)
print("\nP 的 2 次方:")
print(np.round(P2, 2))

# 计算 P 的 5 次方
P5 = np.linalg.matrix_power(P, 5)
print("\nP 的 5 次方:")
print(np.round(P5, 2))

# 计算平稳分布
eigvals, eigvecs = np.linalg.eig(P.T)
eigvec1 = eigvecs[:, np.isclose(eigvals, 1)]

# 将特征向量归一化以使其总和为1
stationary = eigvec1 / eigvec1.sum()
stationary = stationary.real.flatten()
stationary = np.round(stationary, 2)

print("\n平稳分布:")
print(stationary)
P 的 5 次方:
[[0.29 0.29 0.27 0.15]
 [0.29 0.29 0.27 0.15]
 [0.29 0.29 0.27 0.15]
 [0.29 0.29 0.27 0.15]]

平稳分布:
[0.29 0.29 0.27 0.15]

练习3

考虑中国移动,中国联通和中国电信三家运营商,他们的用户可以互相携号转网,已经当前3家运营商的市场份额,而且也能测试出用户转网的可能性,那么将来3家运营商的市场份额情况如何,即利用当前已知的两项数据,分别是当前的市场份额、用户接下来使用运营商的可能性(即转移概率矩阵),则可预测将来3家运营商的市场份额情况。当前3家运营商分别的市场占比为0.55,0.25和0.2,但是有携号转网政策后,用户可自由的切换运营商,当前从调查数据中可得到,移动用户预期下年还会使用移动的比例是80%,使用电信的比例是15%,联通的比例是5%。电信用户接下来会使用移动的比例是20%,继续使用电信的比例是78%,使用联通的比例是2%。联通用户接下来使用移动的比例是5%,电信为20%,继续使用联通的比例是75%。现希望预期后续比如10年后,3家运营商的市场份额情况如何。


import numpy as np

# 初始市场份额
initial_distribution = np.array([0.55, 0.25, 0.2])

# 状态转移矩阵
P = np.array([
    [0.80, 0.15, 0.05],
    [0.20, 0.78, 0.02],
    [0.05, 0.20, 0.75]
])

# 计算10年后的市场份额分布
distribution_10_years = initial_distribution.dot(np.linalg.matrix_power(P, 10))

# 状态名
states = ["移动", "电信", "联通"]

print("10年后的市场份额分布:")
for state, share in zip(states, np.round(distribution_10_years, 2)):
    print(f"{state}: {share}")

# 计算平稳分布
eigvals, eigvecs = np.linalg.eig(P.T)
eigvec1 = eigvecs[:, np.isclose(eigvals, 1)]

# 将特征向量归一化以使其总和为1
stationary = eigvec1 / eigvec1.sum()
stationary = stationary.real.flatten()
stationary = np.round(stationary, 2)

print("\n平稳分布:")
for state, share in zip(states, stationary):
    print(f"{state}: {share}")

10年后的市场份额分布:
移动: 0.45
电信: 0.42
联通: 0.13

平稳分布:
移动: 0.45
电信: 0.42
联通: 0.12

标签:10,0.29,状态,Python,print,np,精解,stationary,运筹学
From: https://www.cnblogs.com/haohai9309/p/18242644

相关文章

  • (高清pdf集合)图灵程序设计丛书:大规模数据处理入门与实战(套装全10册)【图灵出品!一套囊括S
    书:pan.baidu.com/s/1tIHXj9HmIYojAHqje09DTA?pwd=jqso提取码:jqso数据处理基础:介绍数据处理的基本概念、流程和应用场景,帮助读者建立对数据处理的整体认识。SQL语言与应用:详细讲解SQL的语法和用法,包括数据查询、数据操作和数据定义等,以及在实际应用中的最佳实践。Python数据挖......
  • MATLAB算法实战应用案例精讲-【数模应用】事后多重比较(附python、MATLAB和R语言代码实
    目录几个高频面试题目事后检验,多重比较,简单效应分析有什么区别?事后多重对比如何使用?算法原理SPSSAU疑难解惑提示‘数据质量异常’如何解决?如何做Dunnett法事后多重比较?方差分析事后多重比较提供‘字母标记法!’?关于方差分析时的效应量?字母标记法时没有输出结果?......
  • Demo | 利用机器学习构建作物模型的Python源码
    作物模型提出很早,但应用有限。看起来复杂,其实解决的是环境与表型间的关联,可参考前期推文:作物生长模型CropGrow。环境组的复杂,关键在于数据的准确性获取。对于数据分析人员来说,如果不care数据准确性,分析其实很简单的,就是经典的机器学习流程。这里提供一段伪代码仅供参考。1.导库......
  • Python爬虫案例:从某居网爬取房源信息
    网站链接:sjz.anjuke.com目标数据:位置、面积、价格、房源链接约束条件:房产价格在80-140w首先在浏览器上输入网址,通过鼠标右键-“检查”来确定各网页元素在html源代码中的位置和构成​通过检查导航的价格索引,找出了80-140w的房源信息的网页链接,url依次以13-15结尾并且其它数......
  • 批量异步上传aws图片脚本(python)
    背景工作中需要上传一些测试图片,于是网上找找资料(官方说明),前置步骤如下。python需要3.8以上,安装最新的boto3库:pipinstallboto3有一个S3权限的aws账户,得到访问密钥ACCESS_KEY与SECRET_KEY,以及上传图片的存储桶位置安装异步编程asyncio,aiohttp库,方便本地异步上传图片代码......
  • python学习 - 对目录操作和对文件操作的 实例代码
    #!/usr/bin/python#-*-coding:UTF-8-*-importosimportos,shutilclassOperatingFile:defcreatFile(self,path):f=file(path,"w+")f.close()defreadFile(self,path):#方法一f=open("E:/aa......
  • python学习 - for循环 各种使用技巧 案例代码
    #!/usr/bin/python#-*-coding:UTF-8-*-forletterin'Python':#第一个实例print'当前字母:',letterfruits=['banana','apple','mango']forfruitinfruits:#第二个实例print'当前水果:',fr......
  • python学习 - 对list列表的操作 实例代码
    #!/usr/bin/evnpython#-*-encoding:utf-8-*-list=[1,4,3,3,"A","B","c","A"]#增加list.append("AA")#像末尾增加一个新元素list.insert(1,"B")#像指定索引位置插入元素list.extend(["D","DD"])#新......
  • python学习 - 读取xls文件的操作案例代码
    #!/usr/bin/evnpython#-*-encoding:utf-8-*-importxlrdimportxlwtimportxlutils.copyclassExcels:defcreateExcel(self):workbook=xlwt.Workbook()sheet=workbook.add_sheet(u"sheet页名称",cell_overwrite_ok=True)......
  • python学习 - 操作redis数据库常用指令 案例
    #-*-coding:UTF-8-*-importredisimporttimeclassTestRedis:def__init__(self):self.dbconn=NonedefopenRedis(self):#连接redis,加上decode_responses=True,写入的键值对中的value为str类型,不加这个参数写入的则为字节类型。......