from__future__importprint_functionimporttimefromortools.linear_solverimportpywraplpimportnumpyasnpimportpandasaspddefget_data(date=20200301):
data_3=pd.read_csv('forecast_20200829.csv') data_3['date_str']=data_3['date_str'].apply(lambdax:int(str(x).replace('-','')))
data_3['pai_num'] =data_3['pai_num'].apply(lambdax: round(x))
data_3['shou_num'] =data_3['shou_num'].apply(lambdax:round(x))
print(data_3)
print(str(date))
data_tmp=data_3[data_3['date_str']==date]
print(data_tmp)
data_tmp.index=data_tmp['zone_id']
li=list(data_tmp.index)
li=sorted(li, key=lambdax: int(x.split('_')[1]))
data_tmp=data_tmp.apply(li)
sizes_shou=list(data_tmp['shou_num'])
sizes_pai=list(data_tmp['pai_num'])
data_6=pd.read_csv('worker.csv',usecols=['小哥id', '收件能力', '派件能力', '保底收入', '收件成本',
'派件成本']) worker_max_shou=list(data_6['收件能力'])
worker_max_pai=list(data_6['派件能力'])
worker_min_wage=list(data_6['保底收入'])
worker_cost_shou=list(data_6['收件成本'])
worker_cost_pai=list(data_6['派件成本'])
cost_shou=np.array([int(i) foriinworker_cost_shou] *len(sizes_shou)).reshape(-1, len(worker_cost_shou)).T.tolist()
cost_pai=np.array([int(i) foriinworker_cost_pai] *len(sizes_pai)).reshape(-1, len(worker_cost_pai)).T.tolist()
returncost_shou,cost_pai,sizes_shou,sizes_pai,worker_max_shou,worker_max_pai,worker_min_wagedefprint_score(file_path,sizes_shou,worker_max_shou,sizes_pai,worker_max_pai,worker_min_wage):
data=pd.read_csv(file_path)
data=data.sort_values(by=['task'])
worker_list=data['Worker'].tolist()
task_list=data['task'].tolist()
print('----------目标函数测试---------------')
print('任务:', task_list)
print('工人:', worker_list)
shou_requirement= {}
shou_provide= {}
pai_requirement= {}
pai_provide= {}
fort,winzip(task_list,worker_list):
iftnotinshou_requirement:
shou_requirement[t] =sizes_shou[t]
shou_provide[t] =shou_provide.get(t, 0) +worker_max_shou[w]
iftnotinpai_requirement:
pai_requirement[t] =sizes_pai[t]
pai_provide[t] =pai_provide.get(t, 0) +worker_max_pai[w]
print('收件任务需求',(sum(list(shou_requirement.values())),len(list(shou_requirement.values()))))
print(list(shou_requirement.values()))
print('收件任务分配:', (sum(list(shou_provide.values())),len(list(shou_provide.values()))))
print( list(shou_provide.values()))
print('派件任务需求:', (sum(list(pai_requirement.values())),len(list(pai_requirement.values()))))
print( list(pai_requirement.values()))
print('派件任务分配:', (sum(list(pai_provide.values())),len(list(pai_provide.values()))))
print(list(pai_provide.values()))
cast1=[]
cast2= []
cast3= []
cast4= []
fortinlist(set(task_list)):
cast1.append( min(shou_requirement[t], shou_provide[t]))
shou_err=shou_requirement[t] -shou_provide[t]
ifshou_err>0:
cast3.append(18*shou_err)
print('收件件任务分配的员工成本:', (sum(cast1),len(cast1)))
print(cast1)
fortinlist(set(task_list)):
cast1.append( min(pai_requirement[t], pai_provide[t]))
pai_err=pai_requirement[t] -pai_provide[t]
ifpai_err>0:
cast4.append( 12*pai_err)
print('派件件任务分配的员工成本:', (sum(cast1),len(cast1)))
print(cast1)
print('收件溢出成本:', (sum(cast3), len(cast3)))
print(cast3)
print('派件溢出成本:', (sum(cast4), len(cast4)))
print(cast4)
forwinlist(set(worker_list)):
cast2.append(worker_min_wage[w])
cast1_sum=sum(cast1)
cast2_sum=sum(cast2)
cast3_sum=sum(cast3)
cast4_sum=sum(cast4)
cast=cast1_sum+cast2_sum+cast3_sum+cast4_sumprint('cast1_sum:', cast1_sum)
print('cast2_sum:', cast2_sum)
print('cast3_sum:', cast3_sum)
print('cast4_sum:', cast4_sum)
print('cast:',cast)
print('cast1:', cast1)
print('cast2:', cast2)
print('cast3:', cast3)
print('cast4:', cast4)
defmain(date_tag):
solver=pywraplp.Solver('SolveAssignmentProblem',
pywraplp.Solver.SCIP_MIXED_INTEGER_PROGRAMMING)
start=time.time()
cost_shou= [[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1]]
sizes_shou= [10, 4, 8, 6, 7, 12, 5, 11]
worker_max_shou= [20, 23, 8, 17, 12, 5, 7, 9, 12, 14]
cost_pai= [[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1]]
sizes_pai= [10, 4, 8, 6, 7, 12, 5, 11]
worker_max_pai= [20, 23, 8, 17, 12, 5, 7, 9, 12, 14]
worker_min_wage= [10, 15, 5, 1, 14, 12, 8, 7, 13, 11]
cost_shou,cost_pai,sizes_shou,sizes_pai,worker_max_shou,worker_max_pai,worker_min_wage=get_data(date=date_tag)
print(cost_shou)
print(cost_pai)
print(sizes_shou)
print(sizes_pai)
print(worker_max_shou)
print(worker_max_pai)
print(worker_min_wage)
num_workers=len(cost_shou)
num_tasks=len(cost_shou[1])
x_shou= []
foriinrange(num_workers):
t= []
forjinrange(num_tasks):
t.append(solver.IntVar(0, 1, "shou[%i,%i]"% (i, j)))
x_shou.append(t)
x_pai= []
foriinrange(num_workers):
t= []
forjinrange(num_tasks):
t.append(solver.IntVar(0, 1, "pai[%i,%i]"% (i, j)))
x_pai.append(t)
[solver.Add(sum(x_shou[i][j] foriinrange(num_workers)) >=1)
forjinrange(num_tasks)]
[solver.Add(sum(x_pai[i][j] foriinrange(num_workers)) >=1)
forjinrange(num_tasks)]
[solver.Add(sum(x_shou[i][j] forjinrange(num_tasks)) <=1) foriinrange(num_workers)]
[solver.Add(sum(x_pai[i][j] forjinrange(num_tasks)) <=1) foriinrange(num_workers)]
[solver.Add((x_pai[i][j] -x_shou[i][j] ==0)) forjinrange(num_tasks) foriinrange(num_workers)]
compare_task1= []
forjinrange(num_tasks):
compare_task1.append([])
compare_task1[j].append(solver.IntVar(0, solver.infinity(), "sizes_shou_[%i]"% (j)))
compare_task1[j].append(solver.IntVar(0, solver.infinity(), "worker_max_shou_[%i]"% (j)))
solver.Add(compare_task1[j][0] ==sizes_shou[j])
solver.Add(compare_task1[j][1]==sum([worker_max_shou[i]*sum([x_shou[i][j]]) foriinrange(num_workers)]))
target1= []
forjinrange(num_tasks):
target1.append(solver.IntVar(0, solver.infinity(), "target1[%i]"% (j)))
forjinrange(num_tasks):
solver.Add(compare_task1[j][1] >=sizes_shou[j])
forjinrange(num_tasks):
solver.Add(target1[j] ==sizes_shou[j])
compare_task2= []
forjinrange(num_tasks):
compare_task2.append([])
compare_task2[j].append(solver.IntVar(0, solver.infinity(), "sizes_pai_[%i]"% (j)))
compare_task2[j].append(solver.IntVar(0, solver.infinity(), "worker_max_pai_[%i]"% (j)))
solver.Add(compare_task2[j][0] ==sizes_pai[j])
solver.Add(
compare_task2[j][1] ==sum([worker_max_pai[i] *sum([x_pai[i][j]]) foriinrange(num_workers)]))
target2= []
forjinrange(num_tasks):
target2.append(solver.IntVar(0, solver.infinity(), "target2[%i]"% (j)))
forjinrange(num_tasks):
solver.Add(compare_task2[j][1] >=sizes_pai[j])
forjinrange(num_tasks):
solver.Add(target2[j] ==sizes_pai[j])
target3= []
forjinrange(num_tasks):
target3.append(solver.IntVar(-solver.infinity(), solver.infinity(), "target3[%i]"% (j)))
forjinrange(num_tasks):
solver.Add(target3[j] == (18* (sizes_shou[j] -compare_task1[j][1])))
target4= []
forjinrange(num_tasks):
target4.append(solver.IntVar(-solver.infinity(), solver.infinity(), "target4[%i]"% (j)))
forjinrange(num_tasks):
solver.Add(target4[j] ==12* (sizes_pai[j] -compare_task2[j][1]))
cast1=sum(target1) +sum(target2)
cast3=sum(target3)
cast4=sum(target4)
cast2=sum([sum([np.dot(worker_min_wage[i], x_shou[i][j]) foriinrange(num_workers)]) forjinrange(num_tasks)])
solver.Minimize(
cast1+cast2+cast3+cast4)
status=solver.Solve()
plain={}
forjinrange(num_tasks):
plain[j]=[x_shou[i][j].solution_value() foriinrange(num_workers)]
print('任务分配人工:')
print([vfork,vinplain.items()])
print( [[indexforindex,iinenumerate(v) if (i==1) ] fork,vinplain.items()])
shou_task2= {}
pai_task2= {}
forjinrange(num_tasks):
shou_task2[j] =solver.Sum(
[worker_max_shou[i] *x_shou[i][j].solution_value() foriinrange(num_workers)]).solution_value()
print('收件任务需求:', (sum(sizes_shou), len(sizes_shou)))
print(sizes_shou)
print('收件任务分配:', (sum(list(shou_task2.values())), len(list(shou_task2.values()))))
print(list(shou_task2.values()))
forjinrange(num_tasks):
pai_task2[j] =solver.Sum([worker_max_pai[i] *x_pai[i][j] foriinrange(num_workers)]).solution_value()
print('派件任务需求:', (sum(sizes_pai), len(sizes_pai)))
print(sizes_pai)
print('派件任务分配:', (sum(list(pai_task2.values())), len(list(pai_task2.values()))))
print(list(pai_task2.values()))
print('【status】:',status)
ifstatus==solver.OPTIMAL :
print('Minimum cost = %i'%solver.Objective().Value())
print()
result= {'date':[],'Worker': [], 'task': [],'cast1': [], 'cast2': [],'cast3': [], 'cast4': []}
foriinrange(num_workers):
forjinrange(num_tasks):
ifx_shou[i][j].solution_value() ==1:
result['date'].append(date_tag)
result['Worker'].append(i)
result['task'].append(j)
result['cast1'].append(cast1.solution_value())
result['cast2'].append(cast2.solution_value())
result['cast3'].append(cast3.solution_value())
result['cast4'].append(cast4.solution_value())
print('Worker ', i, ' assigned to shou_task ', j, ' Cost1 = ', cost_shou[i][j], ' Cost2 = ',
worker_min_wage[i])
print()
end=time.time()
print("Time = ", round(end-start, 4), "seconds")
data=pd.DataFrame(result)
data.to_csv('best_policy.csv', index=None)
print('model_cast1:', cast1.solution_value())
print('model_cast2:', cast2.solution_value())
print('model_cast3:', cast3.solution_value())
print('model_cast4:', cast4.solution_value())
print_score('best_policy.csv', sizes_shou, worker_max_shou, sizes_pai, worker_max_pai, worker_min_wage)
returncost_shou,cost_pai,sizes_shou,sizes_pai,worker_max_shou,worker_max_pai,worker_min_wagedefouput_result(path='best_policy.csv'):
data=pd.read_csv('best_policy.csv')
result= {}
fordindata.iterrows():
dd=d[1]
time=str(dd['date'])
time=time[:4] +'-'+time[4:6] +'-'+time[6:-2]
zone='zone_'+str(dd['task'])[:-2]
worker='id_'+str(dd['Worker'])[:-2]
result[time] =result.get(time, {})
result[time][zone] =result[time].get(zone, [])
result[time][zone].append(worker)
result_str=json.dumps(result).replace('{', '{\n').replace('],', '],\n').replace('},', '},\n').replace('}', '}\n')
print(result_str)
withopen('result_str.txt', 'w') asf:
f.write(result_str)
returnresultdefcreate_data_model():
"""Create the data for the example."""data= {}
shou= [49, 9, 42, 36, 36, 48, 42, 42, 36]
pai= [15, 30, 25, 50, 35, 30, 15, 40, 30]
chengben= [10, 30, 2, 5, 3, 30, 15, 4, 30]
data['shou'] =shoudata['pai'] =paidata['chengben'] =chengbendata['items'] =list(range(len(shou)))
data['num_items'] =len(shou)
num_bins=1data['bins'] =list(range(num_bins))
data['bin_capacities'] = [100, 150]
returndatadefpackbag(data):
solver=pywraplp.Solver.CreateSolver('CBC')
x= {}
foriindata['items']:
forjindata['bins']:
x[(i, j)] =solver.IntVar(0, 1, 'x_%i_%i'% (i, j))
forjindata['bins']:
solver.Add(sum(x[(i, j)] *data['shou'][i]
foriindata['items']) >=1*data['bin_capacities'][0])
solver.Add(sum(x[(i, j)] *data['pai'][i]
foriindata['items']) >=1*data['bin_capacities'][1])
objective=solver.Objective()
foriindata['items']:
forjindata['bins']:
objective.SetCoefficient(x[(i, j)], data['chengben'][i])
objective.SetMinimization()
status=solver.Solve()
leave_worker=[]
ifstatus==pywraplp.Solver.OPTIMAL:
total_cast=0forjindata['bins']:
shou_list=0pai_list=0bin_chengben=0foriindata['items']:
ifx[i, j].solution_value() >0:
leave_worker.append(i)
shou_list+=data['shou'][i]
pai_list+=data['pai'][i]
bin_chengben+=data['chengben'][i]
bin_shou=data['bin_capacities'][0]
bin_pai=data['bin_capacities'][1]
print()
print('供大于求:',(shou_list+pai_list,bin_shou+bin_pai,shou_list-bin_shou+pai_list-bin_pai,(shou_list-bin_shou+pai_list-bin_pai)/(bin_shou+bin_pai)))
print('供大于求:',(shou_list,bin_shou,shou_list-bin_shou,(shou_list-bin_shou)/(bin_shou)))
print('供大于求:',(pai_list,bin_pai,pai_list-bin_pai,(pai_list-bin_pai)/(bin_pai)) )
total_cast+=bin_shou+bin_pai+bin_chengbenelse:
print('The problem does not have an optimal solution.')
returnleave_worker,total_cast,bin_shou,bin_pai,bin_chengbendefclear_task(task_id,worker_list,data2):
"""Create the data for the example."""data= {}
shou= [data2['worker_max_shou'][i] foriinworker_list]
pai= [data2['worker_max_pai'][i] foriinworker_list]
chengben= [data2['worker_min_wage'][i] foriinworker_list]
print('【task_id】:',task_id)
data['sizes_shou']=data2['sizes_shou']
data['sizes_pai'] =data2['sizes_pai']
data['shou'] =shoudata['pai'] =paidata['chengben'] =chengbendata['items'] =list(range(len(shou)))
data['num_items'] =len(shou)
num_bins=1data['bins'] =list(range(num_bins))
data['bin_capacities'] = [data2['sizes_shou'][task_id],data2['sizes_pai'][task_id]]
leave_worker,new_cast,bin_shou,bin_pai,bin_chengben=packbag(data)
leave_worker=['id_'+str(worker_list[i]) foriinleave_worker]
returnleave_worker,new_cast,bin_shou,bin_pai,bin_chengbendefclear_result(result,sizes_shou,sizes_pai,worker_max_shou,worker_max_pai,worker_min_wage):
"""Create the data for the example."""data={}
data['sizes_shou']=sizes_shoudata['sizes_pai'] =sizes_paidata['worker_max_shou'] =worker_max_shoudata['worker_max_pai'] =worker_max_paidata['worker_min_wage'] =worker_min_wagenew_result={}
new_cast=[]
new_bin_shou=[]
new_bin_pai=[]
new_bin_chengben=[]
fortime,policyinresult.items():
new_result[time]={}
fortask_id ,worker_listinpolicy.items():
task_id_tmp=int(task_id.split('_')[1])
worker_list_tmp=[int(i.split('_')[1]) foriinworker_list]
new_result[time][task_id],cast_,bin_shou,bin_pai,bin_chengben=clear_task(task_id_tmp, worker_list_tmp,data)
new_cast.append(cast_)
new_bin_shou.append(bin_shou)
new_bin_pai.append(bin_pai)
new_bin_chengben.append(bin_chengben)
fortask_idinrange(30):
id='zone_'+str(task_id)
ifidinresult[time]:
new_result[time][id]=result[time][id]
returnnew_result,new_cast,new_bin_shou,new_bin_pai,new_bin_chengbendefmake_commit(date_tag=20200511):
print('背包调整....')
cost_shou= [[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1]]
sizes_shou= [10, 4, 8, 6, 7, 12, 5, 11]
worker_max_shou= [20, 23, 8, 17, 12, 5, 7, 9, 12, 14]
cost_pai= [[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1]]
sizes_pai= [10, 4, 8, 6, 7, 12, 5, 11]
worker_max_pai= [20, 23, 8, 17, 12, 5, 7, 9, 12, 14]
worker_min_wage= [10, 15, 5, 1, 14, 12, 8, 7, 13, 11]
cost_shou, cost_pai, sizes_shou, sizes_pai, worker_max_shou, worker_max_pai, worker_min_wage=get_data(
date=date_tag)
main(date_tag)
result=ouput_result()
print(result)
print('----------------------------')
result, cast, bin_shou, bin_pai, bin_chengben=clear_result(result, sizes_shou, sizes_pai, worker_max_shou,
worker_max_pai, worker_min_wage)
result_str=json.dumps(result).replace('{', '{\n').replace('],', '],\n').replace('},', '},\n').replace('}', '}\n')
print(result_str)
withopen('sche_{0}.json'.format(date_tag), 'w') asf:
f.write(result_str)
print('更新之后cast:', sum(cast))
print('new_cast1:', sum(bin_shou) +sum(bin_pai))
print('bin_shou:', sum(bin_shou))
print('bin_pai:', sum(bin_pai))
print('new_cast2:', sum(bin_chengben))
returnresult,sum(cast)
importjsonif__name__=='__main__':
limit=[20200829,20200830,20200831]
results={}
casts=[]
forlinlimit:
r,c=make_commit(l)
results.update(r)
casts.append(c)
print(casts)
result_str=json.dumps(results).replace('{', '{\n').replace('],', '],\n').replace('},', '},\n').replace('}', '}\n')
print(result_str)
withopen('out/sche.json', 'w') asf:
f.write(result_str)
shell_code='python calc_score.py -w worker.csv -d out -dates 'fortinlimit:
shell_code+=str(t)[:4] +'-'+str(t)[4:6] +'-'+str(t)[6:]+' 'print(shell_code)