组合最小化
Combinatorial minimisation
我正在尝试找到最有效的方法。
学生可以被分配到停靠站 A、B 或 C。我们会得到一份学生有资格被分配到的停靠站列表。
##Create an empty dataframe
df = pd.DataFrame()
## Create a list with potential stops that each student qualifies for
potential_stops_for_each_student = [['A','B','C'], ['B','C'], ['C']]
df['Potential Stops'] = potential_stops_for_each_student
我的目标是尽量减少停靠站的总数,因此在此示例中,显然所有学生都应分配到公交车站 'C'。我的解决方案目前着眼于所有可能的组合(即(A,B,C),(A,C,C),(B,B,C),(B,C,C),(C,B,C), (C,C,C)), 然后选择唯一元素最少的组合。
这对我来说似乎是一个糟糕的解决方案,所以我希望有人能指出我更好的解决方案。对包或任何现有文献的引用都可以,如果你不想,你不必编写代码!
谢谢!
下面是使用 cvxpy with the GLPK solver: you will need to install it as well as cvxpy using the instructions here.
的快速尝试
#import the packages:
import numpy as np
import cvxpy
#we will set the number of stops and children here:
nstops = 10
nchildren = 50
#data looks like a 1/0 array for each child, for each stop
#you can use pd.get_dummies to do this
data = np.random.randint(2, size=(nchildren, nstops))
#here we set our cvxpy variable: this varies to find the best solution
#it will be the boolean to determine which stops we chose
selection = cvxpy.Variable(nstops, boolean=True)
#now we make our constraints
#for each child, the sum of the product of the chosen stops and their available stops must be >=1
#we can probably use a better formulation of this, but it works
constraints = []
for i in range(nchildren):
#we use cvxpy operations to allow the problem to be formulated
constraints.append(cvxpy.sum(cvxpy.multiply(data[i,:],selection )) >= 1)
#now our problem is: minimize the sum of the number of chosen stops:
cost = cvxpy.sum(selection)
#we want to minimize it, subject to our constraints
problem = cvxpy.Problem(cvxpy.Minimize(cost), constraints=constraints)
#then we solve it!
score = problem.solve(solver=cvxpy.GLPK_MI)
#we have our 'selection' as a numpy array of booleans: here we get the indices of the chosen stops
np.where(selection.value.astype(np.bool))
我正在尝试找到最有效的方法。
学生可以被分配到停靠站 A、B 或 C。我们会得到一份学生有资格被分配到的停靠站列表。
##Create an empty dataframe
df = pd.DataFrame()
## Create a list with potential stops that each student qualifies for
potential_stops_for_each_student = [['A','B','C'], ['B','C'], ['C']]
df['Potential Stops'] = potential_stops_for_each_student
我的目标是尽量减少停靠站的总数,因此在此示例中,显然所有学生都应分配到公交车站 'C'。我的解决方案目前着眼于所有可能的组合(即(A,B,C),(A,C,C),(B,B,C),(B,C,C),(C,B,C), (C,C,C)), 然后选择唯一元素最少的组合。
这对我来说似乎是一个糟糕的解决方案,所以我希望有人能指出我更好的解决方案。对包或任何现有文献的引用都可以,如果你不想,你不必编写代码!
谢谢!
下面是使用 cvxpy with the GLPK solver: you will need to install it as well as cvxpy using the instructions here.
的快速尝试#import the packages:
import numpy as np
import cvxpy
#we will set the number of stops and children here:
nstops = 10
nchildren = 50
#data looks like a 1/0 array for each child, for each stop
#you can use pd.get_dummies to do this
data = np.random.randint(2, size=(nchildren, nstops))
#here we set our cvxpy variable: this varies to find the best solution
#it will be the boolean to determine which stops we chose
selection = cvxpy.Variable(nstops, boolean=True)
#now we make our constraints
#for each child, the sum of the product of the chosen stops and their available stops must be >=1
#we can probably use a better formulation of this, but it works
constraints = []
for i in range(nchildren):
#we use cvxpy operations to allow the problem to be formulated
constraints.append(cvxpy.sum(cvxpy.multiply(data[i,:],selection )) >= 1)
#now our problem is: minimize the sum of the number of chosen stops:
cost = cvxpy.sum(selection)
#we want to minimize it, subject to our constraints
problem = cvxpy.Problem(cvxpy.Minimize(cost), constraints=constraints)
#then we solve it!
score = problem.solve(solver=cvxpy.GLPK_MI)
#we have our 'selection' as a numpy array of booleans: here we get the indices of the chosen stops
np.where(selection.value.astype(np.bool))