今天突发奇想,有一个很常用的场景
某个最优化问题,变量为N个正整数,
的范围为0-maxL,目标函数为 所有变量 的重复次数个数。
如,变量集合 X = [0,1,2,3,4]
则obj = 0
如,变量集合 X = [0,1,1,3,1]
则obj = 2
该问题的 obj的最小值是0,经过计算后,爬山法迭代3万次只能收敛到159, 问题规模:变量500个变量,变量范围也为500的规模问题。
在设计最优化模型的时候的变量和算法迭代策略的时候,一定要非常注意这个问题
爬山法:
import matplotlib.pyplot as plt
import numpy as np
'''
该函数是用来计算目标函数,统计出现的每个数的重复次数
如,dataList = [0,1,2,3,4]
则返回 obj = 0
如,dataList = [0,1,1,3,1]
则返回 = 2
'''
def uniqueCount(dataList):
a, b = np.unique(dataList, return_counts=True)
b = np.array(b)
c = b[b>1];
return np.sum(c) - len(c)
maxVarible = 500;
variableList = np.zeros(maxVarible)
i = 0
obj = uniqueCount(variableList) # 记录当前 最优重复值
bestObj = maxVarible + 1 # 记录当前 最优重复值
recordBestObj = []
np.random.seed(0);
while (obj > 0) & (i < 300000):
# 两种策略,一种是交换,一种是在变量范围值中找一个; 策略1对目标函数无用,只是某些算法场景里会有这种情况
strategy = np.random.randint(0, 2)
# 策略1:随机找两个位置交换值
if strategy == 0:
a = np.random.randint(0,maxVarible)
b = np.random.randint(0,maxVarible)
while a == b:
b = np.random.randint(0, maxVarible)
# 开始交换
variableList[a],variableList[b] = variableList[b],variableList[a]
else:
# 策略2: 在变量范围值中随机赋值
a = np.random.randint(0, maxVarible)
variableList[a] = np.random.randint(0,maxVarible)
obj = uniqueCount(variableList)
if obj < bestObj:
bestObj = obj
recordBestObj.append(bestObj)
i = i+1
print(i)
if i % 1000 == 0: # 每1000打印一次
plt.plot(recordBestObj)
plt.title("bestObj"+str(bestObj) + " index:" + str(i))
plt.show()
plt.plot(recordBestObj)
plt.title("bestObj"+str(bestObj) + " index:" + str(i))
plt.show()
收敛图