我怎样才能最大化目标函数?
我有一个客户列表,每个客户都可以通过三种不同方式“激活”。
n= 1000
df = pd.DataFrame(list(range(0,n)), columns = ['Customer_ID'])
df['A'] = np.random.randint(2, size=n)
df['B'] = np.random.randint(2, size=n)
df['C'] = np.random.randint(2, size=n)
df['check_somma'] = df['A']+df['B']+df['C']
for index, rows in df[df['check_somma'] == 0].iterrows():
i = np.random.randint(3)
if i == 0:
df.loc[index,['A']]= 1
if i == 1:
df.loc[index,['B']]= 1
if i == 2:
df.loc[index,['C']]= 1
df['check_somma'] = df['A']+df['B']+df['C']
df['A_k'] = np.random.rand(n,1)
df['B_k'] = np.random.rand(n,1)
df['C_k'] = np.random.rand(n,1)
df['A_k'] = df['A_k'] * df['A']
df['B_k'] = df['B_k'] * df['B']
df['C_k'] = df['C_k'] * df['C']
只有当与激活类型相关的布尔值等于1时,才能在“A”或“B”或“C”上激活每个客户。
在输入中,我有最终激活的计数。 ES:
Target_A = 500
Target_B = 250
Target_C = 250
使用此代码,我希望最小化实际激活计数和输入数据之间的距离。
A = LpVariable.dicts("A", range(0, n), lowBound=0, upBound=1, cat='Boolean')
B = LpVariable.dicts("B", range(0, n), lowBound=0, upBound=1, cat='Boolean')
C = LpVariable.dicts("C", range(0, n), lowBound=0, upBound=1, cat='Boolean')
prob = LpProblem("problem",LpMaximize)
#objective
prob += lpSum(A)+lpSum(B)+lpSum(C)
#constraints
prob += Target_A >= lpSum(A)
prob += Target_B >= lpSum(B)
prob += Target_C >= lpSum(C)
for idx in range(0, n):
prob += A[idx] + B[idx] + C[idx] <= 1 #cant activate more than 1
prob += A[idx] <= df['A'][idx] #cant activate if 0
prob += B[idx] <= df['B'][idx]
prob += C[idx] <= df['C'][idx]
prob.solve()
如何最小化输入分布的距离(如上面的代码所示),同时最大化激活'A_k','B_k','C_k'的权重?
附:代码中的随机值是优化器的输入,表示以这种方式激活客户端的可能性。我可以只使用一种“方式”将客户关联起来,以便尊重最终目标
从here获取代码,您只需要修改1行:目标函数。为了优先考虑绝对差异,并且只有在抽签优先考虑具有更多权重的解决方案的情况下,我们将仅缩放目标函数的差异,以便即使得到1个差异更小,也会比任何重量改善更好。我们可以通过缩放客户数量+1来实现这一点,因为权重之和永远不会超过n。
所以只需使用旧代码并将目标函数更改为:
prob += (O1 + O2 + O3) * (n + 1) - lpSum([A[idx] * df['A_k'][idx] + B[idx] * df['B_k'][idx] + C[idx] * df['C_k'][idx] for idx in range(0, n)])
您现在需要手动检查变量及其分配以了解差异值,因为目标解决方案代表另一个问题。