void CreateStorageBindingConstraint(IloModel model, BoolVar3DMatrix L, BoolVarMatrix M, BoolVarMatrix X, BoolVar3DMatrix R, BoolVarMatrix Y, IloRangeArray c){ IloEnv env = model.getEnv(); //The nested for-loops generate L[p][i][t] //that is required to linearize equation 16 for(int p = 0; p < L.getSize(); p++){ for(int i = 0; i < n; i++){ for(int t = 0; t < T_MAX; t++){ L[p][i].add(IloBoolVar(env)); c.add(L[p][i][t] - M[p][i] - X[i][t] >= -1); c.add(L[p][i][t] - M[p][i] - X[i][t] <= 0); c.add(L[p][i][t] + M[p][i] - X[i][t] <= 1); c.add(L[p][i][t] - M[p][i] + X[i][t] <= 1); } } } //Contructing the array R[p][e][t] for(int p = 0; p < R.getSize(); p++){ for(int e = 0; e < E; e++){ for(int t = 0; t < T_MAX; t++){ R[p][e].add(IloBoolVar(env)); } } } //Encoding the constraint eqn-15 for(int t = 0; t < T_MAX; t++){ IloExprArray sum(env); for(int e = 0; e < E; e++){ sum.add(IloExpr(env)); for(int p = 0; p < n_m; p++){ sum[e] += R[p][e][t]; } c.add(sum[e] - Y[e][t] == 0); } } //Encoding the constraint eqn-21 for(int t = 0; t < T_MAX; t++){ IloExprArray sum1(env); IloExprArray sum2(env); for(int p = 0; p < n_m; p++){ sum1.add(IloExpr(env)); sum2.add(IloExpr(env)); for(int e = 0; e < E; e++) sum1[p] += R[p][e][t]; for(int i = 0; i < n; i++) sum2[p] += L[p][i][t]; c.add(sum1[p] - n_r*sum2[p] <= 0); } } return; }
/** * Create expression for out-flow for each node. */ static IloExprArray createExprArray_out_flow(IloEnv env, vector<Instance::Edge> edges, u_int n_edges, IloIntVarArray fs, Instance& instance) { IloExprArray expr(env, instance.n_nodes); for (u_int i = 0; i < instance.n_nodes; i++) { expr[i] = IloExpr(env); } for (u_int m = 0; m < n_edges; m++) { const u_int i = edges[m].v1; expr[i] += fs[m]; } return expr; }
/** * Create expression for out-degree for each node. */ static IloExprArray createExprArray_out_degree(IloEnv env, vector<Instance::Edge> edges, u_int n_edges, IloBoolVarArray xs, Instance& instance) { IloExprArray e_out_degree(env, instance.n_nodes); for (u_int i = 0; i < instance.n_nodes; i++) { e_out_degree[i] = IloExpr(env); } for (u_int m = 0; m < n_edges; m++) { const u_int i = edges[m].v1; e_out_degree[i] += xs[m]; } return e_out_degree; }
void CreateSchedulingConstraint(IloModel model, BoolVarMatrix X, BoolVarMatrix Y, IloNumVarArray s, IloRangeArray c){ IloEnv env = model.getEnv(); //sum[i] holds the summation //from eqn-8 for operation i IloExprArray sum(env); //The for-loop encodes all //the execution constraints for(int i = 0; i < X.getSize(); i++){ sum.add(IloExpr(env)); for(int t = 0; t < T_MAX; t++){ X[i].add(IloBoolVar(env)); sum[i] += X[i][t]; c.add( t - s[i+1] - T_MAX*(X[i][t]-1) >= 0); c.add(-t + s[i+1] - T_MAX*(X[i][t]-1) + T >= 1); } c.add(sum[i] == T); } //Resources Constraints IloExprArray summation1(env); IloExprArray summation2(env); for(int t = 0; t < T_MAX; t++){ summation1.add(IloExpr(env)); summation2.add(IloExpr(env)); for(int i = 0; i < X.getSize(); i++){ summation1[t] += X[i][t]; } for(int e = 0; e < Y.getSize(); e++){ summation2[t] += Y[e][t]; } c.add(n_r*summation1[t] + summation2[t] <= n_m*n_r); } return; }
void ScenarioProblem::generateProblem(){ for(int i=0;i<_sp.getSize();i++){ if(i>0){ _sp[i]->generateSubProblem(i,_pd,_scenario,_sp[_sp.getParent(i)]); } else{ _sp[i]->generateSubProblem(i,_pd, _scenario); for(int j=0; j<_pd->getNumberOutages(_scenario) ; j++){ _sp[i]->setOutage(_pd->getOutages(_scenario,j), true); } } try{ addSubProblem(i); } catch (IloEmptyHandleException e) { cout << "An exception occurred. Exception " << e << endl; } } int stage; _sumWeightedDemand=IloExpr(_pd->getEnv()); for(int i=0;i<_sp.getSize();i++){ stage=_sp[i]->getStage(); _sumWeightedDemand += _pd->getObjWeights(stage)*_sp[i]->getSumD(); if(i!=0 && _pd->getReDispatch() && _pd->getPenaltyDispatch() ){ _sumWeightedDemand -= _pd->getPenaltyWeight()*IloSum( _sp[i]->getPDeltaPlus() ); } } }
void CreateMixingBindingConstraint(IloModel model, BoolVarMatrix M, BoolVarMatrix Y, BoolVarMatrix X, IloNumVarArray s, IloRangeArray c){ IloEnv env = model.getEnv(); //sum[i] holds summation from //eqn-13 for operation i IloExprArray sum1(env); //Creating array M[p][i] //i is for ith operation for(int p = 0; p < M.getSize(); p++){ for(int i = 0; i < n; i++) M[p].add(IloBoolVar(env)); } //Ensuring operation remains bound to the same module for(int i = 0; i < n; i++){ sum1.add(IloExpr(env)); for(int p = 0; p < n_m; p++){ sum1[i] += M[p][i]; } c.add(sum1[i] == 1); } //Two operations running simulateneously //can not be bound to the same module for(int p = 0; p < n_m; p++){ for(int t = 0; t < T_MAX; t++){ for(int i = 0; i < n; i++){ for(int j = i+1; j < n; j++){ c.add(X[i][t] + X[j][t] + M[p][i] + M[p][j] <= 3); } } } } return; }
Variables *kMST_ILP::modelMCF() { MCFVariables *v = new MCFVariables(); /***** generic part ***/ const vector<Instance::Edge> edges = directed_edges(instance.edges); const u_int n_edges = edges.size(); /* $x_{ij} \in \{0, 1\}$ variables denote whether edge (i, j) is active. */ v->xs = createVarArrayXs(env, edges, n_edges); /* $v_i \in \{0, 1\}$ variables denote whether node i is active. */ v->vs = createVarArrayVs(env, instance.n_nodes); /* add objective function */ addObjectiveFunction(env, model, v->xs, edges, n_edges); /* There are exactly k - 1 edges not counting edges from the artificial root node 0. */ addConstraint_k_minus_one_active_edges(env,model,v->xs,edges,n_edges,this->k); /* Exactly one node is chosen as the tree root. */ addConstraint_one_active_outgoing_arc_for_node_zero(env,model,v->xs,edges,n_edges); /* No edge leads back to the artificial root node 0. */ addConstraint_no_active_incoming_arc_for_node_zero(env,model,v->xs,edges,n_edges); IloExprArray e_in_degree = createExprArray_in_degree(env, edges, n_edges, v->xs, instance); IloExprArray e_out_degree = createExprArray_out_degree(env, edges, n_edges, v->xs, instance); /* Inactive nodes have no outgoing active edges, active ones at most k - 1. TODO: A tighter bound is to take the sum of incoming goods - 1.*/ addConstraint_bound_on_outgoing_arcs(model,v->vs,e_out_degree,instance,this->k); /* Active nodes have at least one active arc.*/ addConstraint_active_node_at_least_one_active_arc(model,v->vs,e_in_degree, e_out_degree,instance); /* Exactly one incoming edge for an active node and none for an inactive node (omitting artificial root). */ addConstraint_in_degree_one_for_active_node_zero_for_inactive(model,v->vs,e_in_degree,instance); //note: position matters. Tried worse positions than this one /* $\sum_{i > 0} v_i = k$. Ensure that exactly k nodes are active. */ addConstraint_k_nodes_active(env, model, v->vs, instance, this->k); e_in_degree.endElements(); e_out_degree.endElements(); /***** MCF specific part ***/ /* $f^k_{ij} \in \{0, 1\}$ variables denote the flow on edge (i, j) for commodity k. */ for (u_int i = 0; i < instance.n_nodes; i++) { v->fss.push_back(IloBoolVarArray(env, n_edges)); } for (u_int k = 0; k < n_edges; k++) { const u_int i = edges[k].v1; const u_int j = edges[k].v2; for (u_int l = 0; l < (u_int) instance.n_nodes; l++) { v->fss[l][k] = IloBoolVar(env, Tools::indicesToString("f", l, i, j).c_str()); } } /* * Each commodity l is generated once by the artificial root node if node l is active, not at all otherwise: * $\forall l \in \{1, \ldots, n\}: \sum_{j:j>0,(0,j) \in A} f^l_{0j} == v_l$ */ for (u_int c = 1; c < instance.n_nodes; c++){ IloExpr e_one_commodity(env); for (u_int m = 0; m < n_edges; m++) { const u_int i = edges[m].v1; const u_int j = edges[m].v2; if (i == 0 && j > 0){ e_one_commodity += v->fss[c][m]; } } model.add(e_one_commodity == v->vs[c]); e_one_commodity.end(); } /* * The artifical root generates k commodities: * $\forall l \in \{0,\ldots,n\}\sum_{j:j>0,(0,j) \in A} f^l_{0j} = k$. */ IloExpr e_root_generates_k(env); for (u_int c = 0; c < instance.n_nodes; c++){ for (u_int m = 0; m < n_edges; m++) { const u_int i = edges[m].v1; const u_int j = edges[m].v2; if (i == 0 && j > 0){ e_root_generates_k += v->fss[c][m]; } } } model.add(e_root_generates_k == this->k); e_root_generates_k.end(); /* * No commodity is generated for the artificial root: * $\forall i, j: f^0_{ij} = 0$. */ for (u_int m = 0; m < n_edges; m++) { model.add(v->fss[0][m] == 0); } /* * Transmitted commodities end up at the target node: * $\forall l>0: \sum_i f^l_{il} = \sum_j f^l_{0j}$. (here: = v_l) */ for (u_int c = 1; c < (u_int) instance.n_nodes; c++){ IloExpr e_commodity_reaches_target(env); for (u_int m = 0; m < n_edges; m++) { const u_int i = edges[m].v1; const u_int j = edges[m].v2; if (i != c && j == c){ e_commodity_reaches_target += v->fss[c][m]; } } model.add(e_commodity_reaches_target == v->vs[c]); e_commodity_reaches_target.end(); } /* * Once reached, the commodity never leaves the target node: * $\forall l>0: \sum_j f^l_{lj} = 0$. */ for (u_int c = 1; c < (u_int) instance.n_nodes; c++){ IloExpr e_commodity_stays_at_target(env); for (u_int m = 0; m < n_edges; m++) { const u_int i = edges[m].v1; const u_int j = edges[m].v2; if (i == c && j != c){ e_commodity_stays_at_target += v->fss[c][m]; } } model.add(e_commodity_stays_at_target == 0); e_commodity_stays_at_target.end(); } /* * Flow is conserved when not at target node. * $\forall j, l s.t. j \neq l: \sum_i f^l_{ij} = \sum_i f^l_{ji}$. */ for (u_int c = 0; c < (u_int) instance.n_nodes; c++){ IloExprArray e_in_flow(env, instance.n_nodes); IloExprArray e_out_flow(env, instance.n_nodes); for (u_int m = 0; m < instance.n_nodes; m++){ e_in_flow[m] = IloExpr(env); e_out_flow[m] = IloExpr(env); } for (u_int m = 0; m < n_edges; m++) { const u_int i = edges[m].v1; const u_int j = edges[m].v2; e_out_flow[i] += v->fss[c][m]; e_in_flow[j] += v->fss[c][m]; } for (u_int m = 1; m < instance.n_nodes; m++){ if (m != c) { model.add(e_in_flow[m] == e_out_flow[m]); } } e_in_flow.endElements(); e_out_flow.endElements(); } /* * Commodities may only be transmitted on active edges: * $\forall l, i, j: f^l_{ij} \leq x_{ij}$. */ for (u_int c = 0; c < (u_int) instance.n_nodes; c++){ for (u_int m = 0; m < n_edges; m++) { model.add(v->fss[c][m] <= v->xs[m]); } } /* * For each commodity l , the total flow is <= k if node l is active, 0 otherwise * (works well for all before g05, k=n/2 which is a bit slower with this) */ for (u_int c = 1; c < (u_int) instance.n_nodes; c++){ IloExpr e_total_flow(env); for (u_int m = 0; m < n_edges; m++) { e_total_flow += v->fss[c][m]; } model.add(e_total_flow <= this->k * v->vs[c]); e_total_flow.end(); } return v; }