开发喵星球

chatgpt实现层次分析法

chatgpt实现层次分析法

帮我用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 方法中,通常还需要进行一致性检查以确保用户提供的权重是一致的。

User

因素有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)

这段代码首先询问用户有哪些因素,并根据这些因素生成一个对应的判断矩阵。然后再像之前一样填充矩阵并计算权重。

User

因素选择的时候用,1到5数字表示,5更重要,1不重要

ChatGPT

了解你的要求,这实际上是简化了用户的输入,使其更加直观和简单。

为此,我们将对代码进行一些修改:

  1. 调整输入提示以接受 1 到 5 之间的整数。
  2. 使用这些整数值调整因素之间的权重比例。

以下是根据这些修改调整的代码:

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 的整数进行比较,然后计算和输出每个因素的权重。

User

将程序转化成web版,flask实现,选择的时候用单选框

ChatGPT

使用 Flask 和 HTML,我们可以创建一个简化的 Web 版本 AHP 工具。

首先,你需要确保你已经安装了 Flask。你可以使用以下命令安装:

Copy code
pip install Flask

以下是将上述程序转化为 Flask Web 版本的步骤:

  1. 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)
  1. 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>
  1. 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>
  1. 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/,你应该可以看到因子输入页面,之后进入因子比较页面,并最后看到权重结果页面。

User

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 函数传递到模板中,因此在模板中应该能够正常使用它了。

   
分类:数据结构和算法 作者:开发喵 发表于:2023-08-15 17:49:03 阅读量:114
<<   >>


powered by kaifamiao