Originally posted by: NancyX
Thank you.Here is the code, do you have a look at this code for any problems?
void CMyCplex::build_model(){
int flight_nums = data.N1.size() + data.N2.size() + data.N3.size();
typedef IloArray<IloIntVarArray> IntMatrix;
typedef IloArray<IntMatrix> Decision_X;
Decision_X X(env, flight_nums);
for(int i = 0; i < flight_nums; i++){
X[i] = IntMatrix(env,data.M.size());
for(int j = 0 ; j < data.M.size(); j++){
int kk;
vector<Deci>::iterator it;
it = find_if(data.deci.begin(), data.deci.end(),findsNum(i*10+(j+1)));
if(it != data.deci.end()){
kk = it->k;
if(i == 0){
X[i][j] = IloIntVarArray(env, kk , 1, 1);
}else{
X[i][j] = IloIntVarArray(env, kk , 0, 1);
}
}else{
X[i][j] = NULL;
}
}
}
for(int i = 0; i < data.SS.size(); i++){
if(data.SS[i].fol.size() == 0 || data.SS[i].flight_id == 0){
continue;
}
int f_id = data.SS[i].flight_id;
for(int j = 0; j < data.M.size() ; j++){
int kk = 0;
vector<Deci>::iterator it;
it = find_if(data.deci.begin(), data.deci.end(),findsNum(f_id*10+(j+1)));
if(it != data.deci.end()){ //在data.deci中找到了该记录
kk = it->k;
}else{ //该飞机不能执行该航班
continue;
}
for(int k = 0; k < kk; k++){ //对于所考察的航班i来说的所有执行方案
IloIntExpr tmp_Expr1(env);
int num = f_id*100+(j+1)*10+k+1;
for(int l = 0; l < data.XX.size(); l++){ //从衔接航班对中查找元素
int t_f_id = data.XX[l][0];
int t_s_id = data.XX[l][1];
if(num == t_f_id){
int b = t_s_id/100; //用于表示航班
int s; //获取num十位上的数,表示飞机的 id
if(t_s_id > 100){
s = t_s_id/10%10 - 1;
}else{
s = t_s_id/10 - 1;
}
int g = t_s_id % 10 -1 ;
tmp_Expr1 += X[b][s][g];
}
}
model.add(tmp_Expr1 == X[f_id][j][k]);
tmp_Expr1.end();
}
}
}
//添加约束条件二 ,每个航班至多只能被一架飞机执行
for(int i = 1; i < data.F.size(); i++){
if(data.F[i].size() == 0){
continue;
}
IloIntExpr tmp_Expr2(env);
for(int j = 0; j < data.F[i].size(); j++){ //每个航班的可执行方案
int f_id; //航班id
int p_id; //飞机id
int k_id; //执行方案
f_id = i;
k_id = data.F[i][j]%10 - 1;
if(data.F[i][j] >100){
p_id = data.F[i][j]/10%10 -1;
}else{
p_id = data.F[i][j]/10 -1;
}
tmp_Expr2 += X[f_id][p_id][k_id];
}
model.add(tmp_Expr2 <= 1);
tmp_Expr2.end();
}
//约束条件三
for(int i = 0; i < data.N4.size(); i++){
int str_id = data.N4[i][0]; //联程拉直航班
int fir_id = data.N4[i][1]; //联程航班的第一个航班
int sed_id = data.N4[i][2]; //联程航班的第二个航班
IloIntExpr tmp_Expr3(env);
IloIntExpr tmp_Expr31(env);
//根据sttr_id 获得联程航班的执行方案
for(int j = 0; j < data.F[str_id].size(); j++){ //先获取联程拉直航班的执行方案
// cout<<data.F[str_id][j]<<endl;
int f_id; //航班id
int p_id; //飞机id
int k_id; //执行方案
f_id = str_id;
k_id = data.F[str_id][j]%10 - 1;
if(data.F[str_id][j] >100){
p_id = data.F[str_id][j]/10%10 -1;
}else{
p_id = data.F[str_id][j]/10 - 1;
}
tmp_Expr3 += X[f_id][p_id][k_id];
}
for(int j = 0; j < data.F[fir_id].size(); j++){
int f_id; //航班id
int p_id; //飞机id
int k_id; //执行方案
f_id = fir_id;
k_id = data.F[fir_id][j]%10 - 1;
if(data.F[fir_id][j] >100){
p_id = data.F[fir_id][j]/10%10 -1;
}else{
p_id = data.F[fir_id][j]/10 - 1;
}
tmp_Expr31 += X[f_id][p_id][k_id];
}
model.add(tmp_Expr3 <= (1 - tmp_Expr31));
tmp_Expr3.end();
tmp_Expr31.end();
}
//约束四
for(int i = 0; i < data.N6.size(); i++){
int fir_id = data.N6[i][0]; //联程航班的第一个航班
int sed_id = data.N6[i][1];
for(int j = 0; j < data.M.size(); j++){
IloIntExpr sub1_Expr4(env);
IloIntExpr sub2_Expr4(env);
//通过i和j确定k的值
int kk = 0;
vector<Deci>::iterator it;
int num = fir_id *10 + j+1; //联程航班的第一个航班的执行方案对应的决策变量
it = find_if(data.deci.begin(), data.deci.end(),findsNum(num));
if(it != data.deci.end()){//在data.deci中找到了该记录
kk = it->k;
}else{
continue;
}
for(int k = 0; k < kk; k++){
sub1_Expr4 += X[fir_id][j][k];
}
int kk2 = 0;
int num2 = sed_id * 10 + j+1;
vector<Deci>::iterator it2;
it2 = find_if(data.deci.begin(), data.deci.end(),findsNum(num2));
if(it2 != data.deci.end()){//在data.deci中找到了该记录
kk2 = it2->k;
}else{
continue;
}
for(int k = 0; k < kk2; k++){
sub2_Expr4 += X[sed_id][j][k];
}
model.add(sub1_Expr4 >= sub2_Expr4);
sub2_Expr4.end();
sub1_Expr4.end();
}
}
//约束五
for(int i = 0; i < data.N5.size(); i++){
int dead_id = data.N5[i][0]; //调机航班
int ff_id = data.N5[i][1]; //调机替换的航班
IloIntExpr tmp_Expr5;
IloIntExpr tmp_Expr51;
//根据sttr_id 获得联程航班的执行方案
for(int j = 0; j < data.F[dead_id].size(); j++){ //考察调机航班的执行情况
int f_id; //航班id
int p_id; //飞机id
int k_id; //执行方案
f_id = dead_id;
k_id = data.F[f_id][j]%10 -1;
if(data.F[f_id][j] < 100){
p_id = data.F[f_id][j]/10 -1;
}else{
p_id = data.F[f_id][j]/10%10 -1;
}
tmp_Expr5 += X[f_id][p_id][k_id];
}
for(int j = 0; j < data.F[ff_id].size(); j++){
int f_id; //航班id
int p_id; //飞机id
int k_id; //执行方案
f_id = ff_id;
k_id = data.F[f_id][j]%10;
if(j == 0){
p_id = data.F[f_id][j]/10 - 1;
}else{
p_id = data.F[f_id][j]/10%10 -1;
}
tmp_Expr51 += X[f_id][p_id][k_id];
}
model.add(tmp_Expr5 <= (1 - tmp_Expr51));
tmp_Expr5.end();
tmp_Expr51.end();
}
//约束六
cout<<"约束六"<<endl;
for(int j = 0; j < data.M.size(); j++){
IloIntExpr tmp_Expr6(env);
for(int t = 0; t < data.T[j].size(); t++){
cout<<data.T[j][t]<<endl;
int f_id ; //航班id
int p_id; //飞机id
int k_id; //执行方案
f_id = data.T[j][t] / 100;
p_id = j;
k_id = data.T[j][t]%10 - 1;
tmp_Expr6 += X[f_id][p_id][k_id];
}
model.add(tmp_Expr6 == 1);
tmp_Expr6.end();
}
cout<<"约束七"<<endl;
////约束七
for(int i = 0; i < data.SS.size(); i++){
if(data.SS[i].fol.size() == 0){
int flight_id = data.SS[i].flight_id; //航班id
IloIntExpr tmp_Expr7(env);
for(int j = 0; j < data.F[flight_id].size(); j++){
// cout<<"航班"<<data.F[flight_id][j]<<"没有后继航班"<<endl;
int f_id; //航班id
int p_id; //飞机id
int k_id; //执行方案
f_id = flight_id;
k_id = data.F[f_id][j]%10 -1;
if(data.F[f_id][j] < 100){
p_id = data.F[f_id][j]/10 - 1 ;
}else{
p_id = data.F[f_id][j]/10%10 - 1;
}
tmp_Expr7 += X[f_id][p_id][k_id];
}
model.add(tmp_Expr7 == 1);
tmp_Expr7.end();
}
}
cout<<"约束八"<<endl;
//0号航班必须执行
for(int i = 0; i < data.F[0].size(); i++){
int num = data.F[0][i];
int b = num / 100;
int s;
if(num > 100){
s = num /10%10 -1;
}else{
s = num/10 - 1;
}
int g = num%10 -1;
model.add(X[b][s][g]);
}
//目标函数
IloExpr expr(env);
//获取目标函数中的第一部分
for(int i = 0; i < flight_nums; i++){
for(int j = 0; j < data.M.size(); j++){
//通过i和j确定k的值
int kk = 0;
vector<Deci>::iterator it;
it = find_if(data.deci.begin(), data.deci.end(),findsNum(i*10+(j+1)));
if(it != data.deci.end()){//在data.deci中找到了该记录
kk = it->k;
}else{
continue;
}
for(int k = 0; k < kk; k++ ){ //方案编号也是从0开始的
int cost = 0;
vector<Cost>::iterator ite;
ite = find_if(data.f_cost.begin(), data.f_cost.end(), finddCost(i*100+(j+1)*10+(k+1)));
if(ite != data.f_cost.end()){
cost = ite->cost;
}else{
continue;
}
cout<<i<<" , "<<j<<", "<<k<<endl;
expr += X[i][j][k] * cost;
}
}
}
cout<<"目标函数"<<endl;
IloExpr expr2(env) ;
for(int i = 1; i<data.N1.size(); i++){ //此时刨除0号航班
//获取F中航班i对应的执行方案
vector<int> tmp_F = data.F[i];
IloExpr tmp_expr(env);
for(auto j : tmp_F){
//tmp_expr中元素的每一位表示一个索引
int b = j /100; //百位,表示航班编号
int s; //十位,表示飞机编号
if(j > 100){
s = j /10 % 10 -1;
}else{
s = j / 10 - 1;
}
int g = j % 10 - 1; //个位,表示对应的执行方案
tmp_expr += X[b][s][g];
}
expr2 +=( 1 - tmp_expr)* data.C[i];
}
IloExpr expr3(env) ;
for(int i = 0; i < data.N4.size(); i++){
vector<int> tmp = data.N4[i];
int str = tmp[0]; //联程拉直航班,相当于决策变量中的i
int fir = tmp[1]; //联程航班的第一个,相当于决策变量中的i'
int sed = tmp[2]; //联程航班的第二个,相当于决策变量中的i''
for(int j = 0; j < data.M.size(); j++){
//通过i和j确定k的值
int kk = 0;
int num = str* 10 + j+1;
vector<Deci>::iterator it;
it = find_if(data.deci.begin(), data.deci.end(),findsNum(num));
if(it != data.deci.end()){//在data.deci中找到了该记录
kk = it->k;
}else{
continue;
}
for(int k = 0; k <kk; k++){
expr3 += X[str][j][k] * (data.C[fir] + data.C[sed]);
}
}
}
IloExpr obj(env);
obj = expr + expr2 + expr3; //目标函数
model.add(IloMinimize(env,obj));
expr.end();
expr2.end();
expr3.end();
obj.end();
//求解模型
vector<vector<int> >solutions(2);
vector<vector<int> > routes(2); //飞机所执行路径集合
vector<vector<double> > costs(2); //每个航班的执行成本
cplex = IloCplex(model);
/*cplex = IloCplex(env);
cplex.extract(model);*/
cplex.exportModel("flightRecovery.lp");
cplex.setParam(IloCplex::TiLim, 600); //设置模型求解时间为10分钟
std::cout<<"模型开始求解"<<endl;
if(cplex.solve()){
cplex.out()<<"Solution status: "<<cplex.getStatus()<<endl;
cplex.out()<<"Total cost = "<<cplex.getObjValue()<<endl;
//模型可解,生成飞机路线
for(int j = 0; j < data.M.size(); j++){
vector<int> r ;
vector<double> c;
int flight_nums = data.N1.size()+ data.N2.size() + data.N3.size();
for(int i = 0; i < flight_nums; i++){ //从第一个航班开始考察
int kk = 0;
vector<Deci>::iterator it;
it = find_if(data.deci.begin(), data.deci.end(),findsNum(i*10+(j+1)));
if(it != data.deci.end()){
if((j+1) > X[i].getSize()){
continue;
}
for(int k = 0; k < X[i][j].getSize(); k++){
//cplex.out()<<cplex.getValue(X[i][j][k])<<endl;
if(cplex.getValue(X[i][j][k])){
r.push_back(i);
break;
}
}
}
}
solutions.push_back(r);
}
for(int i = 0; i < solutions.size(); i++){ //输出路径
for(int j = 0; j <solutions[i].size(); j++){
std::cout<<solutions[i][j]<<"-->";
}
std::cout<<endl;
}
}else{
cplex.out() <<"No Solution"<<endl;
cplex.out() <<cplex.getStatus()<<endl;
}
}
#CPLEXOptimizers#DecisionOptimization