def BRAttackerP(gameModel): source = gameModel.source_list[0] edges = list(gameModel.G.edges()) nodes = list(gameModel.G.nodes()) defender_coverage = gameModel.defender_strategy_set defender_prob = gameModel.defender_prob assert(len(defender_coverage) == len(defender_prob)) resource_list = gameModel.resource_list edge2index = gameModel.edge2index solution_list = [] # =================== attacker CP ================== for j in range(len(gameModel.terminal_list)): # ---------------- tarminal j ------------------ target = gameModel.terminal_list[j] cpo = CpoModel() # cpo.add_parameters(LogVerbosity="Quiet") edge_variables = cpo.binary_var_list(gameModel.m, "gamma") cpo.add(sum([edge_variables[edge2index[source_out]] for source_out in gameModel.G.out_edges(source)]) - sum([edge_variables[edge2index[source_in]] for source_in in gameModel.G.in_edges(source)]) == 1) cpo.add(sum([edge_variables[edge2index[target_out]] for target_out in gameModel.G.out_edges(target)]) - sum([edge_variables[edge2index[target_in]] for target_in in gameModel.G.in_edges(target)]) == -1) for node in nodes: if node == source or node == target: continue else: cpo.add(sum([edge_variables[edge2index[in_edge]] for in_edge in gameModel.G.in_edges(node)]) == sum([edge_variables[edge2index[out_edge]] for out_edge in gameModel.G.out_edges(node)])) # incoming flow == outgoing flow # -------------- computing the objective value ------------- objective_value = 0 for i in range(len(defender_coverage)): success_prob = 1 for r in range(gameModel.R): covering_prob = gameModel.resource_list[r].prob # covering prob # print defender_coverage[i].resource_usage for e_i in range(len(defender_coverage[i].resource_usage[r])): e = defender_coverage[i].resource_usage[r][e_i] success_prob *= (1 - edge_variables[edge2index[e]] * covering_prob) objective_value += success_prob * defender_prob[i] * gameModel.terminal_payoff[j] cpo.add(cpo.maximize(objective_value)) cpo_solution = cpo.solve() if cpo_solution: edge_usage = [edges[i] for i in range(gameModel.m) if cpo_solution[edge_variables[i]] == 1] obj = cpo_solution.get_objective_values() solution_list.append((obj, edge_usage, target, cpo)) else: print("no solution") best_solution = max(solution_list, key=lambda x: x[0]) best_target = best_solution[2] best_cpo = best_solution[3] best_cpo.export_model("attacker.cpo") new_obj = best_solution[0] new_G = nx.DiGraph(best_solution[1]) print("edges:", new_G.edges) new_path = nx.shortest_path(new_G, source, best_target) return new_obj, new_path
def BRDefenderP(gameModel): cpo = CpoModel() # cpo.add_parameters(LogVerbosity="Quiet") edges = list(gameModel.G.edges()) attacker_path = gameModel.attacker_strategy_set attacker_prob = gameModel.attacker_prob assert (len(attacker_path) == len(attacker_prob)) resource_list = gameModel.resource_list edge2index = gameModel.edge2index edge_variables = [] node_variables = [] for i in range(len(resource_list)): tmp_edge_variable_list = cpo.binary_var_list( gameModel.m, "lambda_{0}".format( i)) # the edge variables corresponding to resource i edge_variables.append(tmp_edge_variable_list) tmp_node_variable_list = cpo.binary_var_list( gameModel.n, "lambda_node_{0}".format( i)) # the node variables corresponding to resource i node_variables.append(tmp_node_variable_list) # ---------------- connected edge constraint ---------------- for e in range(gameModel.m): (ns, nt) = edges[e] if gameModel.resource_list[ i].size > 1: # only need connectivity constraints when the resource coverage size is more than 1 ns_incoming_sum = cpo.sum([ edge_variables[i][edge2index[in_edge]] for in_edge in gameModel.G.in_edges(ns) ]) nt_outgoing_sum = cpo.sum([ edge_variables[i][edge2index[out_edge]] for out_edge in gameModel.G.out_edges(nt) ]) cpo.add( edge_variables[i][e] <= ns_incoming_sum + nt_outgoing_sum) # --------------------- node constraint --------------------- cpo.add(edge_variables[i][e] <= node_variables[i][ns]) cpo.add(edge_variables[i][e] <= node_variables[i][nt]) cpo.add(sum(edge_variables[i]) == gameModel.resource_list[i].size) cpo.add(sum(node_variables[i]) == gameModel.resource_list[i].size + 1) # ==================== compute the objective value ===================== objective_value = 0 for j in range(len(attacker_path)): success_prob = 1 # attacker success probability for edge in attacker_path[j].getEdges(): e = edge2index[edge] # edge index for i in range(len(resource_list)): success_prob *= (1 - edge_variables[i][e] * resource_list[i].prob) objective_value += -success_prob * attacker_prob[ j] * gameModel.reward_list[attacker_path[j].path[ -1]] # defender payoff, therefore negative of the attacker payoff cpo.add(cpo.maximize(objective_value)) cpo.export_model("defender.cpo") cpo_solution = cpo.solve() if cpo_solution: coverage = {} for i in range(len(resource_list)): for e in range(gameModel.m): (ns, nt) = edges[e] if cpo_solution[edge_variables[i][e]] == 1: if (ns, nt) in coverage: coverage[(ns, nt)] |= {i} else: coverage[(ns, nt)] = {i} obj = cpo_solution.get_objective_values() return obj, coverage else: print("solution not found!")
vacuumed_at_node = dataPrep.vacuumed_Amount_dict charging_nodes = dataPrep.charging_nodes source_sink_arc_dict = dataPrep.source_sink_arc_dict sink_source_arc_dict = dataPrep.sink_source_arc_dict dirt_plusminus_dict = dataPrep.dirt_plusminus_dict dirt_amount_dict = dataPrep.dirt_amount_dict index_arc_dict = dataPrep.index_arc_dict num_arcs = dataPrep.num_arcs # ----------------------------------------------------------------------------- # Build the model and variables # ----------------------------------------------------------------------------- # Create CPO model mdl = CpoModel() decision_Arcs = mdl.binary_var_list(dataPrep.num_arcs, name='arc') # nested integer_cplex_list for dis+, dis-, decision_dirt_plus = mdl.integer_var_list(len(dataPrep.valid_nodes) * numScenarios, min=0, name='dplus') decision_dirt_minus = mdl.integer_var_list(len(dataPrep.valid_nodes) * numScenarios, min=0, max=1000, name='dminus') # ----------------------------------------------------------------------------- # Build the constraints
nodeList[0])] dirtIndex += 1 # ----------------------------------------------------------------------------- # Build the model and variables # ----------------------------------------------------------------------------- # Create CPO model mdl = CpoModel() # x_ij = mdl.binary_var_dict((source, sink) for source in ) num_arcs = 0 for arc in arclist: num_arcs = num_arcs + len(arc) - 1 decision_Arcs = mdl.binary_var_list(num_arcs, name='arc') # nested integer_cplex_list for dis+, dis-, decision_dirt_plus = mdl.integer_var_list(len(valid_nodes) * numScenarios, min=0, name='dplus') decision_dirt_minus = mdl.integer_var_list(len(valid_nodes) * numScenarios, min=0, name='dminus') # ----------------------------------------------------------------------------- # Build the constraints # ----------------------------------------------------------------------------- # constraint 2, 3 for source in source_sink_arc_dict:
class CPLEX: def __init__(self, fp_listCplexParameters, fp_obInstance): ''' @fp_listCplexParameters: [0:iCandidateFaciNum, 1:fAlpha] ''' self.iCandidateFaciNum = fp_listCplexParameters[0] self.fAlpha = fp_listCplexParameters[1] self.obInstance = fp_obInstance self.model = Model() self.cpomodel = CpoModel() def fun_fillMpModel(self): # creat decision variables list listDeciVarX = self.model.binary_var_list(self.iCandidateFaciNum, lb=0, name='X') listDeciVarY = self.model.binary_var_list(pow(self.iCandidateFaciNum, 3), lb=0, name='Y') # construct objective function objFunction = 0 for i in range(self.iCandidateFaciNum): objFunction += self.obInstance.aiFixedCost[i] * listDeciVarX[i] listTranCost = [] for i in range(self.iCandidateFaciNum): for j in range(self.iCandidateFaciNum): for r in range(2): # 只分配两个设施 fTranCost = self.fAlpha * self.obInstance.aiDemands[ i] * self.obInstance.af_2d_TransCost[i][j] * pow( self.obInstance.fFaciFailProb, r) * (1 - self.obInstance.fFaciFailProb) listTranCost.append(fTranCost) objFunction += fTranCost * listDeciVarY[ pow(self.iCandidateFaciNum, 2) * i + self.iCandidateFaciNum * j + r] # for i in range(pow(self.iCandidateFaciNum, 2) * 2): # objFunction += listTranCost[i] * listDeciVarY[i] self.model.minimize(objFunction) # add constraints for i in range(self.iCandidateFaciNum): for r in range(2): # 只分配两个设施 cons1 = 0 for j in range(self.iCandidateFaciNum): cons1 += listDeciVarY[i * pow(self.iCandidateFaciNum, 2) + j * self.iCandidateFaciNum + r] self.model.add_constraint(cons1 == 1) # constraint 1 for i in range(self.iCandidateFaciNum): for j in range(self.iCandidateFaciNum): cons3 = 0 for r in range(2): # 只分配两个设施 cons3 += listDeciVarY[i * pow(self.iCandidateFaciNum, 2) + j * self.iCandidateFaciNum + r] self.model.add_constraint( cons3 <= listDeciVarX[j]) # constraint 3 cons4 = 0 cons4 = sum(listDeciVarX) # for j in range(self.iCandidateFaciNum): # cons4 += listDeciVarX[j] self.model.add_constraint(cons4 >= 2) def fun_fillMpModel_AlloAllSelcFaci(self): # creat decision variables list listDeciVarX = self.model.binary_var_list(self.iCandidateFaciNum, lb=0, name='X') listDeciVarY = self.model.binary_var_list(pow(self.iCandidateFaciNum, 3), lb=0, name='Y') # construct objective function objFunction = 0 for i in range(self.iCandidateFaciNum): objFunction += self.obInstance.aiFixedCost[i] * listDeciVarX[i] listTranCost = [] for i in range(self.iCandidateFaciNum): for j in range(self.iCandidateFaciNum): for r in range(self.iCandidateFaciNum): # 不只分配两个设施 fTranCost = self.fAlpha * self.obInstance.aiDemands[ i] * self.obInstance.af_2d_TransCost[i][j] * pow( self.obInstance.fFaciFailProb, r) * (1 - self.obInstance.fFaciFailProb) listTranCost.append(fTranCost) objFunction += fTranCost * listDeciVarY[ pow(self.iCandidateFaciNum, 2) * i + self.iCandidateFaciNum * j + r] # for i in range(pow(self.iCandidateFaciNum, 2) * 2): # objFunction += listTranCost[i] * listDeciVarY[i] self.model.minimize(objFunction) # add constraints # constraint a for i in range(self.iCandidateFaciNum): consAleft = sum(listDeciVarY[pow(self.iCandidateFaciNum, 2) * i:(pow(self.iCandidateFaciNum, 2) * (i + 1) - 1)]) consAright = sum(listDeciVarX) self.model.add_constraint(consAleft == consAright) # constraint b for i in range(self.iCandidateFaciNum): for r in range(self.iCandidateFaciNum): consB = 0 for j in range(self.iCandidateFaciNum): consB += listDeciVarY[pow(self.iCandidateFaciNum, 2) * i + self.iCandidateFaciNum * j + r] self.model.add_constraint(consB <= 1) # constraint c for i in range(self.iCandidateFaciNum): for r in range(1, self.iCandidateFaciNum): consCleft = 0 consCright = 0 for j in range(self.iCandidateFaciNum): consCleft += listDeciVarY[pow(self.iCandidateFaciNum, 2) * i + self.iCandidateFaciNum * j + r] consCright += listDeciVarY[pow(self.iCandidateFaciNum, 2) * i + self.iCandidateFaciNum * j + r - 1] self.model.add_constraint(consCleft <= consCright) # constraint d for i in range(self.iCandidateFaciNum): for j in range(self.iCandidateFaciNum): for r in range(self.iCandidateFaciNum): self.model.add_constraint( listDeciVarY[pow(self.iCandidateFaciNum, 2) * i + self.iCandidateFaciNum * j + r] <= listDeciVarX[j]) # # constraint e for i in range(self.iCandidateFaciNum): for j in range(self.iCandidateFaciNum): consE = 0 for r in range(self.iCandidateFaciNum): consE += listDeciVarY[pow(self.iCandidateFaciNum, 2) * i + self.iCandidateFaciNum * j + r] self.model.add_constraint(consE == listDeciVarX[j]) # constraint 4 cons4 = sum(listDeciVarX) self.model.add_constraint(cons4 >= 2) def fun_fillMpModel_Allo2ToAllSelcFaci(self): # creat decision variables list listDeciVarX = self.model.binary_var_list(self.iCandidateFaciNum, lb=0, name='X') listDeciVarY = self.model.binary_var_list(pow(self.iCandidateFaciNum, 3), lb=0, name='Y') # construct objective function objFunction = 0 for i in range(self.iCandidateFaciNum): objFunction += self.obInstance.aiFixedCost[i] * listDeciVarX[i] listTranCost = [] for i in range(self.iCandidateFaciNum): for j in range(self.iCandidateFaciNum): for r in range(2): # 只分配两个设施,可改为2~all间的别的数字 fTranCost = self.fAlpha * self.obInstance.aiDemands[ i] * self.obInstance.af_2d_TransCost[i][j] * pow( self.obInstance.fFaciFailProb, r) * (1 - self.obInstance.fFaciFailProb) listTranCost.append(fTranCost) objFunction += fTranCost * listDeciVarY[ pow(self.iCandidateFaciNum, 2) * i + self.iCandidateFaciNum * j + r] # for i in range(pow(self.iCandidateFaciNum, 2) * 2): # objFunction += listTranCost[i] * listDeciVarY[i] self.model.minimize(objFunction) # add constraints # constraint a for i in range(self.iCandidateFaciNum): consAleft = sum(listDeciVarY[pow(self.iCandidateFaciNum, 2) * i:(pow(self.iCandidateFaciNum, 2) * (i + 1) - 1)]) consAright = sum(listDeciVarX) self.model.add_constraint(consAleft <= consAright) self.model.add_constraint(consAleft >= 2) # constraint b for i in range(self.iCandidateFaciNum): for r in range(self.iCandidateFaciNum): consB = 0 for j in range(self.iCandidateFaciNum): consB += listDeciVarY[pow(self.iCandidateFaciNum, 2) * i + self.iCandidateFaciNum * j + r] self.model.add_constraint(consB <= 1) # constraint c for i in range(self.iCandidateFaciNum): for r in range(1, self.iCandidateFaciNum): consCleft = 0 consCright = 0 for j in range(self.iCandidateFaciNum): consCleft += listDeciVarY[pow(self.iCandidateFaciNum, 2) * i + self.iCandidateFaciNum * j + r] consCright += listDeciVarY[pow(self.iCandidateFaciNum, 2) * i + self.iCandidateFaciNum * j + r - 1] self.model.add_constraint(consCleft <= consCright) # constraint d for i in range(self.iCandidateFaciNum): for j in range(self.iCandidateFaciNum): for r in range(self.iCandidateFaciNum): self.model.add_constraint( listDeciVarY[pow(self.iCandidateFaciNum, 2) * i + self.iCandidateFaciNum * j + r] <= listDeciVarX[j]) # # constraint e for i in range(self.iCandidateFaciNum): for j in range(self.iCandidateFaciNum): consE = 0 for r in range(self.iCandidateFaciNum): consE += listDeciVarY[pow(self.iCandidateFaciNum, 2) * i + self.iCandidateFaciNum * j + r] self.model.add_constraint(consE <= listDeciVarX[j]) # constraint 4 cons4 = sum(listDeciVarX) self.model.add_constraint(cons4 >= 2) def fun_fillCpoModel(self): # creat decision variables list listDeciVarX = self.cpomodel.binary_var_list(self.iCandidateFaciNum, name='X') listDeciVarY = self.cpomodel.binary_var_list(pow( self.iCandidateFaciNum, 3), name='Y') # construct objective function objFunction = 0 for i in range(self.iCandidateFaciNum): objFunction += self.obInstance.aiFixedCost[i] * listDeciVarX[i] listTranCost = [] for i in range(self.iCandidateFaciNum): for j in range(self.iCandidateFaciNum): for r in range(2): # 只分配两个设施 fTranCost = self.fAlpha * self.obInstance.aiDemands[ i] * self.obInstance.af_2d_TransCost[i][j] * pow( self.obInstance.fFaciFailProb, r) * (1 - self.obInstance.fFaciFailProb) listTranCost.append(fTranCost) objFunction += fTranCost * listDeciVarY[ pow(self.iCandidateFaciNum, 2) * i + self.iCandidateFaciNum * j + r] # for i in range(pow(self.iCandidateFaciNum, 2) * 2): # objFunction += listTranCost[i] * listDeciVarY[i] self.cpomodel.add(self.cpomodel.minimize(objFunction)) # add constraints for i in range(self.iCandidateFaciNum): for r in range(2): # 只分配两个设施 cons1 = 0 for j in range(self.iCandidateFaciNum): cons1 += listDeciVarY[i * pow(self.iCandidateFaciNum, 2) + j * self.iCandidateFaciNum + r] self.cpomodel.add(cons1 == 1) # constraint 1 for i in range(self.iCandidateFaciNum): for j in range(self.iCandidateFaciNum): cons3 = 0 for r in range(2): # 只分配两个设施 cons3 += listDeciVarY[i * pow(self.iCandidateFaciNum, 2) + j * self.iCandidateFaciNum + r] self.cpomodel.add(cons3 <= listDeciVarX[j]) # constraint 3 cons4 = 0 for j in range(self.iCandidateFaciNum): cons4 += listDeciVarX[j] self.cpomodel.add(cons4 >= 2)