用Python填充(或略多于)重复组件以获得最低值的背包问题
事实上,我正试图找到从小瓶中提供定制药物剂量的最低成本——然而,在研究过程中,我发现背包问题是描述这个问题的最佳方式,也是目前人们所理解的方式 问题分解 *根据临床需要开出剂量。 *然后考虑用于补充剂量(及其各自剂量)的市售小瓶。相同尺寸的小瓶可多次使用。 *小瓶/大小组合可能会提供过量(即,提供比所需剂量更高的剂量)-因为该组合比满足剂量本身或提供较小过量更便宜。因此,即使存在损耗,只要组合产生规定剂量,也允许过量或损耗。 *输出应显示使用的数量/瓶组合以及该组合的成本 例如,50毫克的药瓶价格为15美元,100毫克的药瓶价格为32美元,200毫克的药瓶价格为64美元 假设处方剂量为220mg。补充剂量的一些可能选项如下所示(请记住,损耗量并不相关,前提是它提供了补充所需剂量的最便宜选项用Python填充(或略多于)重复组件以获得最低值的背包问题,python,python-3.x,pandas,knapsack-problem,Python,Python 3.x,Pandas,Knapsack Problem,事实上,我正试图找到从小瓶中提供定制药物剂量的最低成本——然而,在研究过程中,我发现背包问题是描述这个问题的最佳方式,也是目前人们所理解的方式 问题分解 *根据临床需要开出剂量。 *然后考虑用于补充剂量(及其各自剂量)的市售小瓶。相同尺寸的小瓶可多次使用。 *小瓶/大小组合可能会提供过量(即,提供比所需剂量更高的剂量)-因为该组合比满足剂量本身或提供较小过量更便宜。因此,即使存在损耗,只要组合产生规定剂量,也允许过量或损耗。 *输出应显示使用的数量/瓶组合以及该组合的成本 例如,50毫克的药瓶价
5 x 50mg = 250mg (30mg over) = $75
3 x 50mg + 1 x 100mg = 250mg (30mg over) = $77
2 x 100mg + 1 x 200mg = 400mg (180mg over) = $128
1 x 50mg + 1 x 200mg = 250mg (30mg over) = $79
3 x 100mg = 300mg (80mg over) = $96
因此,我们可以看到最便宜的选择是row1 5x 50mg,价格为75美元
如果有人能给我指出正确的方向,我将不胜感激
下面的代码只使用每个组件一次,但我不知道如何修改它以使其循环使用
items = [("ITEM01", 100, 10000), ("ITEM02", 24, 576), \
("ITEM03", 24, 576), ("ITEM04", 51, 2500), ("ITEM05", 155, 25)]
S = sum([item[1] for item in items]) #sums all the weights in the list of items
dp = [None for i in range(S + 1)] #list within which cycles through each integer of weights creates a list of "None,"
dp[0] = [] #removes the first none from the list
for item in items: #for each element in the list of available vials
for i in range(S, -1, -1): #counts down from sum of all weights of available vial sizes DOWN TO zero (0)
if dp[i] is not None and i + item[1] <= S and \
( #if the long list of Nones - does not read None
dp[i + item[1]] is None
or
sum(set_item[2] for set_item in dp[i]) + item[2]
> sum(set_item[2] for set_item in dp[i + item[1]])
):
dp[i + item[1]] = dp[i] + [item]
desired_sum = 200 #desired weight
i = j = desired_sum # desired sum becomes i and it also becomes j
while i >= 0 and j <= S: #while desired sum(i) is over 0 and less then sum of weight of all vials in the list.
if dp[i] is not None: #if the none list entry at that point is NOT none
print (dp[i]) #print element from that list that isn't 'None'
break
elif dp[j] is not None: #if None list at desired_weight index is not None
print (dp[j]) #print the element that isn't none
break
else:
i -= 1 #else diverge i and j which are originally the same
j += 1
items=[(“ITEM01”,10010000),(“ITEM02”,24576)\
(“项目03”,24576),(“项目04”,512500),(“项目05”,155,25)]
S=总和([项目中项目的项目[1])#总和项目列表中的所有权重
dp=[None for i in range(S+1)]#列表,在该列表中,通过每个整数的权重循环创建一个“None”列表
dp[0]=[]#从列表中删除第一个
对于项目中的项目:#对于可用小瓶列表中的每个元素
对于范围(S,-1,-1)内的i:#从可用小瓶尺寸的所有重量之和向下计数到零(0)
如果dp[i]不是无,且i+项目[1]和(dp[i+项目[1]中的集合项目的集合项目[2])
):
dp[i+项目[1]]=dp[i]+[项目]
期望值总和=200#期望权重
i=j=desired_sum#desired sum变成i,它也变成j
在你的例子中,当i>=0和j时,我会假设50mg剂量总是赢的,因为它总是最便宜的。想象一下,100,2x15美元的剂量小于1x100毫克。现在我看不出除了50mg小瓶之外还有什么其他选择。我假设你需要一些额外的限制,例如,每个患者的最大药瓶数量是三瓶或类似的。Uwe-是的,这是正确的。5倍50mg会赢(在这种情况下)。我必须为27种不同的药物运行这个场景,其中一些药物有多达5种小瓶大小的组合。每个剂量的药瓶数量没有上限-这纯粹是基于最低成本(尽管浪费)!为了简单起见,这些只是整数。我有超过4000行的交易需要查看,这4000行由27种不同的药物组成。每种药物都有不同数量/大小的小瓶和不同的价格。价格并不总是像提供的示例那样线性。下面,除了最小的小瓶,每毫克的成本是线性的,比最小的小瓶多6美分。每毫克5000美元471.05(每毫克成本=0.09)1000美元94.21(每毫克成本=0.09)500美元47.11(每毫克成本=0.09)50美元4.71(每毫克成本=0.09)5美元4.82(每毫克成本=0.096)
同时检查一下它似乎给出了一个非常好的概述