帮我用python实现一个层次分析法,因素A,因素B,因素C。因素A、B、C要给出提示选择,A相对于B选哪个,B相对于C选哪个
ChatGPT
2 / 2
层次分析法 (Analytic Hierarchy Process, AHP) 是一种复杂的决策方法,它用于确定多因素决策中的优先级。以下是一个简化版本的实现,它仅考虑了因素 A、B 和 C,并提示用户为每对因素之间的关系提供权重。
pythonCopy code
import numpy as np
def get_input(prompt):
while True:
try:
value = float(input(prompt))
if 0 < value:
return value
else:
print("请输入一个大于0的值。")
except ValueError:
print("无效输入,请输入一个数字。")
def ahp():
factors = ["A", "B", "C"]
matrix = np.eye(3) # 创建3x3的单位矩阵
# 填充矩阵
for i in range(2):
for j in range(i+1, 3):
prompt = f"因素{factors[i]}相对于因素{factors[j]}的权重是多少?(>1表示{factors[i]}更重要, <1表示{factors[j]}更重要): "
weight = get_input(prompt)
matrix[i, j] = weight
matrix[j, i] = 1 / weight
# 计算特征向量和特征值
eigenvalues, eigenvectors = np.linalg.eig(matrix)
# 取最大的特征值对应的特征向量
principal_eigenvalue = np.max(eigenvalues)
principal_eigenvector = eigenvectors[:, np.argmax(eigenvalues)]
# 归一化特征向量
weights = principal_eigenvector / sum(principal_eigenvector)
# 打印结果
for factor, weight in zip(factors, weights):
print(f"因素{factor}的权重: {weight.real:.4f}")
if __name__ == "__main__":
ahp()
这段代码首先提示用户为因素之间的关系提供权重。然后,它使用这些权重构建层次分析法的判断矩阵,然后计算矩阵的主特征向量,该向量提供了因素的归一化权重。
请注意,此代码没有执行一致性检查,而在实际的 AHP 方法中,通常还需要进行一致性检查以确保用户提供的权重是一致的。
因素有N个
ChatGPT
对于 N 个因素的情况,我们可以扩展上述代码以处理任何数量的因素。以下是如何做到这一点的:
pythonCopy code
import numpy as np
def get_input(prompt):
while True:
try:
value = float(input(prompt))
if 0 < value:
return value
else:
print("请输入一个大于0的值。")
except ValueError:
print("无效输入,请输入一个数字。")
def ahp(factors):
n = len(factors)
matrix = np.eye(n)
for i in range(n - 1):
for j in range(i+1, n):
prompt = f"因素{factors[i]}相对于因素{factors[j]}的权重是多少?(>1表示{factors[i]}更重要, <1表示{factors[j]}更重要): "
weight = get_input(prompt)
matrix[i, j] = weight
matrix[j, i] = 1 / weight
# 计算特征向量和特征值
eigenvalues, eigenvectors = np.linalg.eig(matrix)
# 取最大的特征值对应的特征向量
principal_eigenvalue = np.max(eigenvalues)
principal_eigenvector = eigenvectors[:, np.argmax(eigenvalues)]
# 归一化特征向量
weights = principal_eigenvector / sum(principal_eigenvector)
# 打印结果
for factor, weight in zip(factors, weights):
print(f"因素{factor}的权重: {weight.real:.4f}")
if __name__ == "__main__":
factors = input("请输入所有的因素,以逗号分隔(例如: A,B,C,D,E): ").split(',')
ahp(factors)
这段代码首先询问用户有哪些因素,并根据这些因素生成一个对应的判断矩阵。然后再像之前一样填充矩阵并计算权重。
因素选择的时候用,1到5数字表示,5更重要,1不重要
ChatGPT
了解你的要求,这实际上是简化了用户的输入,使其更加直观和简单。
为此,我们将对代码进行一些修改:
以下是根据这些修改调整的代码:
pythonCopy code
import numpy as np
def get_input(prompt):
while True:
try:
value = int(input(prompt))
if 1 <= value <= 5:
return value
else:
print("请输入一个在1到5之间的整数。")
except ValueError:
print("无效输入,请输入一个整数。")
def ahp(factors):
n = len(factors)
matrix = np.eye(n)
for i in range(n - 1):
for j in range(i+1, n):
prompt = f"对比因素{factors[i]}和因素{factors[j]},哪个更重要?(1: {factors[j]}非常重要, 3: 两者相同, 5: {factors[i]}非常重要): "
weight_value = get_input(prompt)
if weight_value == 3:
weight = 1
elif weight_value < 3:
weight = 1 / (4 - weight_value)
else:
weight = weight_value - 2
matrix[i, j] = weight
matrix[j, i] = 1 / weight
# 计算特征向量和特征值
eigenvalues, eigenvectors = np.linalg.eig(matrix)
# 取最大的特征值对应的特征向量
principal_eigenvalue = np.max(eigenvalues)
principal_eigenvector = eigenvectors[:, np.argmax(eigenvalues)]
# 归一化特征向量
weights = principal_eigenvector / sum(principal_eigenvector)
# 打印结果
for factor, weight in zip(factors, weights):
print(f"因素{factor}的权重: {weight.real:.4f}")
if __name__ == "__main__":
factors = input("请输入所有的因素,以逗号分隔(例如: A,B,C,D,E): ").split(',')
ahp(factors)
现在,当你运行这个程序时,它会根据输入的因素提示你使用 1 到 5 的整数进行比较,然后计算和输出每个因素的权重。
将程序转化成web版,flask实现,选择的时候用单选框
ChatGPT
使用 Flask 和 HTML,我们可以创建一个简化的 Web 版本 AHP 工具。
首先,你需要确保你已经安装了 Flask。你可以使用以下命令安装:
Copy code
pip install Flask
以下是将上述程序转化为 Flask Web 版本的步骤:
app.py
: Flask 主程序文件pythonCopy code
from flask import Flask, render_template, request, redirect, url_for
import numpy as np
app = Flask(__name__)
@app.route("/", methods=["GET", "POST"])
def index():
if request.method == "POST":
factors = request.form.get("factors").split(',')
return redirect(url_for('compare', factors=",".join(factors)))
return render_template("index.html")
@app.route("/compare/<factors>", methods=["GET", "POST"])
def compare(factors):
factors = factors.split(',')
comparisons = [(i, j) for i in range(len(factors)) for j in range(i+1, len(factors))]
if request.method == "POST":
matrix = np.eye(len(factors))
for i, j in comparisons:
weight_value = int(request.form[f"{i}_{j}"])
if weight_value == 3:
weight = 1
elif weight_value < 3:
weight = 1 / (4 - weight_value)
else:
weight = weight_value - 2
matrix[i, j] = weight
matrix[j, i] = 1 / weight
eigenvalues, eigenvectors = np.linalg.eig(matrix)
principal_eigenvalue = np.max(eigenvalues)
principal_eigenvector = eigenvectors[:, np.argmax(eigenvalues)]
weights = principal_eigenvector / sum(principal_eigenvector)
return render_template("results.html", factors=factors, weights=weights)
return render_template("compare.html", factors=factors, comparisons=comparisons)
if __name__ == "__main__":
app.run(debug=True)
templates/index.html
: 输入因子页面htmlCopy code
<!DOCTYPE html>
<html>
<head>
<title>AHP Tool</title>
</head>
<body>
<h2>输入因子</h2>
<form action="/" method="post">
<input type="text" name="factors" placeholder="例如: A,B,C,D,E">
<input type="submit" value="下一步">
</form>
</body>
</html>
templates/compare.html
: 对比因子页面htmlCopy code
<!DOCTYPE html>
<html>
<head>
<title>比较因子</title>
</head>
<body>
<h2>比较因子</h2>
<form action="/compare/{{ ','.join(factors) }}" method="post">
{% for i, j in comparisons %}
<p>
对比因素{{ factors[i] }}和因素{{ factors[j] }},
<input type="radio" name="{{ i }}_{{ j }}" value="1"> 1
<input type="radio" name="{{ i }}_{{ j }}" value="2"> 2
<input type="radio" name="{{ i }}_{{ j }}" value="3" checked> 3
<input type="radio" name="{{ i }}_{{ j }}" value="4"> 4
<input type="radio" name="{{ i }}_{{ j }}" value="5"> 5
</p>
{% endfor %}
<input type="submit" value="计算权重">
</form>
</body>
</html>
templates/results.html
: 显示权重结果页面htmlCopy code
<!DOCTYPE html>
<html>
<head>
<title>权重结果</title>
</head>
<body>
<h2>权重结果</h2>
<ul>
{% for factor, weight in zip(factors, weights) %}
<li>因素{{ factor }}的权重: {{ weight.real|round(4) }}</li>
{% endfor %}
</ul>
<a href="/">返回开始</a>
</body>
</html>
运行 app.py
,然后访问 http://127.0.0.1:5000/
,你应该可以看到因子输入页面,之后进入因子比较页面,并最后看到权重结果页面。
jinja2.exceptions.UndefinedError: ‘zip’ is undefined
ChatGPT
错误信息表明 zip
在 Jinja2 模板中是未定义的。这是因为 Jinja2 模板环境默认并不包括所有的 Python 内置函数。要在模板中使用 zip
,我们需要显式地将它传递给模板。
为了解决这个问题,我们可以稍微修改我们的 Flask 代码来传递 zip
到模板环境中。
在你的 app.py
中,找到这行代码:
pythonCopy code
return render_template("results.html", factors=factors, weights=weights)
然后更改为:
pythonCopy code
return render_template("results.html", factors=factors, weights=weights, zip=zip)
这将 zip
函数传递到模板中,因此在模板中应该能够正常使用它了。
powered by kaifamiao