import numpy as np
from typing import List, Dict, Tuple

import numpy as np

# 动态生成收益函数
def revenue_functions(num_projects):
    functions = []
    for i in range(num_projects):
        # 这里可以根据实际需求调整系数
        a = -0.1 - 0.05 * i  # 二次项系数,每次递减 0.05
        b = 2 + 0.5 * i  # 一次项系数,每次递增 0.5
        def r(x, a=a, b=b):
            return a * x**2 + b * x
        functions.append(r)
    return functions

def dpsa(num_projects, total_resource, num_iterations, step_size):
    # 初始化每个项目的资源分配为 0
    resource_allocation = [0] * num_projects
    revenue_funs = revenue_functions(num_projects)

    for _ in range(num_iterations):
        # 保存上一次的资源分配结果
        prev_allocation = resource_allocation.copy()

        for i in range(num_projects):
            # 计算当前项目的梯度(导数)
            gradient = (revenue_funs[i](resource_allocation[i] + step_size) - revenue_funs[i](resource_allocation[i])) / step_size

            # 更新资源分配
            resource_allocation[i] += gradient * step_size

            # 确保资源分配不超过总资源
            if sum(resource_allocation) > total_resource:
                # 调整资源分配以满足约束条件
                excess = sum(resource_allocation) - total_resource
                # 按比例减少每个项目的资源分配
                factor = (total_resource - sum(resource_allocation[:i])) / (sum(resource_allocation[i:]))
                for j in range(i, num_projects):
                    resource_allocation[j] *= factor

        # 判断是否收敛
        if np.linalg.norm(np.array(resource_allocation) - np.array(prev_allocation)) < 1e-6:
            break

    # 计算总收益
    total_revenue = sum(revenue_funs[i](resource_allocation[i]) for i in range(num_projects))

    return resource_allocation, total_revenue