Implementing a 'such that' constraint in pyomo - pyomo

I am new to pyomo and would like to implement the following AMPL constraint:
param Tele=48;
set T=1..Tele; #set of epochs
set A ordered; #set of appliances
var active{A,T}, binary;
param d{A}>=0;
subject to max_duration{a in A, t in T, ti in T:t>ti}:
active[a,t]*t-active[a,ti]*ti<=d[a]*(1- Tele*(active[a,t]+active[a,ti]-2));
I am confused about how to implement the 'such that' condition t in T, ti in T:t>ti of the constraint. Would it involve defining a new set Tcomp along these lines (but unsure how to handle the else case here):
def tlarge_rule(m, t1, t2):
if t1 > t2:
return (t1,t2)
model.Tcomp = Set(model.T, model.T, initialize=tlarge_rule)
Another query I have is with regards to the most suitable (open-source) pyomo solver for large-scale MILP optimisation (as I not able to use Gurobi in my project). Can GLPK or CBC handle such optimisations (or is there another open-source solver that is more suitable)?
Many thanks for your help.

Welcome to the site.
The "such that" sub-setting can be done pretty easily in pyomo. You cannot "bury" an if statement in your model because those values are unknown at the time the model is built.... Not sure how AMPL handles such things. The trick is to use core python to construct arbitrarily complicated subsets and use those to construct your model. Fortunately, python's list/set comprehensions are immensely powerful and make this pretty straightforward. Below is a snippet that shows this. 2 methods... Well, 2nd is just an enhancement. Note that you don't necessarily need to bring the subset into your model, but sometimes it is good for consistency and T/S, and using the "within" keyword in Method 2 allows error checking (buffoonery prevention...). Note that the 2 constraints constructed in the model are equivalent/redundant... Just shown for consistency. [Aside: active is a keyword in pyomo, so I used act.]
Edit: There is probably a legit 3rd method here to by using a for-loop over the desired indices (with the inner loop for t_prime controlled by the loop over t with individual calls to make constraint for each combo, but that seems much clumsier than making your own subset... you would be just replicating the set comprehension. Seems inferior to what is shown below...
Regarding solvers, GLPK and CBC are both free and great. Installs can be a little challenging depending on type of machine. On a mac with homebrew, it is a snap.
import pyomo.environ as pyo
tele = 4
appliances = ['fridge', 'tv']
m = pyo.ConcreteModel('subset_maker')
### SETS
m.T = pyo.Set(initialize=range(1, tele + 1))
m.A = pyo.Set(initialize=appliances)
### VARIABLES
m.act = pyo.Var(m.A, m.T, domain=pyo.Binary)
### Method 1: Make subset on fly...
c1_set = {(a, t, t_prime) for a in m.A for t in m.T for t_prime in m.T if t_prime < t}
def C1(model, a, t, t_prime):
return model.act[a, t] * t_prime <= 10 # some nonsense...
m.C1 = pyo.Constraint(c1_set, rule=C1)
### Method 2: Bring that subset into the model (good for T/S and consistency...)
m.C1_SET = pyo.Set(within=m.A*m.T*m.T, initialize=c1_set)
m.C1_method_2 = pyo.Constraint(m.C1_SET, rule=C1)
m.pprint()
Yields:
7 Set Declarations
A : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 1 : Any : 2 : {'fridge', 'tv'}
C1_SET : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 3 : C1_SET_domain : 12 : {('tv', 4, 1), ('fridge', 4, 3), ('fridge', 3, 2), ('fridge', 4, 2), ('tv', 2, 1), ('tv', 4, 3), ('tv', 3, 2), ('tv', 4, 2), ('fridge', 3, 1), ('fridge', 4, 1), ('fridge', 2, 1), ('tv', 3, 1)}
C1_SET_domain : Size=1, Index=None, Ordered=True
Key : Dimen : Domain : Size : Members
None : 3 : C1_SET_domain_index_0*T : 32 : {('fridge', 1, 1), ('fridge', 1, 2), ('fridge', 1, 3), ('fridge', 1, 4), ('fridge', 2, 1), ('fridge', 2, 2), ('fridge', 2, 3), ('fridge', 2, 4), ('fridge', 3, 1), ('fridge', 3, 2), ('fridge', 3, 3), ('fridge', 3, 4), ('fridge', 4, 1), ('fridge', 4, 2), ('fridge', 4, 3), ('fridge', 4, 4), ('tv', 1, 1), ('tv', 1, 2), ('tv', 1, 3), ('tv', 1, 4), ('tv', 2, 1), ('tv', 2, 2), ('tv', 2, 3), ('tv', 2, 4), ('tv', 3, 1), ('tv', 3, 2), ('tv', 3, 3), ('tv', 3, 4), ('tv', 4, 1), ('tv', 4, 2), ('tv', 4, 3), ('tv', 4, 4)}
C1_SET_domain_index_0 : Size=1, Index=None, Ordered=True
Key : Dimen : Domain : Size : Members
None : 2 : A*T : 8 : {('fridge', 1), ('fridge', 2), ('fridge', 3), ('fridge', 4), ('tv', 1), ('tv', 2), ('tv', 3), ('tv', 4)}
C1_index : Size=1, Index=None, Ordered=False
Key : Dimen : Domain : Size : Members
None : 3 : Any : 12 : {('fridge', 2, 1), ('fridge', 3, 1), ('fridge', 3, 2), ('fridge', 4, 1), ('fridge', 4, 2), ('fridge', 4, 3), ('tv', 2, 1), ('tv', 3, 1), ('tv', 3, 2), ('tv', 4, 1), ('tv', 4, 2), ('tv', 4, 3)}
T : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 1 : Any : 4 : {1, 2, 3, 4}
act_index : Size=1, Index=None, Ordered=True
Key : Dimen : Domain : Size : Members
None : 2 : A*T : 8 : {('fridge', 1), ('fridge', 2), ('fridge', 3), ('fridge', 4), ('tv', 1), ('tv', 2), ('tv', 3), ('tv', 4)}
1 Var Declarations
act : Size=8, Index=act_index
Key : Lower : Value : Upper : Fixed : Stale : Domain
('fridge', 1) : 0 : None : 1 : False : True : Binary
('fridge', 2) : 0 : None : 1 : False : True : Binary
('fridge', 3) : 0 : None : 1 : False : True : Binary
('fridge', 4) : 0 : None : 1 : False : True : Binary
('tv', 1) : 0 : None : 1 : False : True : Binary
('tv', 2) : 0 : None : 1 : False : True : Binary
('tv', 3) : 0 : None : 1 : False : True : Binary
('tv', 4) : 0 : None : 1 : False : True : Binary
2 Constraint Declarations
C1 : Size=12, Index=C1_index, Active=True
Key : Lower : Body : Upper : Active
('fridge', 2, 1) : -Inf : act[fridge,2] : 10.0 : True
('fridge', 3, 1) : -Inf : act[fridge,3] : 10.0 : True
('fridge', 3, 2) : -Inf : 2*act[fridge,3] : 10.0 : True
('fridge', 4, 1) : -Inf : act[fridge,4] : 10.0 : True
('fridge', 4, 2) : -Inf : 2*act[fridge,4] : 10.0 : True
('fridge', 4, 3) : -Inf : 3*act[fridge,4] : 10.0 : True
('tv', 2, 1) : -Inf : act[tv,2] : 10.0 : True
('tv', 3, 1) : -Inf : act[tv,3] : 10.0 : True
('tv', 3, 2) : -Inf : 2*act[tv,3] : 10.0 : True
('tv', 4, 1) : -Inf : act[tv,4] : 10.0 : True
('tv', 4, 2) : -Inf : 2*act[tv,4] : 10.0 : True
('tv', 4, 3) : -Inf : 3*act[tv,4] : 10.0 : True
C1_method_2 : Size=12, Index=C1_SET, Active=True
Key : Lower : Body : Upper : Active
('fridge', 2, 1) : -Inf : act[fridge,2] : 10.0 : True
('fridge', 3, 1) : -Inf : act[fridge,3] : 10.0 : True
('fridge', 3, 2) : -Inf : 2*act[fridge,3] : 10.0 : True
('fridge', 4, 1) : -Inf : act[fridge,4] : 10.0 : True
('fridge', 4, 2) : -Inf : 2*act[fridge,4] : 10.0 : True
('fridge', 4, 3) : -Inf : 3*act[fridge,4] : 10.0 : True
('tv', 2, 1) : -Inf : act[tv,2] : 10.0 : True
('tv', 3, 1) : -Inf : act[tv,3] : 10.0 : True
('tv', 3, 2) : -Inf : 2*act[tv,3] : 10.0 : True
('tv', 4, 1) : -Inf : act[tv,4] : 10.0 : True
('tv', 4, 2) : -Inf : 2*act[tv,4] : 10.0 : True
('tv', 4, 3) : -Inf : 3*act[tv,4] : 10.0 : True
10 Declarations: T A act_index act C1_index C1 C1_SET_domain_index_0 C1_SET_domain C1_SET C1_method_2
[Finished in 413ms]

Related

How to include take the absolute value in objective function solving using pyomo and glpk

I have to find the optimum cost of building links between nodes. In my objective function, I am trying to minimise the cost. The problem can be solved to determine the variable, however the optimal value of my cost is incorrect as I want it to take the absolute value of each cost. How can I modify my codes as I cannot use abs() in the objective function?
cost+=(model.a[i,k]-model.a[j,k])model.cmodel.d[i,j].
This value can be negative if model.a[j,k]=1 or positive if model.a[i,k]=1
from pyomo.environ import *
# Creation of a Concrete Model
model = ConcreteModel()
# Sets
model.i = Set(initialize=[1,2,3,4,5,6,7,8,9,10,11,12,13], doc='Nodes')
model.k = Set(initialize=['Orange','SFR', 'Bouygues'], doc='Companies')
# Parameters
model.c = Param(initialize=25, doc='Cost of transforming an existing link into a backbone link in euro/km')
links={
(1, 2) : 1.8,
(1, 7) : 1,
(1, 13) : 5.4,
(2, 8) : 2.3,
(2, 3) : 1.7,
(2, 5) : 7,
(2, 7) : 2,
(2, 12) : 3,
(3, 4) : 2,
(3, 10) : 6.5,
(4, 5) : 1,
(4, 6) : 2,
(5, 8) : 5,
(5, 10) : 1,
(5, 11) : 1.5,
(6, 11) : 2.1,
(7, 12) : 2,
(8, 9) : 2,
(8, 13) : 0.7,
(9, 10) : 1.1,
(10, 11) : 1,
(12, 13) : 2.5,
}
model.d=Param(model.i, model.i,default=0, initialize=links, doc='distance in 10 km between nodes')
# Variables
model.a = Var(model.i, model.k, within=Binary, doc='Binary variable indicating whether node i belongs to company k (0 if it does not belong and 1 if it belongs)')
#Contraints#
def allocation_rule(model, i):
return sum(model.a[i,k] for k in model.k) == 1
model.allocation = Constraint(model.i, rule=allocation_rule, doc='Each node can only belong to one company')
def minimum_rule(model, k):
return sum(model.a[i,k] for i in model.i) >= 2
model.minimum = Constraint(model.k, rule=minimum_rule, doc='Each company must have at least 2 nodes')
#objective
def totalcost(model):
cost=0
for i in model.i:
for j in model.i:
if model.d[i,j]!=0:
for k in model.k:
cost+=(model.a[i,k]-model.a[j,k])*model.c*model.d[i,j]
return cost
model.z = Objective(rule=totalcost, sense=minimize, doc='Minimize the cost of implementing a backbone connecting the three sub-networks')
def total(model):
return model.cost_postive-model.cost_negative
## Display of the output ##
optimizer = SolverFactory("glpk",executable='/usr/bin/glpsol') #creates an optimizer object that uses the glpk package installed to your usr/bin.
optimizer.solve(model) #tells your optimizer to solve the model object
model.display()
I have tried using the cost+=abs((model.a[i,k]-model.a[j,k])model.cmodel.d[i,j]) but this makes the problem non-linear so it cannot be solved.
edited to introduce a new variable p, and added 2 constraints to p>=(model.a[i,k]-model.a[j,k])model.cmodel.d[i,j]) and
p>=-(model.a[i,k]-model.a[j,k])model.cmodel.d[i,j]). However, it returns with error: ERROR:pyomo.core:Rule failed for Param 'd' with index (1, 2):
from pyomo.environ import *
# Creation of a Concrete Model
model = ConcreteModel()
# Sets
model.i = Set(initialize=[1,2,3,4,5,6,7,8,9,10,11,12,13],
doc='Nodes')
model.i = Set(initialize=['Orange','SFR', 'Bouygues'],
doc='Companies')
# Parameters
model.c = Param(initialize=25, doc='Cost of transforming an
existing link into a backbone link in euro/km')
links={
(1, 2) : 1.8,
(1, 7) : 1,
(2, 3) : 1.7,
(2, 5) : 7,
(2, 7) : 2,
(2, 12) : 3,
(3, 4) : 2,
(3, 10) : 6.5,
(4, 5) : 1,
(4, 6) : 2,
(5, 8) : 5,
(5, 10) : 1,
(5, 11) : 1.5,
(6, 11) : 2.1,
(7, 12) : 2,
(8, 9) : 2,
(8, 13) : 0.7,
(9, 10) : 1.1,
(10, 11) : 1,
(12, 13) : 2.5,
(1, 13) : 5.4,
(2, 8) : 2.3,
}
model.d=Param(model.i, model.i,default=0, initialize=links, doc='distance in 10 km between nodes')
# Variables
model.a = Var(model.i, model.k, within=Binary, doc='Binary variable indicating whether node i belongs to company k (0 if it does not belong and 1 if it belongs)')
model.p = Var(model.i,model.k, within=(0.0,None), doc='Cost of building backbone link p_ij')
#Contraints#
def allocation_rule(model, i):
return sum(model.a[i,k] for k in model.k) == 1
model.allocation = Constraint(model.i, rule=allocation_rule, doc='Each node can only belong to one company')
def minimum_rule(model, k):
return sum(model.a[i,k] for i in model.i) >= 2
model.minimum = Constraint(model.k, rule=minimum_rule, doc='Each company must have at least 2 nodes')
def absolute_rule1(model):
return model.p >=(model.a[i,k]-
model.a[j,k])*model.c*model.d[i,j]
model.absolute1 = Constraint(model.i, rule=absolute_rule1, doc='To take the positive cost')
def absolute_rule2(model):
for i in model.i:
for j in model.i:
if model.d[i,j]!=0:
for k in model.k:
return model.p >=-(model.a[i,k]-
model.a[j,k])*model.c*model.d[i,j]
model.absolute2 = Constraint(model.i, rule=absolute_rule2, doc='To take the positive cost')
#objective
def totalcost(model):
cost=0
for i in model.i:
for j in model.i:
if model.d[i,j]!=0:
for k in model.k:
cost+=model.p
return cost
model.z = Objective(rule=totalcost, sense=minimize, doc='Minimize the cost of implementing a backbone connecting the three sub-networks')
Below is a slightly modified approach.
You could put in the helper variables to get to absolute value, but I think that might lead you a bit astray in your objective, as I mentioned in the comment. Specifically, if you have 3 companies, the best you could do for "ownership" would be 1 company owning it, so as you summed over all three companies, you would get one "zero" cost and two actual costs, which is probably not desired.
I reformulated a bit to something which kinda does the same thing with a couple new variables. Realize there is "upward pressure" in the model for link ownership... cost is reduced (good) if more links are owned, so the variable I put in assesses each link by company and only allows ownership if they own both nodes.
The other new variable indicates whether a link is owned or not, independent of company. I think you could probably do without that, but it adds a little clarity. You could get the same thing (remove the variable, I think) by observing:
build_link >= 1 - sum(own_link)
Also, a reminder... I didn't see in your original code that you were inspecting the solver results. Always, always, always do that to ensure the status is "optimal" or you are looking at junk response.
Code:
from pyomo.environ import *
links={
(1, 2) : 1.8,
(1, 7) : 1,
(1, 13) : 5.4,
(2, 8) : 2.3,
(2, 3) : 1.7,
(2, 5) : 7,
(2, 7) : 2,
(2, 12) : 3,
(3, 4) : 2,
(3, 10) : 6.5,
(4, 5) : 1,
(4, 6) : 2,
(5, 8) : 5,
(5, 10) : 1,
(5, 11) : 1.5,
(6, 11) : 2.1,
(7, 12) : 2,
(8, 9) : 2,
(8, 13) : 0.7,
(9, 10) : 1.1,
(10, 11) : 1,
(12, 13) : 2.5,
}
# Creation of a Concrete Model
model = ConcreteModel()
# Sets
model.i = Set(initialize=[1,2,3,4,5,6,7,8,9,10,11,12,13], doc='Nodes')
model.k = Set(initialize=['Orange','SFR', 'Bouygues'], doc='Companies')
model.links = Set(within=model.i*model.i, initialize=links.keys())
# Parameters
model.c = Param(initialize=25, doc='Cost of transforming an existing link into a backbone link in euro/km')
model.d = Param(model.links, default=0, initialize=links, doc='distance in 10 km between nodes')
# Variables
model.a = Var(model.i, model.k, within=Binary, doc='Binary variable indicating whether node i belongs to company k (0 if it does not belong and 1 if it belongs)')
model.own_link = Var(model.links, model.k, within=Binary, doc='Own the link')
model.build_link = Var(model.links, within=Binary, doc='build link')
#Contraints#
def allocation_rule(model, i):
return sum(model.a[i,k] for k in model.k) == 1
model.allocation = Constraint(model.i, rule=allocation_rule, doc='Each node can only belong to one company')
def minimum_rule(model, k):
return sum(model.a[i,k] for i in model.i) >= 2
model.minimum = Constraint(model.k, rule=minimum_rule, doc='Each company must have at least 2 nodes')
def link_owner(model, k, n1, n2):
return model.own_link[n1, n2, k] <= 0.5 * (model.a[n1, k] + model.a[n2, k])
model.link1 = Constraint(model.k, model.links, rule=link_owner)
# link the "build link" variable to lack of link ownership
def link_build(model, *link):
return model.build_link[link] >= 1 - sum(model.own_link[link, k] for k in model.k)
model.build_constraint = Constraint(model.links, rule=link_build)
# objective
cost = sum(model.build_link[link]*model.c*model.d[link] for link in model.links)
model.z = Objective(expr=cost, sense=minimize, doc='Minimize the cost of implementing a backbone connecting the three sub-networks')
## Display of the output ##
optimizer = SolverFactory("glpk") #creates an optimizer object that uses the glpk package installed to your usr/bin.
result = optimizer.solve(model) #tells your optimizer to solve the model object
print(result)
print('Link Ownership Plan:')
for idx in model.own_link.index_set():
if model.own_link[idx].value: # will be true if it is 1, false if 0
print(idx, model.own_link[idx].value)
print('\nLink Build Plan:')
for idx in model.build_link.index_set():
if model.build_link[idx].value: # will be true if it is 1, false if 0
print(idx, model.build_link[idx].value)
Output:
Problem:
- Name: unknown
Lower bound: 232.5
Upper bound: 232.5
Number of objectives: 1
Number of constraints: 105
Number of variables: 128
Number of nonzeros: 365
Sense: minimize
Solver:
- Status: ok
Termination condition: optimal
Statistics:
Branch and bound:
Number of bounded subproblems: 2183
Number of created subproblems: 2183
Error rc: 0
Time: 0.21333098411560059
Solution:
- number of solutions: 0
number of solutions displayed: 0
Link Ownership Plan:
(1, 2, 'Orange') 1.0
(1, 7, 'Orange') 1.0
(1, 13, 'Orange') 1.0
(2, 8, 'Orange') 1.0
(2, 5, 'Orange') 1.0
(2, 7, 'Orange') 1.0
(2, 12, 'Orange') 1.0
(3, 10, 'SFR') 1.0
(4, 6, 'Bouygues') 1.0
(5, 8, 'Orange') 1.0
(6, 11, 'Bouygues') 1.0
(7, 12, 'Orange') 1.0
(8, 9, 'Orange') 1.0
(8, 13, 'Orange') 1.0
(12, 13, 'Orange') 1.0
Link Build Plan:
(2, 3) 1.0
(3, 4) 1.0
(4, 5) 1.0
(5, 10) 1.0
(5, 11) 1.0
(9, 10) 1.0
(10, 11) 1.0

Pytorch tensor dimension multiplication

I'm trying to implement the grad-camm algorithm:
https://arxiv.org/pdf/1610.02391.pdf
My arguments are:
activations: Tensor with shape torch.Size([1, 512, 14, 14])
alpha values : Tensor with shape torch.Size([512])
I want to multiply each activation (in dimension index 1 (sized 512)) in each corresponding alpha value: for example if the i'th index out of the 512 in the activation is 4 and the i'th alpha value is 5, then my new i'th activation would be 20.
The shape of the output should be torch.Size([1, 512, 14, 14])
Assuming the desired output is of shape (1, 512, 14, 14).
You can achieve this with torch.einsum:
torch.einsum('nchw,c->nchw', x, y)
Or with a simple dot product, but you will first need to add a couple of additional dimensions on y:
x*y[None, :, None, None]
Here's an example with x.shape = (1, 4, 2, 2) and y = (4,):
>>> x = torch.arange(16).reshape(1, 4, 2, 2)
tensor([[[[ 0, 1],
[ 2, 3]],
[[ 4, 5],
[ 6, 7]],
[[ 8, 9],
[10, 11]],
[[12, 13],
[14, 15]]]])
>>> y = torch.arange(1, 5)
tensor([1, 2, 3, 4])
>>> x*y[None, :, None, None]
tensor([[[[ 0, 1],
[ 2, 3]],
[[ 8, 10],
[12, 14]],
[[24, 27],
[30, 33]],
[[48, 52],
[56, 60]]]])

Change 5th number from list

I have a one function for my calendar
def formatweek(self, theweek, events):
week = ''
for d, weekday in theweek:
#return f'<tr style="color:blue";> {week} </tr>'
week += self.formatday(d, events)
return f'<tr> {week} </tr>'
def formatday(self, day, events):
events_per_day = events.filter(start_time__day=day)
d = ''
for event in events_per_day:
d += f'<li> {event.get_html_url} </li>'
if day != 0:
return f"<td><span class='date'>{day}</span><ul> {d} </ul></td>"
return '<td></td>'
where theweek is a list of pairs:
[(1, 0), (2, 1), (3, 2), (4, 3), (5, 4), (6, 5), (7, 6)]
[(8, 0), (9, 1), (10, 2), (11, 3), (12, 4), (13, 5), (14, 6)]
[(15, 0), (16, 1), (17, 2), (18, 3), (19, 4), (20, 5), (21, 6)]
[(22, 0), (23, 1), (24, 2), (25, 3), (26, 4), (27, 5), (28, 6)]
[(29, 0), (30, 1), (31, 2), (0, 3), (0, 4), (0, 5), (0, 6)]
Where the first number(for example(1)) in pairs is day in month (1.januar) and the second is a number for weekday name (0-Monday, 1-Thuesday etc...)
d and weekday become an int in loop. d = days of month (1,2,3,4....)and Weekday = number for days (Mon - 0, Tue - 1 etc...).
It returns this return f'<tr> {week} </tr>'for the table. And I would like to make it return for 5th and 6th weekday numbers (Saturday, Sunday) additionally f'<tr style="color:blue";> {5 (or 6)} </tr>'.
So the simple say: I would like to make a weekend days to become blue.

Gurobi python : error with indexing var in callback for lazy constraint

Could somebody please help me with this error:
When I use callback for add lazy constraints, I received this the follow message:
Exception TypeError: 'Var' object does not support indexing in 'gurobipy.callbackstub' ignored.
The error comes from the line which contains "selected". I try to test 2 versions of callback without success. I have alos try to run the example of TSP on Gurobi but model._vars.keys() dont work. I use Gurobi 6.5.2 and Python 2.7. Print model._vZ give :
[<gurobi.Var vZ_j((9, 6, 6), 3)_i((4, 7, 6), 3)_e(3, 'P2')>, <gurobi.Var vZ_j((9, 6, 6), 3)_i((4, 7, 6), 3)_e(3, 'P3')>, <gurobi.Var vZ_j((9, 6, 6), 3)_i((4, 7, 6), 3)_e(3, 'P4')>, <gurobi.Var vZ_j((9, 6, 6), 3)_i((4, 7, 6), 3)_e(3, 'P5')>, <gurobi.Var vZ_j((3, 8, 6), 2)_i((10, 7, 5), 3)_e(3, 'P1')>, <gurobi.Var vZ_j((3, 8, 6), 2)_i((10, 7, 5), 3)_e(3, 'P2')>, <gurobi.Var vZ_j((3, 8, 6), 2)_i((10, 7, 5), 3)_e(3, 'P3')>, <gurobi.Var vZ_j((3, 8, 6), 2)_i((10, 7, 5), 3)_e(3, 'P4')>, <gurobi.Var vZ_j((3, 8, 6), 2)_i((10, 7, 5), 3)_e(3, 'P5')>, <gurobi.Var vZ_j((10, 10, 6), 3)_i((4, 7, 6), 3)_e(3, 'P1')>, <gurobi.Var vZ_j((10, 10, 6), 3)_i((4, 7, 6), 3)_e(3, 'P2')>, <gurobi.Var vZ_j((10, 10, 6), 3)_i((4, 7, 6), 3)_e(3, 'P3')>, <gurobi.Var vZ_j((10, 10, 6), 3)_i((4, 7, 6), 3)_e(3, 'P4')>, <gurobi.Var vZ_j((10, 10, 6), 3)_i((4, 7, 6), 3)_e(3, 'P5')>]
[, , , , , , , , , , , , , ]
Thanks
def subtourelim(model, where):
if where == GRB.Callback.MIPSOL:
vZs = model.cbGetSolution(model._vZ)
vXs = model.cbGetSolution(model._vX)
opeqp= model._OpEqP
nz=model._nz
for e in opeqp:
selected = [(model._vZ[i][0],model._vZ[i][1]) for i in range(nz) if model._vZ[i][2]==e and model._vZ[i][1]!=(b1,T)]
bti=b0
chaine_primo=[]
while True:
bti=[bt for bt in BlocsEPT if vZs[bti,bt,e]>0.5][0]
if bit!=(b1,T):
chaine_primo.append(bti)
else:
break
unvisit=[bt for bt in Blocs_EP if vXs[bt,e]>0.5 and bt not in chaine_primo]
if len(unvisit)>0:
tour = subtour(selected,unvisit,chaine_primo,Blocs_EP)
ArcsTour=[(bt0,bt1) for bt in tour for bt1 in tour if (bt0,bt1) in CBloc_T and vZs[bt0,bt1,e]>0.5]
model.cbLazy(quicksum(model._vZ[ct[0],ct[1],e] for ct in ArcsTour) <= len(tour)-1)
Thanks, i found the solution :
selected = tuplelist((cte[0],cte[1]) for cte in model._vZ if cte[2]==e if model.cbGetSolution(model._vZ[cte]) > 0.5 and cte[1]!=(Fb1,FT))
"model._vZ" came from "model.getVars()" whitch this a list. I change it to "model._vZ = varZ" which is dictionnary and then applied evaluate "selected"

Importing text file to Excel with VBA - multiple strings with same delimiter

I'm trying to import a number of text files into Excel using the VBA code below. Whilst the code produces a list of the Transaction Sales Numbers with corresponding date for each file imported, I can't work out how to get the associated Transaction Sales Numbers into seperate columns in each imported file row. I have tried RegEx but struggled with the differing formats of the Sales Numbers (an example of each is in the sample file)... Can anyone help?
Many thanks in advance
Sample text file:
This is sales enquiry response for SER:SS09458GQPBXX201503191300WWPL0933 *********************************************************** Sales record match For SER:SS09458GQPBXX201503191300WWPL0933 **********************Original File********************** File Data Source POS Type of Transaction EFT Date Mar 19 2015 12:00PM Transaction Sales Number LLRUMOLN120150319FLRPLIS08783 Product Name HAIRDRYER ***************Sales File # 1*************** File Data Source POS Type of Transaction EFT Date Apr 23 2015 12:00PM Transaction Sales Number PLVOLMJBD0960807420300 Product Name HAIRDRYER ***************Sales File # 2*************** File Data Source POS Type of Transaction EFT Date May 28 2015 12:00PM Transaction Sales Number 781266HO3 Product Name HAIRDRYER ***************Sales File # 3*************** File Data Source POS Type of Transaction EFT Date May 10 2015 12:00PM Transaction Sales Number CVFORM05061126581000433 Product Name HAIRDRYER ***************Sales File # 4*************** File Data Source POS Type of Transaction EFT Date Jun 28 2015 12:07PM Transaction Sales Number LLB01L32330772427059291FOLM400P00295 Product Name HAIRDRYER
Option Explicit
Sub Sales_File_Extractor()
Dim fName As String, fPath As String, fPathDone As String
Dim LR As Long, NR As Long
Dim wbData As Workbook, wsMaster As Worksheet
Dim TSN_Start As String, TSN_End As String
Dim Date_Start As String, Date_End As String
Dim textline As String, text As String
'Setup
Application.ScreenUpdating = False 'speed up macro execution
Application.EnableEvents = False 'turn off other macros for now
Application.DisplayAlerts = False 'turn off system messages for now
Set wsMaster = ThisWorkbook.Sheets("SALES") 'sheet report is built into
With wsMaster
NR = .Range("A" & .Rows.Count).End(xlUp).Row + 1 'appends data to existing data
'Path and filename (edit this section to suit)
fPath = "C:\Users\burnsr\desktop\sales"
fPathDone = fPath & "Imported\" 'remember final \ in this string
On Error Resume Next
MkDir fPathDone 'creates the completed folder if missing
On Error GoTo 0
fName = Dir(fPath & "*.txt*") 'listing of desired files, edit filter as desired
Do While Len(fName) > 0
Open (fPath & fName) For Input As #1
Do Until EOF(1)
Line Input #1, textline
text = text & textline 'second loop text is already stored -> see reset text
Loop
Close #1
On Error Resume Next
.Cells(NR, "A").Value = fName
Date_Start = InStr(text, "Date ") 'position of start delimiter
Date_End = InStr(text, "Transaction Sales Number") 'position of end delimiter
.Cells(NR, "C").Value = Mid(text, Date_Start + 34, Date_End - Date_Start - 34) 'position number is length of start string
TSN_Start = InStr(text, "Transaction Sales Number ") 'position of start delimiter
TSN_End = InStr(text, "Product Name") 'position of end delimiter
.Cells(NR, "B").Value = Mid(text, TSN_Start + 34, TSN_End - TSN_Start - 34) 'position number is length of start string
'How to get all other successive values in columns?
text = "" 'reset text
Close #1 'close file
NR = .Range("A" & .Rows.Count).End(xlUp).Row + 1 'next row
Name fPath & fName As fPathDone & fName 'move file to IMPORTED folder
fName = Dir 'ready next filename
Loop
End With
ErrorExit: 'Cleanup
Application.DisplayAlerts = True 'turn system alerts back on
Application.EnableEvents = True 'turn other macros back on
Application.ScreenUpdating = True 'refreshes the screen
MsgBox "Import completed"
Rabbie, I have an XLSM file that reads 6 CSV files and adds 6 sheets to inside itself. Text are TAB delimited.
UTF-8 CSV Headers Example:
Customer Number Customer description Cust. Name-Lang 2 Status Phone Number Fax Number E-mail Address Type of Business Cust. Group Code
VBA:
Function IsOpen(File$) As Boolean
Dim FN%
FN = FreeFile
On Error Resume Next
Open File For Random Access Read Write Lock Read Write As #FN
Close #FN
IsOpen = Err
End Function
Public Sub Load_Data()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
allName = Worksheets("START").Cells(6, "B").Value
tmpltName = Worksheets("START").Cells(4, "B").Value
savePath = Worksheets("START").Cells(3, "B").Value
Set currBook = ActiveWorkbook
Set prevsheet = ActiveSheet
'Load all ZOOM files
i = 2
For Each n In Worksheets("START").Range("E2:E8")
On Error Resume Next
currBook.Sheets(n.Text).Select
If Not Err Then
Err.Clear
currBook.Worksheets(n.Text).Delete
End If
Sheets.Add(Before:=Sheets("START")).Name = n.Text
' Checking if file is opened
If Not IsOpen(Worksheets("START").Cells(i, "F").Value) Then
' Loadd CSV file
LoadCSV Worksheets("START").Cells(i, "F").Value, n.Text
End If
' List of combining fields
' Find column with combining field
With Worksheets(n.Text).Columns("A:DZ")
Set result = .Find(What:=Worksheets("START").Cells(i, "G").Value, LookIn:=xlValues)
If result Then
combFields.Add result.Address, n.Text
End If
End With
i = i + 1
Next n
' Find column with combining field in Peoples
combFieldPeople = combFields.Item("peoples")
' Find column with combining field in Companies
combFieldCompany = combFields.Item("companies")
' Find company names field in "companies"
With Worksheets("companies").Columns("A:DZ")
Set result = .Find(What:=Worksheets("START").Cells(3, "I").Value, LookIn:=xlValues)
If result Then
companyNameField = result.Address
End If
End With
' Find column with "CopyToExcel" checkbox for Peolles
With Worksheets("peoples").Columns("A:DZ")
Set result = .Find(What:=Worksheets("START").Cells(2, "H").Value, LookIn:=xlValues)
If result Then
copyUserField = result.Address
End If
End With
' Find column with "CopyToExcel" checkbox for "Companies"
With Worksheets("companies").Columns("A:DZ")
Set result = .Find(What:=Worksheets("START").Cells(3, "H").Value, LookIn:=xlValues)
If result Then
copyField = result.Address
End If
End With
' Remove unnecessary organizations
startBook.Activate
With Worksheets("companies")
.Activate
.AutoFilterMode = False
fldNum = .Range(copyField).Column
.UsedRange.AutoFilter Field:=fldNum, Criteria1:="Y"
ActiveCell.CurrentRegion.Select ' copy unique values
nRow = Selection.Rows.Count
Selection.Copy
'.UsedRange.AutoFilter
Worksheets.Add.Name = "tmp1"
ActiveSheet.Range("A1").Select
ActiveSheet.Paste
Worksheets("companies").Delete
Worksheets("tmp1").Name = "companies"
End With
Worksheets("START").Activate
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Function LoadCSV(fName As String, shName As String)
ActiveWorkbook.Worksheets(shName).Activate
iPath = ThisWorkbook.Path
fullFileName = iPath & "\" & fName
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;" + fullFileName, Destination:=Range("$A$1"))
'.CommandType = 0
.Name = fullFileName
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 65001
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = False
'.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, _
' 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 _
' , 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, _
' 1, 1, 1, 1, 1)
.TextFileColumnDataTypes = Array(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End Function
It works fine with Hebrew and Zoom/Priority. MS Office 2010/2013/2016(32/64)