【写在前面的话】
我们选择A题,分析A题题目可以得知属于一种组合优化模型,类似于旅行商问题,0-1背包问题等等。该类问题通常采用遗传算法,粒子群算法,模拟退火算法等算法进行求解。由于本题需要我们建立出数学模型之后通过转换为QUBO模型,从而建立量子退火模型,从而可以实现在量子计算机中求解。所以我们直接选择采用模拟退火模型。
第一问太简单,我TM直接穷举🤣,代码给你们看看(别太荒谬哈哈):
clc;clear;
load bank.mat
max=0;
i_max=0;
j_max=0;
for j=1:2:200
for i=1:10
banifit=1000000*bank(i,j)*0.08*(1-bank(i,j+1))-1000000*bank(i,j)*bank(i,j+1);
if(banifit>max)
max=banifit;
i_max=i;
j_max=j;
end
end
end
开玩笑的,正儿八经还得用模拟退火模型求解嘿嘿
第一问的代码(这么详细的注释,我哭死,你怎么还不哭😡):
clc;
clear;
tic
load bank.mat
x1=bank(:,1:2:end);
x1=x1(:);
x1=x1';
x2=bank(:,2:2:end);
x2=x2(:);
x2=x2';
n=length(x1);
T0 = 1000;
T = T0;
maxgen = 500;
Lk = 20;
alfa = 0.95;
way0 = zeros(1,n);
load_matrix=way0;
profit0=sum(1000000*0.08*way0.*x1.*(1-x2)-1000000*way0.*x1.*x2);
max_profit = profit0;
PROFIT = zeros(maxgen,1);
for iter = 1 : maxgen
for i = 1 : Lk
[way1,load_matrix] = gen_new_way(way0,load_matrix,n);
profit1 =sum(1000000*0.08*way1.*x1.*(1-x2)-1000000*way1.*x1.*x2);
if profit1 > profit0
way0 = way1;
profit0 = profit1;
else
p = exp(-(profit0 - profit1)/T);
if rand(1) < p
way0 = way1;
profit0 = profit1;
end
end
if profit0 > max_profit
max_profit = profit0;
best_way = way0;
end
end
PROFIT(iter) = max_profit;
T = alfa*T;
end
disp('最佳的阈值方案是:'); disp(best_way)
disp('此时最优值是:'); disp(max_profit)
plot(1:maxgen,PROFIT,'r-');
xlabel('迭代次数');
ylabel('银行最大收益值');
hold on
toc
主函数中用到的gen_new_way
函数:
function [way1, delta_weight] = gen_new_way(way0, n, weight)
i = randi([1,n],1);
if way0(i) == 1
way0(i) = 0;
empty_ind = find(way0==0);
length_empth_ind = length(empty_ind);
ind = randi([1, length_empth_ind], 1);
j = empty_ind(ind);
way0(j) = 1;
delta_weight = weight(j) - weight(i);
else
way0(i) = 1;
delta_weight = weight(i);
if rand(1) < 0.5
fill_ind = find(way0==1);
length_fill_ind = length(fill_ind);
ind = randi([1, length_fill_ind], 1);
j = fill_ind(ind);
way0(j) = 0;
delta_weight = weight(i) - weight(j);
end
end
way1 = way0;
end
第二问就是第一问的一个拓展,主函数差不多,要变得是收益函数的形式和新解的产生方法(正经起来了不是?):
clc;
clear;
tic
load bank.mat
x1=bank(:,1:2:6);
x1=x1(:);
x1=x1';
x2=bank(:,2:2:6);
x2=x2(:);
x2=x2';
n=length(x1);
T0 = 1000;
T = T0;
maxgen = 50;
Lk = 20;
alfa = 0.95;
way0 = zeros(1,n);
i_1= randi([1,10],1);
i_2= randi([11,20],1);
i_3= randi([21,30],1);
way0(i_1)=1;
way0(i_2)=1;
way0(i_3)=1;
T_tresh_ind=find((way0)~=0);
T_tresh=x1(T_tresh_ind(1))*x1(T_tresh_ind(2))*x1(T_tresh_ind(3));
H_tresh_ind=find((way0)~=0);
H_tresh=1/3*(x2(H_tresh_ind(1))+x2(H_tresh_ind(2))+x2(H_tresh_ind(3)));
profit0=sum(1000000*0.08*T_tresh*(1-H_tresh)-1000000*T_tresh*H_tresh);
max_profit = profit0;
PROFIT = zeros(maxgen,1);
for iter = 1 : maxgen
for i = 1 : Lk
[way1] = gen_new_way_2(way0,n);
T_tresh_ind=find((way1)~=0);
T_tresh=x1(T_tresh_ind(1))*x1(T_tresh_ind(2))*x1(T_tresh_ind(3));
H_tresh_ind=find((way1)~=0);
H_tresh=1/3*(x2(H_tresh_ind(1))+x2(H_tresh_ind(2))+x2(H_tresh_ind(3)));
profit1 =sum(1000000*0.08*T_tresh*(1-H_tresh)-1000000*T_tresh*H_tresh);
if profit1 > profit0
way0 = way1;
profit0 = profit1;
else
p = exp(-(profit0 - profit1)/T);
if rand(1) < p
way0 = way1;
profit0 = profit1;
end
end
if profit0 > max_profit
max_profit = profit0;
best_way = way0;
end
end
PROFIT(iter) = max_profit;
T = alfa*T;
end
disp('最佳的阈值方案是:'); disp(best_way)
disp('此时最优值是:'); disp(max_profit)
plot(1:maxgen,PROFIT,'r-');
xlabel('迭代次数');
ylabel('银行最大收益值');
hold on
toc
主函数中用到的gen_new_way_2
函数:
function [way1] = gen_new_way_2(way0,n)
way0_split=reshape(way0,10,[]);
way0_1=way0_split(:,1);
way0_2=way0_split(:,2);
way0_3=way0_split(:,3);
i=randi([1,n],1);
if i<=10
if way0(i) == 1
empty_ind = find(way0_1==0);
length_empth_ind = length(empty_ind);
ind = randi([1, length_empth_ind], 1);
j = empty_ind(ind);
way0(j) = 1;
way0(i) = 0;
else
empty_ind = find(way0_1==1);
j = empty_ind(1);
way0(j)=0;
way0(i)=1;
end
elseif i<=20
if way0(i) == 1
empty_ind = find(way0_2==0);
length_empth_ind = length(empty_ind);
ind = randi([1, length_empth_ind], 1);
j = empty_ind(ind);
way0(j+10) = 1;
way0(i) = 0;
else
empty_ind = find(way0_2==1);
j = empty_ind(1);
way0(j+10)=0;
way0(i)=1;
end
else
if way0(i) == 1
empty_ind = find(way0_3==0);
length_empth_ind = length(empty_ind);
ind = randi([1, length_empth_ind], 1);
j = empty_ind(ind);
way0(j+20) = 1;
way0(i) = 0;
else
empty_ind = find(way0_3==1);
j = empty_ind(1);
way0(j+20)=0;
way0(i)=1;
end
end
way1 = way0;
end
其实我感觉我第二问的产生新解的函数写的有点复杂了,有点冗余,第三问虽然问题更复杂了,涉及的数据更多了,但是代码又简化了很多嘿嘿:
clc;
clear;
tic
load bank.mat
x1=bank(:,1:2:end);
x1=x1(:);
x1=x1';
x2=bank(:,2:2:end);
x2=x2(:);
x2=x2';
n=length(x1);
T0 = 1000;
T = T0;
maxgen = 500;
Lk = 20;
alfa = 0.96;
way0 = zeros(1,n);
i_1= randi([1,10],1);
i_2= randi([11,20],1);
i_3= randi([21,30],1);
way0(i_1)=1;
way0(i_2)=1;
way0(i_3)=1;
T_tresh_ind=find((way0)~=0);
T_tresh=x1(T_tresh_ind(1))*x1(T_tresh_ind(2))*x1(T_tresh_ind(3));
H_tresh_ind=find((way0)~=0);
H_tresh=1/3*(x2(H_tresh_ind(1))+x2(H_tresh_ind(2))+x2(H_tresh_ind(3)));
profit0=sum(1000000*0.08*T_tresh*(1-H_tresh)-1000000*T_tresh*H_tresh);
max_profit = profit0;
PROFIT = zeros(maxgen,1);
for iter = 1 : maxgen
for i = 1 : Lk
[way1] = gen_new_way_3(way0,n);
T_tresh_ind=find((way1)~=0);
T_tresh=x1(T_tresh_ind(1))*x1(T_tresh_ind(2))*x1(T_tresh_ind(3));
H_tresh_ind=find((way1)~=0);
H_tresh=1/3*(x2(H_tresh_ind(1))+x2(H_tresh_ind(2))+x2(H_tresh_ind(3)));
profit1 =sum(1000000*0.08*T_tresh*(1-H_tresh)-1000000*T_tresh*H_tresh);
if profit1 > profit0
way0 = way1;
profit0 = profit1;
else
p = exp(-(profit0 - profit1)/T);
if rand(1) < p
way0 = way1;
profit0 = profit1;
end
end
if profit0 > max_profit
max_profit = profit0;
best_way = way0;
end
end
PROFIT(iter) = max_profit;
T = alfa*T;
end
disp('最佳的阈值组合是:'); disp(best_way)
disp('此时最优值是:'); disp(max_profit)
plot(1:maxgen,PROFIT,'r-');
xlabel('迭代次数');
ylabel('银行最大收益值');
hold on
toc
主函数中用到的gen_new_way_3
函数:
function [way1] = gen_new_way_3(way0,n)
empty_ind = find(way0==1);
length_empth_ind = length(empty_ind);
ind = randi([1, length_empth_ind], 1);
j = empty_ind(ind);
way0(j) = 0;
i=randi([1,n],1);
while(panduan(i,empty_ind)==1)
i=randi([1,n],1);
end
way0(i) = 1;
way1 = way0;
end
其中用到的panduan
函数:
function [result] = panduan(i,index)
if i>=index(1)-mod(index(1),10)+1 && i<=index(1)-mod(index(1),10)+10
result=1;
elseif i>=index(2)-mod(index(2),10)+1 && i<=index(2)-mod(index(2),10)+10
result=1;
elseif i>=index(3)-mod(index(3),10)+1 && i<=index(3)-mod(index(3),10)+10
result=1;
else
result=0;
end
end
第二三问运行结果每次可能都会有些许不同,因为并不是只有一个最优解,所以他会在几个最优解之间跳动,这是正常现象。
还不点赞?!怎么回事?!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)