组合优化中的全排列生成
之前有同学遇到组合优化(如0-1优化)问题,想采用穷举法,那么首先就要穷举产生所有的组合。
以0-1优化为例,假设当前有3个item,每个item有“选”或“不选”两种状态,那么所有可能的8方案为:
item1 | item2 | item3 |
---|---|---|
0 | 0 | 0 |
0 | 0 | 1 |
0 | 1 | 0 |
1 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
1 | 1 | 1 |
显然,当item数较小时,我们可以用多层for循环来穷举产生所有方案,但是当item较大时,多层for嵌套的方法则不可行。
对于Matlab
,可以选择用第三方函数allcomb()
来产生全组合,
allcomb()
源码下载地址:
https://cn.mathworks.com/matlabcentral/fileexchange/10064-allcomb-varargin-
调用方法:
num = 3; % 假设存在3种选项
A = [0 1]; % 每个选项两种可能状态
arg_in = cell(num,1);
for i=[1:num]
arg_in{i} = A;
end
result = allcomb(arg_in{:});
运行后在command window中查看result
:
>> result
result =
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
结果确实为8种。
另外,对于Python
,itertools
提供了类似的函数:
import numpy as np
import itertools as itl
num = 4 # 假设存在4个选项
# num个选项,每个选项都有选或不选2种状态
selects = 2*np.ones(num, dtype=int)
# 产生所有可能的选择方案的迭代器
methods = itl.product(*[range(i) for i in selects])
# 所有选择方案存入一个list中, 此处all_choices中共2^num种选择方案
all_choices = [list(choice) for choice in methods]
for choice in all_choices:
print(choice) # 打印所有方案
# 若要将所有方案输出到txt文件
# 保存为np.array的数据
choice_mat = np.array(all_choices)
# 每个数以整数形式写入
np.savetxt("select_output.txt", choice_mat,fmt='%d')
select_output.txt
文件内容:
不过,考虑到如果item较大的情况,如共item超过20个时,待选方案总数为 220 个,数量相当大,若依旧用穷举并对每个方案进行计算,则程序速度可能会相当慢。对于这类0-1优化问题,我可能会尝试随机的算法,如遗传算法和模拟退火算法。这两种算法相对于蒙特卡洛算法可能收敛较快,可以尝试一下。