import itertools
import os
import pandas as pd
def get_result(hope, list_input, used):
"""
:param hope: # 期望相加所得参数
:param list_input: # 所有数值
:param used: # 已使用过列表,起始数据为空
:return:
"""
def generate_combination(items, length):
for combination in itertools.combinations(items, length):
result_generate = list(combination)
# print(result)
yield result_generate
# 容差值,避免float计算过小
epsilon = 0.001
# 剔除大于目标值部分的列表内容不进行计算
larger_list = [i for i in list_input if i > hope]
step_1_list = list(set(list_input) - set(larger_list))
# 剔除已使用过数据
# print(used)
step_1_list = list(set(step_1_list) - set(used))
# 根据初步判断后的step_1_list,迭代每一种数据长度的可能性
result = []
for i in range(1, len(step_1_list) + 1):
# print('当前判断长度:' + str(i))
# 用迭代器 按照每种长度 生成每种可能
calculate = generate_combination(items=step_1_list, length=i)
# 循环迭代结果
for x in calculate:
# 对迭代器中每个元组求和
if abs(sum(x) - hope) <= epsilon:
result = x
used = x
# print('计算出', hope, ',组合是', result)
# 计算出结果,则该
break # 如果计算出结果,则终止对迭代结果循环
else:
# print('无结果')
continue # 未计算出结果,继续对迭代结果循环
break # if True 则终止对所有长度可能的循环
return hope, result, used
if __name__ == '__main__':
# 准备填数文件和基础参数
input_path = '数据求和匹配.xlsx'
output_path = '数据求和匹配结果.xlsx'
df_input = pd.DataFrame(columns=['求和标识', '求和列', '计算标识', '计算列'])
# 若不存在前期文件,则新建模板用于计算
if not os.path.exists(input_path):
df_input.to_excel(input_path, index=False)
os.system(input_path)
# 根据df_input取数list1 list2
df_input = pd.read_excel(input_path, dtype=str)
df_input.fillna(0, inplace=True)
list1 = df_input['计算列'].astype(float).tolist()
list2 = df_input['求和列'].astype(float).tolist()
print(sum(list1), sum(list2))
# 开始运行,used装填已使用过数据 新建df数据用于汇总全部数据
used = []
df_total = pd.DataFrame()
for i in list2:
if i != 0:
end = get_result(i, list1, used=used)
sus_hope = end[0] # 求和数据
sus_result = end[1] # 求和列表
print(sus_hope, '计算结果', sus_result)
sus_used = end[2] # 已使用数据
sus_used = used.extend(sus_used)
# 组合hope和resu为结果数据
df_division = pd.DataFrame(columns=['计算列'], data=sus_result)
df_division['求和列'] = sus_hope
df_total = pd.concat([df_division, df_total])
df_total['求和列'] = df_total['求和列'].astype(str)
df_total['计算列'] = df_total['计算列'].astype(str)
add_df = df_input[['求和列', '求和标识']]
df_total = pd.merge(df_total, add_df, on='求和列')
cal_df = df_input[['计算列', '计算标识']]
df_total = pd.merge(df_total, cal_df, on='计算列')
print(df_total)
df_result = pd.DataFrame(columns=['计算列', '计算标识', '求和标识', '求和列'])
df_result = pd.concat([df_result, df_total])
df_result.to_excel('result.xlsx', index=False)
os.system('result.xlsx')