python中的分配包装器
我是python新手,有简单LP问题的输出 在这个问题上,几个部分组成一个房子,几个部分组成一个社会。交付时有房屋和社会层面的目标。如果在任何级别均未达到交付要求,则将不良零件更换为交付50个单元的零件(更换=Y) 解决方案已优化,但我们没有替换的能力。 所以,我想优先考虑更换 我有能力做3次更换,解决方案是7次更换 我们是否可以根据优先级对解决方案进行后处理以获得3个替换 给定值=3个最大替换值 优先级=S3(社会3),H2,H1,S2 我的输出将是U、R和A的替换,而另一个保持不变?可以用python来做吗?或者这不能在python中完成(在这种情况下,我可以使用excel宏) 编辑python中的分配包装器,python,pandas,linear-programming,Python,Pandas,Linear Programming,我是python新手,有简单LP问题的输出 在这个问题上,几个部分组成一个房子,几个部分组成一个社会。交付时有房屋和社会层面的目标。如果在任何级别均未达到交付要求,则将不良零件更换为交付50个单元的零件(更换=Y) 解决方案已优化,但我们没有替换的能力。 所以,我想优先考虑更换 我有能力做3次更换,解决方案是7次更换 我们是否可以根据优先级对解决方案进行后处理以获得3个替换 给定值=3个最大替换值 优先级=S3(社会3),H2,H1,S2 我的输出将是U、R和A的替换,而另一个保持不变?可以用
Raw data:
data = [
{'Part': 'A', 'House': 'H1', 'Society': 'S1', 'Present_Delivery': 10, 'Replaced': 'Y'},
{'Part': 'B', 'House': 'H1', 'Society': 'S1', 'Present_Delivery': 30, 'Replaced': ''},
{'Part': 'C', 'House': 'H1', 'Society': 'S1', 'Present_Delivery': 40, 'Replaced': ''},
{'Part': 'D', 'House': 'H1', 'Society': 'S1', 'Present_Delivery': 50, 'Replaced': ''},
{'Part': 'E', 'House': 'H2', 'Society': 'S1', 'Present_Delivery': 50, 'Replaced': ''},
{'Part': 'F', 'House': 'H2', 'Society': 'S1', 'Present_Delivery': 50, 'Replaced': ''},
{'Part': 'G', 'House': 'H2', 'Society': 'S1', 'Present_Delivery': 50, 'Replaced': ''},
{'Part': 'H', 'House': 'H2', 'Society': 'S1', 'Present_Delivery': 50, 'Replaced': ''},
{'Part': 'I', 'House': 'H3', 'Society': 'S2', 'Present_Delivery': 30, 'Replaced': 'Y'},
{'Part': 'J', 'House': 'H3', 'Society': 'S2', 'Present_Delivery': 40, 'Replaced': ''},
{'Part': 'K', 'House': 'H3', 'Society': 'S2', 'Present_Delivery': 50, 'Replaced': ''},
{'Part': 'L', 'House': 'H4', 'Society': 'S2', 'Present_Delivery': 30, 'Replaced': 'Y'},
{'Part': 'M', 'House': 'H4', 'Society': 'S2', 'Present_Delivery': 30, 'Replaced': 'Y'},
{'Part': 'N', 'House': 'H4', 'Society': 'S2', 'Present_Delivery': 50, 'Replaced': ''},
{'Part': 'O', 'House': 'H5', 'Society': 'S2', 'Present_Delivery': 20, 'Replaced': 'Y'},
{'Part': 'P', 'House': 'H5', 'Society': 'S2', 'Present_Delivery': 50, 'Replaced': ''},
{'Part': 'Q', 'House': 'H5', 'Society': 'S2', 'Present_Delivery': 50, 'Replaced': ''},
{'Part': 'R', 'House': 'H6', 'Society': 'S3', 'Present_Delivery': 20, 'Replaced': 'Y'},
{'Part': 'S', 'House': 'H6', 'Society': 'S3', 'Present_Delivery': 40, 'Replaced': ''},
{'Part': 'T', 'House': 'H6', 'Society': 'S3', 'Present_Delivery': 50, 'Replaced': ''},
{'Part': 'U', 'House': 'H7', 'Society': 'S3', 'Present_Delivery': 15, 'Replaced': 'Y'},
{'Part': 'V', 'House': 'H7', 'Society': 'S3', 'Present_Delivery': 40, 'Replaced': ''},
{'Part': 'W', 'House': 'H7', 'Society': 'S3', 'Present_Delivery': 50, 'Replaced': ''},
]
house_targets = {'H1': 140,
'H2': 160,
'H3': 120,
'H4': 110,
'H5': 120,
'H6': 115,
'H7': 105,
}
society_targets = {'S1': 330,
'S2': 500,
'S3': 250}
df = pd.DataFrame(data)
for house, target in house_targets.items():
df.loc[df['House'] == house, 'House_Target'] = target
for society, target in society_targets.items():
df.loc[df['Society'] == society, 'Society_Target'] = target
replacement_value = 50
df.loc[df['Replaced'] == 'Y', 'replacement_value'] = replacement_value - df['Present_Delivery']
df['replacement_value'].fillna(0, inplace=True)
事实上,解决方案是直截了当的。您只需要按照给定的优先级对正确的列进行切片并对其进行排序。大部分代码只是包装器的锅炉板 包装纸
将熊猫作为pd导入
类替换约束:
定义初始化(self,df:pd.DataFrame,*,max_replacements:int,priority:list):
断言isinstance(df,pd.DataFrame)
self.df=df
self.max\u replacements=max\u replacements
self.priority=优先级
self.result=pd.DataFrame()
@静力学方法
def解析优先级(优先级):
“”“将优先级字符串映射到列”“”
col_map={'H':'House',
'S':'Society'}
返回col_映射[prio_str[0]]
def计算(自我):
“”“根据优先级对数据帧的切片进行排序并附加到self.result”“”
对于具有自优先权的prio:
col=自解析优先级(prio)
掩码=(self.df['Replaced']='Y')&(self.df[col]==prio)
结果\u tmp=self.df[mask]。排序\u值('replacement\u value',升序=False)
self.result=pd.concat([self.result,result\u tmp])
self.result=self.result.iloc[:self.max\u replacements]
给定一个数据帧df
(见下文),您可以将包装器用作:
wrapper=ReplacementConstraint(df,max_replacements=3,优先级=['S3'、'H2'、'H1'、'S2']))
wrapper.calculate()
打印(wrapper.result)
解决方案如下所示:
Part House Society ... House_Target Society_Target replacement_value
20 U H7 S3 ... 105.0 250.0 35.0
17 R H6 S3 ... 115.0 250.0 30.0
0 A H1 S1 ... 140.0 330.0 40.0
原始数据 数据帧数据的键入占用了我大部分时间。请考虑下一次发布文本而不是图片。我在这里发布它,这样如果其他人想发布另一个解决方案,她就不需要再次键入它。此外,通过发布数据帧,我的解决方案是
可能的改进
- 包装器不检查目标值。我认为这与第一次优化无关
- 结果数据帧不会更正传递的值。这没什么大不了的。我只是想提供一个简单的例子。您可以根据需要改进包装器
join
、combine\u first
和sort
来实现:
priority = ["S3", "H2", "H1", "S2"]
priority = pd.Series(range(len(priority)), index=priority, name="priority")
df["priority"] = df.join(priority, on="Society").priority.combine_first(df.join(priority, on="House").priority)
result = df[df.replacement_value > 0] .sort_values("priority").head(3)
print(result)
结果:
Part House Society Present_Delivery Replaced House_Target Society_Target replacement_value priority
17 R H6 S3 20 Y 115.0 250.0 30.0 0.0
20 U H7 S3 15 Y 105.0 250.0 35.0 0.0
0 A H1 S1 10 Y 140.0 330.0 40.0 2.0
我会将容量限制直接添加到LP/MIP问题中,而不是在事后试图捏造。这意味着模型没有反映问题,或者你对问题的理解不够详细。你可能会说……问题是一些约束条件不满足于容量约束条件,因此,选择或回避(正如你所说的)下游是很重要的……如何解决可能的改进
Part House Society Present_Delivery Replaced House_Target Society_Target replacement_value priority
17 R H6 S3 20 Y 115.0 250.0 30.0 0.0
20 U H7 S3 15 Y 105.0 250.0 35.0 0.0
0 A H1 S1 10 Y 140.0 330.0 40.0 2.0