Python 最小化成本

Python 最小化成本,python,sorting,Python,Sorting,有组和p项。每组为每个项目花费的成本在2D列表中给出。我想通过最小化成本和添加所有项目来解决这个问题 for effort in items: minE = min(minE , sum(effort)) row = len(items) col = len(items[0]) itemsEach = [] for i in range(col): minm = items[0][i] for j in range(1 , row): if items

有组和p项。每组为每个项目花费的成本在2D列表中给出。我想通过最小化成本和添加所有项目来解决这个问题

for effort in items:
    minE = min(minE , sum(effort))

row = len(items)
col = len(items[0])

itemsEach = []
for i in range(col):
    minm = items[0][i]
    for j in range(1 , row):
        if items[j][i] < minm:
            minm = items[j][i]
    itemsEach.append(minm)
minE = min(minE , sum(itemsEach))
print(minE)
对于项目中的工作:
我的=最小值(我的,总和(努力))
行=列(项目)
col=len(项目[0])
itemsEach=[]
对于范围内的i(列):
minm=项目[0][i]
对于范围内的j(第1行):
如果项目[j][i]
编辑:此答案适用于

这里有一种解决方法:

from functools import lru_cache


def min_cost(costs) -> int:
    num_doctors = len(costs)
    num_patients = len(costs[0])

    @lru_cache(None)
    def doctor_cost(doctor_index, patient_start, patient_end) -> int:
        if patient_start >= patient_end:
            return 0
        return costs[doctor_index][patient_start] + doctor_cost(
            doctor_index, patient_start + 1, patient_end
        )

    @lru_cache(None)
    def min_cost_(patient_index, available_doctors) -> float:
        if all(not available for available in available_doctors) or patient_index == num_patients:
            return float("+inf") if patient_index != num_patients else 0

        cost = float("+inf")
        available_doctors = list(available_doctors)
        for (doctor_index, is_doctor_available) in enumerate(available_doctors):
            if not is_doctor_available:
                continue

            available_doctors[doctor_index] = False
            for patients_to_treat in range(1, num_patients - patient_index + 1):
                cost_for_doctor = doctor_cost(
                    doctor_index, patient_index, patient_index + patients_to_treat
                )
                cost = min(
                    cost,
                    cost_for_doctor
                    + min_cost_(
                        patient_index + patients_to_treat, tuple(available_doctors)
                    ),
                )
            available_doctors[doctor_index] = True

        return cost

    return int(min_cost_(0, tuple(True for _ in range(num_doctors))))


assert min_cost([[2, 2, 2, 2], [3, 1, 2, 3]]) == 8
min\u cost\u
功能获取可用的患者索引和医生,并从该患者索引开始分配一名医生处理一名或多名患者(
patients\u to\u treat
)。此成本是当前医生处理这些患者的成本(
doctor\u cost
)+min\u cost(当前医生不可用的下一个患者索引)。然后,在所有可用的医生和医生可以治疗的患者数量上,成本最小化

因为会有重复的子问题,所以使用缓存(使用
lru\u缓存
decorator)来避免重新计算这些子问题

时间复杂性 设
M
=医生人数,
N
=患者人数

所有调用
doctor\u cost
的时间复杂度都是
O(M*N^2)
,因为这是可以形成的
(doctor\u索引、patient\u开始、patient\u结束)
元组的数量,而函数本身(递归调用除外)只做恒定的工作

时间复杂度
min\u cost
O((N*2^M)*(M*N))=O(2^M*M*N^2)
N*2^M
是可以形成的
(患者索引,可用医生)
对的数量,
M*N
是函数所做的工作(递归调用除外)<由于在计算
doctor\u cost
的时间紧迫性时,我们考虑了所有可能的调用
doctor\u cost
,因此这里可以将code>doctor\u cost视为O(1)

因此,总时间复杂度是
O(2^M*M*N^2)+O(M*N^2)=O(2^M*M*N^2)


考虑到原始问题的约束条件(Edit):此答案适用于

这里有一种解决方法:

from functools import lru_cache


def min_cost(costs) -> int:
    num_doctors = len(costs)
    num_patients = len(costs[0])

    @lru_cache(None)
    def doctor_cost(doctor_index, patient_start, patient_end) -> int:
        if patient_start >= patient_end:
            return 0
        return costs[doctor_index][patient_start] + doctor_cost(
            doctor_index, patient_start + 1, patient_end
        )

    @lru_cache(None)
    def min_cost_(patient_index, available_doctors) -> float:
        if all(not available for available in available_doctors) or patient_index == num_patients:
            return float("+inf") if patient_index != num_patients else 0

        cost = float("+inf")
        available_doctors = list(available_doctors)
        for (doctor_index, is_doctor_available) in enumerate(available_doctors):
            if not is_doctor_available:
                continue

            available_doctors[doctor_index] = False
            for patients_to_treat in range(1, num_patients - patient_index + 1):
                cost_for_doctor = doctor_cost(
                    doctor_index, patient_index, patient_index + patients_to_treat
                )
                cost = min(
                    cost,
                    cost_for_doctor
                    + min_cost_(
                        patient_index + patients_to_treat, tuple(available_doctors)
                    ),
                )
            available_doctors[doctor_index] = True

        return cost

    return int(min_cost_(0, tuple(True for _ in range(num_doctors))))


assert min_cost([[2, 2, 2, 2], [3, 1, 2, 3]]) == 8
min\u cost\u
功能获取患者索引和可用的医生,并从该患者索引开始分配医生处理一个或多个患者(
patients\u to\u treat
)。这是当前医生处理这些患者的成本(
doctor\u cost
)+min\u成本_(当前医生不可用时的下一个患者指数)。然后将所有可用医生和医生可以治疗的患者数量的成本降至最低

因为会有重复的子问题,所以使用缓存(使用
lru\u缓存
decorator)来避免重新计算这些子问题

时间复杂性 设
M
=医生人数,
N
=患者人数

所有调用
doctor\u cost
的时间复杂度都是
O(M*N^2)
,因为这是可以形成的
(doctor\u索引、patient\u开始、patient\u结束)
元组的数量,而函数本身(递归调用除外)只做恒定的工作

时间复杂度
min\u cost
O((N*2^M)*(M*N))=O(2^M*M*N^2)
N*2^M
是可以形成的
(患者索引,可用医生)
对,而
M*N
是函数(除了递归调用)所做的工作。
doctor\u cost
可以被认为是(1) 因为在计算
doctor\u cost
的时间紧迫性时,我们考虑了所有可能调用
doctor\u cost

因此,总时间复杂度是
O(2^M*M*N^2)+O(M*N^2)=O(2^M*M*N^2)


给定原始问题的约束条件(可能有多少医生和患者?这个问题是一个正在进行的竞赛的一部分。发布问题的人违反了行为准则。我要求主持人记录相关问题,不要进一步讨论。Techgig CodeGladiator半决赛第1轮。该问题一直持续到7月6日,供提交演示多个医生。)TOR和患者可以吗?这个问题是一个正在进行的竞赛的一部分。发布问题的人违反了行为准则。我要求主持人记录相关问题,不要进一步讨论。Techgig CodeGladiator半决赛第1轮。该问题在7月6日之前有效。提交我想如果我们关注疼痛根据我们的分区算法,时间复杂度将为O(2^n*n!*n^2)@chindiralasampathkumar我计算出时间复杂度为
O(2^M*M*n^2)
where
M=#doctors
N=#patients
。我在解决方案中添加了一个部分来解释。关于时间复杂性,我有一个疑问。它是2^M还是M!?。我编写代码只是为了调用AvailableDoctors方法,用于医生数量=10,它正在进行大约10万次调用。在您的回复中,
doctorsavable()
不是缓存的,而是在
@lru\u缓存(无)上方的Python代码中
decorator缓存函数调用的结果。如果我们考虑到这一点,最多只能调用
mincost
N*2^M
是的,你是对的。添加缓存调用后大大减少了。这对我来说是一个很好的学习。再次感谢你!我认为如果我们遵循painter的分区算法,那么时间复杂度将是O(2^n*n!*n^2)@chindiralasampathkumar我计算的时间复杂度为
O(2^M*M*n^2)
其中
M=#医生
n=#患者
。我在解决方案中添加了一节解释。关于时间复杂度,我有疑问。是否