Multi-scenario infeasible
Answered
"""
-*- coding: utf-8 -*-
@Author : CWLLC
@Time : 2024/4/11 10:44
@File : test.py
"""
import gurobipy as gp
from gurobipy import GRB
import pandas as pd
import numpy as np
import networkx as nx
import copy
import math
from matplotlib import pyplot as plt
# 节点属性
# 节点ID
Demand_Node_Set = [10, 11, 12, 13, 21, 22, 23, 31, 32]
Demand_Node_Set = list(map(str, Demand_Node_Set))
Reservoir_Node_Set = [9, 2]
Reservoir_Node_Set = list(map(str, Reservoir_Node_Set))
Node_Set = Demand_Node_Set + Reservoir_Node_Set
Demand_Node_Attributes = pd.DataFrame(0, index=Demand_Node_Set, columns=['Demand', 'Head_Upper', 'Head_Lower'])
Reservoir_Node_Attributes = pd.DataFrame(0, index=Reservoir_Node_Set, columns=['Head_Upper', 'Head_Lower'])
# 节点需求
Demand_Node_Attributes.loc['10', 'Demand'] = 0
Demand_Node_Attributes.loc['11', 'Demand'] = 150
Demand_Node_Attributes.loc['12', 'Demand'] = 150
Demand_Node_Attributes.loc['13', 'Demand'] = 100
Demand_Node_Attributes.loc['21', 'Demand'] = 150
Demand_Node_Attributes.loc['22', 'Demand'] = 200
Demand_Node_Attributes.loc['23', 'Demand'] = 150
Demand_Node_Attributes.loc['31', 'Demand'] = 100
Demand_Node_Attributes.loc['32', 'Demand'] = 100
# 节点水头范围
Demand_Node_Attributes.loc[:, 'Head_Upper'] = 950000000
Demand_Node_Attributes.loc[:, 'Head_Lower'] = 0
# 水库水头范围
Reservoir_Node_Attributes.loc['9', 'Head_Upper'] = 1000000000
Reservoir_Node_Attributes.loc['2', 'Head_Upper'] = 9700000000
Reservoir_Node_Attributes.loc['9', 'Head_Lower'] = 600
Reservoir_Node_Attributes.loc['2', 'Head_Lower'] = 700
# 管道属性
Pipe_ID_Set = [10, 11, 12, 21, 22, 31, 110, 111, 112, 113, 121, 122]
Pipe_Set = pd.DataFrame(0, index=Node_Set, columns=Node_Set)
Pipe_Length_Set = pd.DataFrame(0, index=Node_Set, columns=Node_Set, dtype=float)
Pipe_Diameter_Set = pd.DataFrame(0, index=Node_Set, columns=Node_Set, dtype=float)
Pipe_Roughness_Set = pd.DataFrame(0, index=Node_Set, columns=Node_Set)
Pipe_Flow_Upper_Set = pd.DataFrame(0, index=Node_Set, columns=Node_Set, dtype=float)
Pipe_Flow_Lower_Set = pd.DataFrame(0, index=Node_Set, columns=Node_Set, dtype=float)
# 管道定义
Pipe_Set.loc['10', '11'] = 1
Pipe_Set.loc['11', '12'] = 1
Pipe_Set.loc['12', '13'] = 1
Pipe_Set.loc['21', '22'] = 1
Pipe_Set.loc['22', '23'] = 1
Pipe_Set.loc['31', '32'] = 1
Pipe_Set.loc['2', '12'] = 1
Pipe_Set.loc['11', '21'] = 1
Pipe_Set.loc['12', '22'] = 1
Pipe_Set.loc['13', '23'] = 1
Pipe_Set.loc['21', '31'] = 1
Pipe_Set.loc['22', '32'] = 1
Pipe_Set.loc['9', '10'] = 1
# 最大连接定义
Edge_Max_Set = pd.DataFrame(0, index=Node_Set, columns=Node_Set)
Edge_Max_Set.loc['12', '23'] = 1
Edge_Max_Set.loc['11', '22'] = 1
Edge_Max_Set.loc['21', '32'] = 1
# 定义管道长度
Pipe_Length_Set.loc['10', '11'] = 105.3
Pipe_Length_Set.loc['11', '12'] = 52.8
Pipe_Length_Set.loc['12', '13'] = 52.8
Pipe_Length_Set.loc['21', '22'] = 52.8
Pipe_Length_Set.loc['22', '23'] = 52.8
Pipe_Length_Set.loc['31', '32'] = 52.8
Pipe_Length_Set.loc['2', '12'] = 2
Pipe_Length_Set.loc['11', '21'] = 52.8
Pipe_Length_Set.loc['12', '22'] = 52.8
Pipe_Length_Set.loc['13', '23'] = 52.8
Pipe_Length_Set.loc['21', '31'] = 52.8
Pipe_Length_Set.loc['22', '32'] = 52.8
Pipe_Length_Set.loc['9', '10'] = 10
# 定义管道直径
Pipe_Diameter_Set.loc['10', '11'] = 0.18
Pipe_Diameter_Set.loc['11', '12'] = 0.14
Pipe_Diameter_Set.loc['12', '13'] = 0.10
Pipe_Diameter_Set.loc['21', '22'] = 0.10
Pipe_Diameter_Set.loc['22', '23'] = 0.12
Pipe_Diameter_Set.loc['31', '32'] = 0.06
Pipe_Diameter_Set.loc['2', '12'] = 0.18
Pipe_Diameter_Set.loc['11', '21'] = 0.10
Pipe_Diameter_Set.loc['12', '22'] = 0.12
Pipe_Diameter_Set.loc['13', '23'] = 0.08
Pipe_Diameter_Set.loc['21', '31'] = 0.08
Pipe_Diameter_Set.loc['22', '32'] = 0.06
Pipe_Diameter_Set.loc['9', '10'] = 0.10
# 定义粗糙系数
Pipe_Roughness_Set.loc['10', '11'] = 100
Pipe_Roughness_Set.loc['11', '12'] = 100
Pipe_Roughness_Set.loc['12', '13'] = 100
Pipe_Roughness_Set.loc['21', '22'] = 100
Pipe_Roughness_Set.loc['22', '23'] = 100
Pipe_Roughness_Set.loc['31', '32'] = 100
Pipe_Roughness_Set.loc['2', '12'] = 100
Pipe_Roughness_Set.loc['11', '21'] = 100
Pipe_Roughness_Set.loc['12', '22'] = 100
Pipe_Roughness_Set.loc['13', '23'] = 100
Pipe_Roughness_Set.loc['21', '31'] = 100
Pipe_Roughness_Set.loc['22', '32'] = 100
Pipe_Roughness_Set.loc['9', '10'] = 100
for i in Node_Set:
for j in Node_Set:
if Pipe_Set.loc[i, j] != 0:
Pipe_Set.loc[j, i] = Pipe_Set.loc[i, j]
if Edge_Max_Set.loc[i, j] != 0:
Edge_Max_Set.loc[j, i] = Edge_Max_Set.loc[i, j]
if Pipe_Length_Set.loc[i, j] != 0:
Pipe_Length_Set.loc[j, i] = Pipe_Length_Set.loc[i, j]
if Pipe_Diameter_Set.loc[i, j] != 0:
Pipe_Diameter_Set.loc[j, i] = Pipe_Diameter_Set.loc[i, j]
if Pipe_Roughness_Set.loc[i, j] != 0:
Pipe_Roughness_Set.loc[j, i] = Pipe_Roughness_Set.loc[i, j]
# 管道流量界限
for i in Node_Set:
for j in Node_Set:
Pipe_Flow_Upper_Set.loc[i, j] = math.pi/4*Pipe_Diameter_Set.loc[i, j]**2*10*3600
M = 10**8
eps = 0.0001
n_a = 2
n_f = 2
n_b = 2
n_r = 2
n_all = 3
# 建立模型
model = gp.Model('WDN')
# 变量声明
# 添加水库工作变量
Reservoir_Operation = model.addVars(Reservoir_Node_Set, vtype = GRB.BINARY, name = "Reservoir_Operation")
# 添加管道流量变量
Flow_Rate = model.addVars(Node_Set, Node_Set, vtype = GRB.CONTINUOUS, lb = -GRB.INFINITY,name = "Flow_Rate")
# 添加水流流向变量
Flow_Direction_From_To = model.addVars(Node_Set, Node_Set, vtype=GRB.BINARY, name = "Flow_Direction_FT")
Flow_Direction_To_From = model.addVars(Node_Set, Node_Set, vtype=GRB.BINARY, name = "Flow_Direction_TF")
# 添加节点外流流量变量
Out_Flow_Rate = model.addVars(Node_Set, vtype = GRB.CONTINUOUS, lb = -GRB.INFINITY, name = "Out_Flow_Rate")
# 添加节点水头变量
Node_Head = model.addVars(Node_Set, vtype = GRB.CONTINUOUS, name = "Node_Head")
# 添加攻击变量
Attack = model.addVars(Node_Set, Node_Set, vtype = GRB.BINARY,name = "Attack")
# 添加防御变量
Fortify = model.addVars(Node_Set, Node_Set, vtype = GRB.BINARY,name = "Fortify")
Replace = model.addVars(Node_Set, Node_Set, vtype = GRB.BINARY,name = "Replace")
New_Build = model.addVars(Node_Set, Node_Set, vtype = GRB.BINARY,name = "New_Build")
New_Diameter = model.addVars(Node_Set, Node_Set, vtype = GRB.CONTINUOUS,name = "New_Diameter")
Diameter_Choice = model.addVars(Node_Set, Node_Set, vtype=GRB.BINARY, name="Diameter_Choice")
New_Flow_Upper_Bound = model.addVars(Node_Set, Node_Set, vtype = GRB.CONTINUOUS,name = "New_Flow_Upper_Bound")
New_Flow_Lower_Bound = model.addVars(Node_Set, Node_Set, vtype = GRB.CONTINUOUS,name = "New_Flow_Lower_Bound")
# 添加指示变量
Replace_Direction = model.addVars(Node_Set, Node_Set, vtype = GRB.BINARY, name = "Replace_Direction")
Old_Direction = model.addVars(Node_Set, Node_Set, vtype = GRB.BINARY, name = "Old_Direction")
New_Build_Direction = model.addVars(Node_Set, Node_Set, vtype = GRB.BINARY, name = "New_Build_Direction")
Node_Change = model.addVars(Node_Set, Node_Set, vtype = GRB.BINARY, name = "Node_Change")
Construct = model.addVars(Node_Set, Node_Set, vtype = GRB.BINARY, name = "Construct")
Replace_Flow_Assistance = model.addVars(Node_Set, Node_Set, vtype = GRB.CONTINUOUS, name = "Replace Flow Assistance")
d_0 = 0.1
d_1 = 0.5
model.update()
# 添加约束
# 节点流量守恒约束
model.addConstrs((Out_Flow_Rate[i] + Flow_Rate.sum(i, '*') == 0 for i in Node_Set), name = "Node Flow Consistent Constrains")
# 节点流量范围约束
model.addConstrs((Out_Flow_Rate[i] <= Demand_Node_Attributes.loc[i, 'Demand'] for i in Demand_Node_Set), name = "Node Demand Bound Constrains")
model.addConstrs((Out_Flow_Rate[i] >= 0 for i in Demand_Node_Set), name = "Demand Node Outflow Bound Constrains")
model.addConstrs((Out_Flow_Rate[i] <= 0 for i in Reservoir_Node_Set), name = "Reservoir Node Outflow Bound Constrains")
# 水流方向约束
model.addConstrs((Flow_Rate[i, j] >= eps - M*(1-Flow_Direction_From_To[i,j]) for i in Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == 1), name='From to')
model.addConstrs((Flow_Rate[i, j] <= M*Flow_Direction_From_To[i,j] for i in Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == 1), name='From to')
model.addConstrs((Flow_Rate[i, j] <= -eps + M*(1-Flow_Direction_To_From[i,j]) for i in Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == 1), name='To from')
model.addConstrs((Flow_Rate[i, j] >= -M*Flow_Direction_To_From[i,j] for i in Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == 1), name='To from')
# 添加攻击约束
model.addConstrs((Attack[i,j] == Attack[j,i] for i in Node_Set for j in Node_Set), name = "Attack Constrains")
model.addConstrs((Attack[i,j] <= Pipe_Set.loc[i, j] for i in Node_Set for j in Node_Set), name = "Attack Constrains")
# Fortify约束
model.addConstrs((Fortify[i, j] == Fortify[j,i] for i in Node_Set for j in Node_Set), name = "Fortify Constrains")
model.addConstrs((Fortify[i, j] == 0 for i in Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == 0), name="Fortify Constrains")
model.addConstr((Fortify.sum() <= 2*n_f), name="Fortify Number Constrains")
# Replace约束
model.addConstrs((Replace[i, j] == Replace[j,i] for i in Node_Set for j in Node_Set), name = "Replace Constrains")
model.addConstrs((Replace[i, j] == 0 for i in Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == 0), name="Replace Constrains")
model.addConstr((Replace.sum() == 2*n_r), name="Replace Number Constrains")
# New Built约束
model.addConstrs((New_Build[i, j] == New_Build[j,i] for i in Node_Set for j in Node_Set), name = "New Build Constrains")
model.addConstrs((New_Build[i, j] == 0 for i in Node_Set for j in Node_Set if Edge_Max_Set.loc[i, j] == 0), name = "New Build Constrains")
model.addConstr((New_Build.sum() <= 2*n_b), name="New Built Number Constrains")
# 相互关系约束
model.addConstrs((Flow_Direction_To_From[i,j] + Flow_Direction_From_To[i,j] <= 1-Attack[i,j] + Fortify[i, j] + Replace[i, j] for i in Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == 1), name = "Out Of Service Constrains")
model.addConstrs((Flow_Direction_To_From[i,j] + Flow_Direction_From_To[i,j] <= New_Build[i, j] for i in Node_Set for j in Node_Set if Edge_Max_Set.loc[i, j] == 1), name = "Out Of Service Constrains")
model.addConstrs((Fortify[i, j] + Replace[i, j] <= 1 for i in Node_Set for j in Node_Set), name="Defense between fortify and replace Constrains")
# 管道直径选择约束
model.addConstrs((Construct[i, j] == gp.or_(Replace[i, j], New_Build[i, j]) for i in Node_Set for j in Node_Set))
model.addConstrs(((Construct[i, j] == 1) >> (New_Diameter[i, j] == Diameter_Choice[i, j]*d_0 + (1-Diameter_Choice[i, j])*d_1) for i in Node_Set for j in Node_Set), name="New Diameter Constrains")
model.addConstrs(((Construct[i, j] == 0) >> (New_Diameter[i, j] == 0) for i in Node_Set for j in Node_Set), name="New Diameter Constrains")
# 新管道流量范围
model.addConstrs((New_Flow_Upper_Bound[i, j] == (math.pi/4*New_Diameter[i, j]*New_Diameter[i, j]*10*3600) for i in Node_Set for j in Node_Set), name="New Flow Upper Bound")
model.addConstrs((New_Flow_Lower_Bound[i, j] == 0*(Replace[i, j] + New_Build[i, j]) for i in Node_Set for j in Node_Set), name="New Flow Lower Bound")
# 管道流量范围约束
## Replace 管道流量
model.addConstrs((Replace_Direction[i, j] == gp.and_(Flow_Direction_From_To[i, j], Replace[i, j]) for i in Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == 1))
model.addConstrs(((Replace_Direction[i, j]==1) >> (Flow_Rate[i, j] <= New_Flow_Upper_Bound[i, j]) for i in Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == 1), name = "New Pipe Flow Upper Bound Constrains")
model.addConstrs(((Replace_Direction[i, j]==1) >> (Flow_Rate[i, j] >= New_Flow_Lower_Bound[i, j]) for i in Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == 1), name = "New Pipe Flow Lower Bound Constrains")
## Unchanged 管道流量
model.addConstrs((Old_Direction[i, j] == (1 - Replace[i, j])*Flow_Direction_From_To[i, j] for i in Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == [1]))
model.addConstrs(((Old_Direction[i, j] == 1) >> (Flow_Rate[i, j] <= Pipe_Flow_Upper_Set.loc[i, j]) for i in Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == 1), name = "Pipe Flow Upper Bound Constrains")
model.addConstrs(((Old_Direction[i, j] == 1) >> (Flow_Rate[i, j] >= Pipe_Flow_Lower_Set.loc[i, j]) for i in Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == 1), name = "Pipe Flow Lower Bound Constrains")
## New build 管道流量
model.addConstrs((New_Build_Direction[i, j] == gp.and_(New_Build[i, j], Flow_Direction_From_To[i, j]) for i in Node_Set for j in Node_Set if Edge_Max_Set.loc[i, j] == 1))
model.addConstrs(((New_Build_Direction[i, j]==1) >> (Flow_Rate[i, j] <= New_Flow_Upper_Bound[i, j]) for i in Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == 1), name = "New Pipe Flow Upper Bound Constrains")
model.addConstrs(((New_Build_Direction[i, j]==1) >> (Flow_Rate[i, j] >= New_Flow_Lower_Bound[i, j]) for i in Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == 1), name = "New Pipe Flow Lower Bound Constrains")
model.addConstrs((Flow_Rate[i, j] + Flow_Rate[j, i] == 0 for i in Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == 1), name = "f_ij = -f_ji")
model.addConstrs((Flow_Rate[i, j] == 0 for i in Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == 0))
# 节点水头约束
## 旧节点
model.addConstrs((Node_Head[i] <= Demand_Node_Attributes.loc[i, 'Head_Upper'] for i in Demand_Node_Set), name = "Demand Node Head Upper Bound")
model.addConstrs((Node_Head[i] >= Demand_Node_Attributes.loc[i, 'Head_Lower'] for i in Demand_Node_Set), name = "Demand Node Head Lower Bound")
model.addConstrs((Node_Head[i] <= Reservoir_Node_Attributes.loc[i, 'Head_Upper'] for i in Reservoir_Node_Set), name = "Reservoir Node Head Upper Bound")
model.addConstrs((Node_Head[i] >= Reservoir_Node_Attributes.loc[i, 'Head_Lower'] for i in Reservoir_Node_Set), name = "Reservoir Node Head Lower Bound")
## 新节点
# 水头损失约束
# 旧管道
model.addConstrs(((Node_Head[i] - Node_Head[j])*(Flow_Direction_From_To[i, j]-Flow_Direction_To_From[i, j]) == 10.654 * Pipe_Roughness_Set.loc[i, j]**(-1.852) * Flow_Rate[i, j]*Flow_Rate[i, j] / Pipe_Diameter_Set.loc[i, j]**4.87 for i in Node_Set for j in Node_Set if Pipe_Set.loc[i,j] == 1), name = "Head Loss")
## New built 管道
model.addConstrs((Replace_Flow_Assistance[i,j] == 10.654 * Pipe_Roughness_Set.loc[i, j]**(-1.852) * Flow_Rate[i, j]*Flow_Rate[i, j] / d_0**4.87 for i in Node_Set for j in Node_Set if Pipe_Set.loc[i,j] == 1))
model.addConstrs((Replace_Direction[i, j] == 1) >> (Node_Head[i] - Node_Head[j] == Replace_Flow_Assistance[i, j]) for i in Node_Set for j in Node_Set)
# 水库工作约束
model.addConstrs((Out_Flow_Rate[i] <= 0 for i in Reservoir_Node_Set), name = "Reservoir Node Working Flow")
model.addConstrs((Flow_Rate[i, j] >= 0 for i in Reservoir_Node_Set for j in Node_Set if Pipe_Set.loc[i,j] == 0), name = "Reservoir Node Working Flow")
model.addConstrs((Flow_Rate[i, j] <= M*Reservoir_Operation[i] for i in Reservoir_Node_Set for j in Node_Set if Pipe_Set.loc[i,j] == 0), name = "Reservoir Node Working Flow")
model.addConstrs((Out_Flow_Rate[i] >= -Reservoir_Operation[i]*sum(Pipe_Flow_Upper_Set.loc[i]) for i in Reservoir_Node_Set), name = "Reservoir Node Working Flow")
model.addConstrs((Node_Head[j] <= Reservoir_Operation[i]*Node_Head[i] + (1-Reservoir_Operation[i])*Demand_Node_Attributes.loc[j, 'Head_Upper'] for i in Reservoir_Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == 1), name = 'Reservoir Node Working Head')
# Scenario setting
Attack_base = model.addConstrs((Attack[i, j] == 0 for i in Node_Set for j in Node_Set if Pipe_Set.loc[i, j] == 1), 'Attack Base')
Attack_num = model.addConstr((Attack.sum() <= 2*n_a), name="Attack Number Constrains")
# model.addConstr(Attack_base['10', '11'] == 1)
# Attack_base = model.addConstrs((Attack[i, j] == 0 for i in attack_list), name = 'test')
# Scenario
model.NumScenarios = 2
# Scenario 0
model.Params.ScenarioNumber = 0
model.ScenNName = "pipe (10, 11), (12, 11)"
Attack_base['10', '11'].ScenNRhs = 1
Attack_base['12', '11'].ScenNRhs = 1
# Scenario 1
model.Params.ScenarioNumber = 1
model.ScenNName = "pipe (9, 10), (32, 31)"
# Attack_base['10', '11'].ScenNRhs = 0
# Attack_base['12', '11'].ScenNRhs = 0
Attack_base['10', '9'].ScenNRhs = 1
Attack_base['32', '31'].ScenNRhs = 1
model.update()
# 模型目标函数
model.setObjective((sum(Out_Flow_Rate[i]*1/Demand_Node_Attributes.loc[i, 'Demand'] for i in Demand_Node_Set if Demand_Node_Attributes.loc[i, 'Demand'] != 0)), GRB.MAXIMIZE)
model.update()
model.write('test.lp')
model.optimize()
-
The first scenario is not feasible. Try replacing the scenario-related lines by
# Scenario 0
Attack_base['10', '11'].Rhs = 1
Attack_base['12', '11'].Rhs = 1
model.update()This will lead to an infeasible/unbounded model.
Have a look at this article for more hints on debugging that scenario. Hint: generating the IIS and writing it to a file will help you identify the problem :-)
Kind regards,
Ronald0 -
# Scenario 0
model.Params.ScenarioNumber = 0
model.ScenNName = "pipe (10, 11), (12, 11)"
Attack_base['10', '11'].ScenNRhs = 1
Attack_base['12', '11'].ScenNRhs = 1
model.update()
# Scenario 1
model.Params.ScenarioNumber = 1
model.ScenNName = "pipe (9, 10), (32, 31)"
# Attack_base['10', '9'].ScenNRhs = 1
# Attack_base['32', '31'].ScenNRhs = 1Thank you for your reply. But it seems still not work. I have checked it. In this way (as the picture or code above shows)the model is feasible actually. And what's the difference between Rhs and ScenNRhs when I want to change the right hands of a constrain in a scenario? The example multiscenario.py uses ScenNRhs? Thanks again for your help.
0 -
There's a caveat here (please refer to this page in the documentation on the meaning of the model status for multi-scenario models):
A status of
OPTIMAL
indicates that optimal solutions were found (subject to tolerances) for all scenarios that have feasible solutions, and that the other scenarios were determined to be infeasible.So, although the log file suggests that "something" was optimal, this actually refers to the solution of the second scenario even though the first scenario is actually infeasible.
When you iterate over the scenarios and query the ScenNObjVal/ScenNObjBound attributes of the model, you will see that these are (negative) infinity for the first scenario when running your code, indicating that this scenario is infeasible.
for i in range(model.NumScenarios):
model.Params.ScenarioNumber = i
print(f'Scenario {i}: obj={model.ScenNObjVal}, bound={model.ScenNObjBound}')Similarly, when you make the change I suggested earlier (solve only a single model with no scenarios), you will see the infeasibility reported as the status and explained in the ILP file that is being generated:
Maximize
Subject To
Attack_Constrains[10,11]: Attack[10,11] - Attack[11,10] = 0
Attack_Base[10,11]: Attack[10,11] = 1
Attack_Base[11,10]: Attack[11,10] = 0
Bounds
Binaries
Attack[10,11] Attack[11,10]
End0 -
Thank you very much. I have solved my problem.
0
Please sign in to leave a comment.
Comments
4 comments