本人没参加比赛,主要嫌写论文麻烦,本身代码就能表现算法和结果,并用于评分,硬是要一篇论文,不明其意义所在,语言使用python,其处理数据比较方便。matlib?不明白它的优势在哪,好像数学建模就一定要使用一样,难道只是为了方便抄代码?我瞎说哦,别当真。R?这需要专门写一篇文章,以后再说。我没有乱套随机算法,所以最后结果是稳定的,第一问得到67批次,第二问得到78713的总距离,第三问得到36923的总时间,下面都是比赛期间写的,不想再继续优化了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# 读取数据
import pandas as pd
data = pd.read_csv("附件1:订单信息.csv")

# 预处理
def stringToNum(x):
return int(x[1:])
OrderNo = list(map(stringToNum, data["OrderNo"]))
ItemNo = list(map(stringToNum, data["ItemNo"]))
OrderObject = []
index = 0
for i in range(0, 20340):
if OrderNo[i] > index:
OrderObject.append([])
index += 1
OrderObject[index-1].append(ItemNo[i])

# 第一题
# 生成排列索引,越相似订单靠的越进
OrderLen = []
for k,v in enumerate(OrderObject):
OrderLen.append([k, len(v)])
OrderLen.sort(key=lambda item:item[1], reverse=True)
def getFitness(i, j):
item1 = OrderObject[OrderLen[i][0]]
item2 = OrderObject[OrderLen[j][0]]
tmp = set(item1)
tmp.update(item2)
return 1-(len(tmp)-len(item1))/len(item2)
for i in range(len(OrderLen)-1):
maxfitindex = i+1
maxfit = 0
for j in range(i+1, len(OrderLen)):
fitness = getFitness(i, j)
if fitness > maxfit:
maxfitindex = j
maxfit = fitness
tmp = OrderLen[i+1]
OrderLen[i+1] = OrderLen[maxfitindex]
OrderLen[maxfitindex] = tmp
len(OrderLen)
# 按给定顺序分配订单
GroupNo = []
for orderInf in iter(OrderLen):
overIndex = -1
overDelta = orderInf[1]
overSet = set()
product = set(OrderObject[orderInf[0]])
cache = set()
for i, j in enumerate(GroupNo):
cache = product.copy()
cache.update(j[0])
if len(cache) > 200:
continue
if len(cache)-len(j[0])==0:
overIndex = i
overSet = cache
break
if len(cache)-len(j[0]) <= overDelta:
overIndex = i
overDelta = len(cache)-len(j[0])
overSet = cache
continue
if overIndex == -1:
GroupNo.append([product, [orderInf[0]]])
else:
GroupNo[overIndex][0] = overSet
GroupNo[overIndex][1].append(orderInf[0])
print(len(GroupNo))
# 保留一级结果
res1 = []
for k, v in enumerate(GroupNo):
for i in iter(v[1]):
res1.append([i+1,k+1])
len(res1)
# 生成最后结果并输出
def NumToStringD(x):
return ["D{0:0>4}".format(x[0]), x[1]]
res1.sort(key=lambda item: item[0])
result1 = list(map(NumToStringD, res1))
result1 = pd.DataFrame(result1, columns=['OrderNo','GroupNo']);
result1.to_csv("result1.csv", index=False)

# 第二题
# 保存结果列表和计算函数
ProductOrderList = []
DistanceList = []
def sumDistance(TargetSort, NormOrder):
sum = 0
for item in iter(NormOrder):
if len(item) == 1:
continue
min, max = 0, len(TargetSort)-1
for k, v in enumerate(TargetSort):
if v in item:
min = k
break
for k, v in enumerate(reversed(TargetSort)):
if v in item:
max = len(TargetSort)-k-1
break
sum += max-min
return sum
# 寻找批次最短距离
for temp in GroupNo:
N = len(temp[0])
NormOrder = []
ProductList = list(temp[0])
for k, v in enumerate(temp[1]):
NormOrder.append([])
for i in iter(OrderObject[v]):
NormOrder[k].append(ProductList.index(i))
TargetSort = list(range(0, N))

currentSum = sumDistance(TargetSort, NormOrder)
for i in range(0, N):
for j in range(i+1, N):
tmp = TargetSort[j]
TargetSort[j] = TargetSort[i]
TargetSort[i] = tmp
tmpSum = sumDistance(TargetSort, NormOrder)
if tmpSum < currentSum:
currentSum = tmpSum
continue
elif tmpSum == currentSum:
if j-i < (N-i)/1:
continue
else:
break
else:
tmp = TargetSort[j]
TargetSort[j] = TargetSort[i]
TargetSort[i] = tmp
if j-i < (N-i)/1:
continue
else:
break

DistanceList.append(currentSum)
ProductOrderList.append(list(map(lambda ind: ProductList[ind],TargetSort)))
# 一级结果
res2 = []
for k, v in enumerate(ProductOrderList):
for i, j in enumerate(v):
res2.append([j, k+1, i+1])
print(len(res2))
sum(DistanceList)
# 最后结果
def NumToStringP(x):
return ["P{0:0>4}".format(x[0]), x[1], x[2]]
result2 = list(map(NumToStringP, res2))
result2 = pd.DataFrame(result2, columns=['ItemNo','GroupNo','ShelfNo']);
result2.to_csv("result2.csv", index=False)

# 第三题
# 保存结果列表和计算函数
TaskList = []
TimeList = []
def sumDeltaDistance(pos, Product, CurrentOrder):
min, max = 0, len(Product)-1
for k, v in enumerate(Product):
if v in CurrentOrder:
min = k
break
for k, v in enumerate(reversed(Product)):
if v in CurrentOrder:
max = len(Product)-k-1
break
if pos <= min:
return max-min, max
elif pos >= max:
return max-min, min
else:
if pos - min < max - pos:
return max-min+pos-min, max
else:
return max-min+max-pos, min
# 寻找最短分配方案
for indexNum in range(len(GroupNo)):
TaskList.append([])
CurrentTask = [[],[],[],[],[]]
CurrentPos = [0, 0, 0, 0, 0]
CurrentSum = [0, 0, 0, 0, 0]
temp = GroupNo[indexNum]
tempProduct = ProductOrderList[indexNum]
ProductList = list(temp[0])
for v in iter(temp[1]):
minIndex = 0
minPos = 0
minSum = max(CurrentSum) + len(ProductList)
for i in range(0,5):
delta, tmpPos = sumDeltaDistance(CurrentPos[i], ProductList, OrderObject[v])
if CurrentSum[i]+delta < minSum:
minSum = CurrentSum[i]+delta
minIndex = i
minPos = tmpPos
CurrentTask[minIndex].append(v)
CurrentPos[minIndex] = minPos
CurrentSum[minIndex] = minSum
TaskList[indexNum] = CurrentTask
TimeList.append(max(CurrentSum))
# 一级结果
res3 = []
for k, v in enumerate(TaskList):
for i in range(0, 5):
for tn, pi in enumerate(v[i]):
res3.append([pi+1, k+1, i+1, tn+1])
print(len(res3))
sum(TimeList)
# 最后结果
def NumToString(x):
return ["D{0:0>4}".format(x[0]), x[1], x[2], x[3]]
result3 = list(map(NumToString, res3))
result3 = pd.DataFrame(result3, columns=['OrderNo','GroupNo','WorkerNo', 'TaskNo']);
result3.to_csv("result3.csv", index=False)

想要有所长进,就多实践吧。接下来想多做些算法,不太想写文章了。

至于数学竞赛,奈何实力不够(想参加数学类的),没资格参加。