免责声明:此问题与算法问题相关,而不是纯Python编码(或Excel解算器)问题
我们目前正在将600多个网站迁移到新平台。部分工作是将组件代码(30+)移植到新平台。 为了解决这个问题,我们已经清点了每个站点上每个组件的用法:
现在,我们应该找到以哪种顺序移植组件。 基本规则如下:只要移植给定网站使用的所有组件,就可以迁移网站。
目标是尽可能最大限度地增加我们可以迁移的网站数量。
在我的例子中:
这对于4个组件和5个站点来说相当容易,但对于我们必须处理的金额而言,这是一个真正的噩梦。
什么是系统方法?
答案 0 :(得分:2)
虽然这是NP难的(请参阅此question for a proof),但只有30个组件,您应该能够通过使用the Held-Karp algorithm的变体来解决所有组合问题,以解决旅行商问题。
主要思想是计算分数,而不是针对每个排列(因为排列太多),而是针对您构建的每个组件的每一组。
将会有2 ^ N套,比N小得多!排列。
要计算每个集合S的分数,您将迭代选择最后一个组件x,并将所有包含x(以及S中的其他组件)的所有网站的分数添加到之前计算的分数中较小的集合Sx。对于每个集合,您可以存储可用的最佳分数,以及最后应添加的组件。
当您计算出添加所有组件的分数时,您可以追溯存储的信息以计算添加组件的顺序。
答案 1 :(得分:1)
我会将您拥有的组件数量概括为N
(“N”个组件)。由于组件重构的顺序会影响在该时间实例中可以部署的站点数量,因此这将成为排列的最大化。
一组
N
尺寸的排列量为N!
或factorial(N)
如果您有4个组件,则组件重构的顺序将有24个不同的排列。从那里,您可以计算每个排列顺序可以迁移的可能站点的数量。
您决定哪个是“最佳”结果。通过选择使用第一个组件重构或组件重构总和产生最多迁移的结果来最大化它。它完全依赖于您的业务逻辑。
答案 2 :(得分:0)
两种算法:
第一个您在示例中主要描述的那个。这样可以提高效率,并以最快的速度完成所有站点的迁移,但可能不是预先提供更多站点的站点
为每个组件提供数据后,请计划网站迁移。迁移所有组件后,可以迁移站点:
- 对于每个站点,从最后一个ComponentMigrationDate开始,按ComponentMigrationDate迭代所有组件。在迭代时,检查站点是否具有该组件,站点的第一个组件是SiteMigrationDate。
第二个可能会生成更多迁移得更快的网站
生成所有组件的列表。对于列表中的每个组件,生成仅对此组件具有剩余依赖关系的站点计数(SitesPendingOn)。拿一个最多的,并为其分配一个MigrationOrder(升序号码)。如果列表中没有此类组件,则为每个剩余的(未分配的迁移顺序)生成站点使用计数:ComponentSiteUsageCount。拿一个最多的,并为其分配下一个MigrationOrder。在未分配MigrationOrder的组件上重复循环以获取SitesPendingOn,直到所有组件都分配了MigrationOrder
对于每个站点,从最后一个ComponentMigrationDate开始,按ComponentMigrationDate迭代所有组件。在迭代时,检查站点是否具有该组件,站点的第一个组件是SiteMigrationDate。
第二算法代码 '
import pandas as pd
def get_pending_sites(site_components, component, components):
count = 0
for index, site in site_components.iterrows():
#print('site ...', site['Site'])
if site[component] > 0. and components[component][0] == 0:
#print('site uses component')
other_dependent = False
for site_component in list(site_components.columns.values)[1:]:
if site_component != component:
if site[site_component] > 0. and components[site_component][0] == 0:
#print('site uses other components')
other_dependent = True
break
if other_dependent == False:
count += 1
#print('count', count)
return count
def get_used_sites(site_components, component):
count = len(site_components[site_components[component] > 0.])
print ("Component: ", component, " used in sites: ", count)
return count
def get_most_pending_sites(components):
most_count = 0
most_component = None
for component in components:
if components[component][0] == 0:
count = components[component][1]
if count > most_count:
most_component = component
most_count = count
elif (count == most_count) and (most_component != None):
if components[component][2] > components[most_component][2] :
most_component = component
return most_component
def get_most_used_sites(components):
most_count = 0
most_component = None
for component in components:
if components[component][0] == 0:
count = components[component][2]
if count > most_count:
most_component = component
most_count = count
return most_component
migration_order = 1
site_components = pd.read_csv('site_components.csv')
#print(site_components.describe())
components = dict.fromkeys(list(site_components.columns.values)[1:])
for component in components:
components[component] = [0, 0, 0]
components[component][2] = get_used_sites(site_components, component)
#print(components)
while True:
print("Components: ", components)
for component in components:
if components[component][0] == 0:
print('starting .....', component)
components[component][1] = get_pending_sites(site_components, component, components)
print('finished .....', component, components[component][1], components[component][2])
while True:
most_pending_sites_component = get_most_pending_sites(components)
print('most pending sites components: ', most_pending_sites_component)
if most_pending_sites_component != None:
components[most_pending_sites_component][0] = migration_order
migration_order = migration_order + 1
else:
break
most_used_sites_component = get_most_used_sites(components)
if most_used_sites_component != None:
components[most_used_sites_component][0] = migration_order
migration_order = migration_order + 1
else:
break
# order of migration in [0]
print("Components: ", components)
假设:迁移组件所需的时间在所有组件中是统一的 注意:将包含网站和组件的电子表格另存为csv,并删除所有垂直和水平的总计