Representation of tuple set in Pyomo - tuples

I am trying to solve a problem in Pyomo. I need to write down restrictions on a subset A for some arcs between nodes (I and II) for a Constraint1. I wrote a model:
from pyomo.environ import *
model = AbstractModel()
model.I = Set()
model.II = SetOf(model.I)
model.J = Set()
model.A = Set(model.I,model.II)
model.c = Param(model.I, model.J, default=0)
model.b = Param(model.I, default=0)
model.x = Var(model.I, model.J, within=NonNegativeReals)
model.y = Var(model.I, model.II, within=NonNegativeReals)
data = DataPortal()
data.load(filename='Data.yaml')
data.load(filename='Table.tab')
def objective_rule(model):
return (sum(model.c[i,j]*model.x[i,j] for i in model.I for j in model.J))
model.OBJ = Objective(rule=objective_rule, sense = minimize)
def B_rule(model,i):
Bb = sum(model.x[i,j] for j in model.J)-sum(model.y[i,ii] for ii in model.II if ii != i)+0.01*sum(model.y[ii,i] for ii in model.II if ii != i)
return model.b[i] == Bb
model.B1 = Constraint(model.I, rule=B_rule)
def constraint1_rule(model,i,ii):
if (i,ii) in model.A:
return model.y[i,ii] <= 10000
return Constraint.Skip
model.constraint1 = Constraint(model.I, model.II, rule = constraint1_rule)
instance = model.create_instance(data)
opt = SolverFactory('cplex')
opt.solve(instance)
instance.OBJ.display()
instance.x.display()
instance.y.display()
The data is presented in the file Data.yaml:
I: [1, 2, 3, 4]
J: [1, 2]
b : {1: 10000, 2: 20000, 3: 25000, 4: 22000}
c:
- index: [1, 1]
value: 550
- index: [2, 2]
value: 120
- index: [3, 1]
value: 650
- index: [4, 2]
value: 550
- index: [1, 1]
value: 120
- index: [2, 2]
value: 650
- index: [3, 1]
value: 650
- index: [4, 2]
value: 550
The two-dimensional set A is presented in the file Table.tab:
set A : 1 2 3 4 :=
1 - - + +
2 - - + +
3 + + - +
4 + + + - ;
After the solution I get the error:
Unspecified format and data option
How to correctly represent the set A?

First, your data and sets are so small, that I would really consider just putting them into the base file and making a concrete model. Much easier to troubleshoot. You could even use basic python to read from csv files or such.
Anyhow. You can find a good example here on working with .tab files:
https://pyomo.readthedocs.io/en/stable/working_abstractmodels/data/dataportals.html?highlight=.tab#loading-structured-data
2 things you need to do:
change your statement for model.A to just show that it is within the sets.
model.A = Set(within = model.I*model.I)
Clean up your tab file to show the set index in top left and clear out the punctuation:
I 1 2 3 4
1 - - + +
2 - - + +
3 + + - +
4 + + + -
update your read statement:
data.load(filename='table.tab', set=model.A, format='set_array')

Related

Python - Error using linprog ("Invalid input for linprog: provide a 3 x 2 array for bounds, not a 2 x 3 array")

I am trying to use the linprog in python to solve this problem:
# Minimize = (0.035*x1) + (0.015*x2) + (0.025*x3)
# x1+x2+x3=1.2
# 0<=x1<=0.7
# 0<=x2<=0.3
# 0<=x3<=0.5
c = [0.035, 0.015, 0.025] #objective function
A_eq = [[1, 1, 1]]
b = [1.2]
lb = (0, 0, 0)
up = (0.7, 0.3, 0.5)
from scipy.optimize import linprog
linprog(c, A_ub=None, b_ub=None, A_eq=A_eq, b_eq=b, bounds=[lb,up], method='interior-point', callback=None, options=None, x0=None)
However I am getting an error could you help me with that?
thanks a lot!
You sholud define correctly the bounds for each variable in the same order as the coefficients. In this case, they’re between zero and some number:
# Minimize = (0.035*x1) + (0.015*x2) + (0.025*x3)
# x1+x2+x3=1.2
# 0<=x1<=0.7
# 0<=x2<=0.3
# 0<=x3<=0.5
c = [0.035, 0.015, 0.025] #objective function
A_eq = [[1, 1, 1]]
b = [1.2]
x1_b = (0, 0.7)
x2_b = (0, 0.3)
x3_b = (0, 0.5)
from scipy.optimize import linprog
linprog(c, A_ub=None, b_ub=None, A_eq=A_eq, b_eq=b, bounds=[x1_b, x2_b,x3_b], method='interior-point', callback=None, options=None, x0=None)

Record intermediary results in sympy

I am doing some operations on two matrices in sympy and I want to record how the result was obtained. For example in a isympy session:
a = Matrix([[1, 0], [2, 1]])
b = Matrix([[1, 1], [0, 2]])
out = HadamardProduct(a,b).doit()
out = sum(out)
out
Output:
3
Instead I would like this output:
1 * 1 + 0 * 1 + 2 * 0 + 1 * 2 = 3
How do I keep track of the history?
This seems to be it:
a = Matrix([[1, 0], [2, 1]])
b = Matrix([[1, 1], [0, 2]])
with evaluate(False):
out = a.multiply_elementwise(b)
out = sum(out)
Eq(out, out.simplify())
Output:
2⋅0 + 0⋅1 + 0 + 1⋅1 + 1⋅2 = 3

Getting solution of constraints when model gives infeasible solution

I am coding an optimization problem. The model is giving infeasible solution. I want to check which constraint is giving infeasible solution. So far, I have checked online, but have not been able to come up with the solution to the problem. Can anyone help me? For example:in the code below, because of constraint 3 model is infeasible. How do I determine it from the solution? Thanks
from gurobipy import *
# Create a new model
m = Model("mip1")
# Create variables
x1 = m.addVar(vtype=GRB.INTEGER, name="x1")
x2 = m.addVar(vtype=GRB.INTEGER, name="x2")
# Integrate new variables
m.update()
# Set objective
m.setObjective(7*x1 + 2*x2, GRB.MAXIMIZE)
m.addConstr(-x1 + 2 * x2 <= 4, "constraint-0")
m.addConstr(5*x1 + x2 <= 20, "constraint-1")
m.addConstr(-2*x1 -2*x2 <= -7, "constraint-2")
m.addConstr(x1 <= -2, "constraint-3")
m.addConstr(x2 <= 4, "constraint-4")
m.optimize()
for v in m.getVars():
print('%s %g' % (v.varName, v.x))
print('Obj: %g' % m.objVal)
an exemple :
from gurobipy import *
# Create a new model
m = Model("mip1")
# Create variables
x1= m.addVar(lb=0,ub=62,vtype=GRB.INTEGER,name="x1")
x2 = m.addVar(lb=0,ub=50, vtype=GRB.INTEGER,name="x2")
m.update()
m.addConstr(-x1 + 2*x2 <= 4, "constraint-0")
m.addConstr(5*x1 + x2 <= 20, "constraint-1")
m.addConstr(-2*x1 -2*x2 <= -25, "constraint-2")
m.addConstr(x1 <= 2, "constraint-3")
#m.addConstr(x2 <= 50, "constraint-4")
m.update()
# Set objective
m.setObjective(7*x1 + 2*x2, GRB.MAXIMIZE)
m.update()
m.optimize()
status = m.status
if status == GRB.Status.OPTIMAL:
for v in m.getVars():
print('%s %g' % (v.varName, v.x))
print('Obj: %g' % m.objVal)
elif status == GRB.Status.INFEASIBLE:
print('Optimization was stopped with status %d' % status)
# do IIS
m.computeIIS()
for c in m.getConstrs():
if c.IISConstr:
print('%s' % c.constrName)

updating function arguments python in each iterations

I am trying to update my function arguments after each iteration but failed to do so. Kindly check my code because I am new to python language. My task is to calculate xps, (represents collection of positions) and v2ps, (represents collection of velocities) after each iteration and want to plot them against each other. Basic this program represents the collision of objects moving vertical down and one of object also collide with plane above which they are moving.
acc_grav = 10
m1 =float(input(" Input mass of ball one, m1: "))
m2 =float(input(" Input mass of ball two, m2: "))
time_steps =10000
num_coll_bounce = 0
num_ball_coll = 0
eps=1.e-6
def ball_coll(x1_old,v1_old,x2_old,v2_old,time_ball_coll):
v1 = v1_old - acc_grav*time_ball_coll
v2 = v2_old - acc_grav*time_ball_coll
x1 = x1_old + time_ball_coll*v1_old - 0.5*acc_grav*(time_ball_coll)**2
x2 = x2_old + time_ball_coll*v2_old - 0.5*acc_grav*(time_ball_coll)**2
v1_ball_coll = (v1*(m1-m2)+(2*m2*v2))/(m1+m2)
v2_ball_coll = (v2*(m2-m1)+(2*m1*v1))/(m1+m2)
cumlv2=v2
return [v1,v2,x1,x2,v1_ball_coll,v2_ball_coll]
def floor_coll(x1_old,v1_old,x2_old,v2_old,time_floor_coll):
v1 = v1_old - acc_grav*time_floor_coll
v2 = v2_old - acc_grav*time_floor_coll
x1 = 0 #at the time of bonuce
x2 = x2_old + time_floor_coll*v2_old - 0.5*acc_grav*time_floor_coll**2
#update velocities following rules for collision with walls
v1_bounce = -v1
v2_bounce = v2
return [v1,v2,x1,x2,v1_bounce,v2_bounce]
for i in range(0, 10):
x1_0 = 1
x2_0 = 3 - (i-1)*0.1
v1_0 = 2
v2_0 = 2*v1_0
xps = []
v2ps = []
for n in range (time_steps-1):
time_ball_coll = (x2_0-x1_0)/(v1_0 - v2_0)
time_floor_coll = (v1_0 + (v1_0**2 + 2*acc_grav*x1_0)**1/2)/acc_grav
if ((time_ball_coll - time_floor_coll)<eps and v1_0 - v2_0 > 0):
num_coll_bounce = num_coll_bounce + 1
num_ball_coll = num_ball_coll + 1
ball_coll(x1_0,v1_0,x2_0,v2_0,time_ball_coll)
#xps[n] = x2_0
#v2ps(n,num_ballcoll) = v2ini
xps.append(x2_0)
v2ps.append(v2_0)
else:
num_coll_bounce = num_coll_bounce + 1
floor_coll(x1_0,v1_0,x2_0,v2_0,time_floor_coll)
#x1_old,v1_old,x2_old,v2_old,time_floor_coll = dd2
x_1.append(x1_0)
x_2.append(x2_0)

defined function not found

I have a script as follows:
import numpy as np
import pandas as pd
import pdb
# conventions: W = fitness, A = affinity ; sex: 1=M, 0=F; alien: 1=alien,
# 0=native
# pop array order: W, A, sex, alien
def mkpop(n):
W = np.repeat(a=1, repeats=n)
A = np.random.normal(1, 0.1, size=n)
A[A < 0] = 0
alien = np.repeat(a=False, repeats=n)
sex = np.random.randint(0, 2, n)
pop = np.array([W, A, sex, alien])
pop = np.transpose(pop)
return pop
def migrate(pop, n=10, gParams=[1, 0.1]):
W = np.random.gamma(shape=gParams[0], scale=gParams[1], size=n)
A = np.repeat(1, n)
# 0 is native; 1 is alien
alien = np.repeat(True, n)
# 0 is female
sex = np.random.randint(0, 2, n)
popAlien = np.array([W, A, sex, alien])
popAlien = np.transpose(popAlien)
pop = np.vstack((pop, popAlien))
return pop
def mate(pop):
# split into male and female
f = pop[pop[:, 2] == 0]
m = pop[pop[:, 2] == 1]
# create transition matricies for native and alien mates
# m with native = m.!alien.transpose * f.alien
# negate alien
naLog = list(np.asarray(m[:, 3]) == False)
naPdMat = np.outer(naLog, f[:, 1])
# mate with alien = m.alien.transpose * affinity
alPdMat = np.outer(m[:, 3], f[:, 1])
# add transition matrices for probability density matrix
pdMat = alPdMat + naPdMat
# transition matrix is equal to the pd matrix / column sumso
colSums = np.sum(pdMat, axis=0)
pMat = pdMat / colSums
# select mates
def choice(x):
ch = np.random.choice(a=range(0, len(x)), p=x)
return ch
mCh = np.apply_along_axis(choice, 0, pMat)
mCh = m[mCh, :]
WMid = (f[:, 0] + mCh[:, 0]) / 2
AMid = (f[:, 1] + mCh[:, 1]) / 2
# assign fitness based on group affiliation; only native/alien matings have
# modified fitness
# reassign fitness and affinity based on group id and midparent vals
W1 = np.where(
(f[:, 3] == mCh[:, 3]) |
((f[:, 3] == 1) & (mCh[:, 3] == 0))
)
WMid[W1] = 1
# number of offspring is a poisson-distributed variable with lambda=2W
nOff = map(lambda x: np.random.poisson(lam=x), 2 * WMid)
# generate offspring
# expand list of nOff to numbers of offspring per pair
# realized offspring is index posisions of W and A vals to be replicated
# for offspring
# this can be rewritten to return a matrix of the appropriate length. This
# should work
midVals = np.array([WMid, AMid]).T
realOff = np.array([0, 0])
for i in range(0, len(nOff)):
sibs = np.repeat([np.array(midVals[i])], [nOff[i]], axis=0)
realOff = np.vstack((realOff, sibs))
offspring = np.delete(realOff, 0, 0)
sex = np.random.randint(0, 2, len(offspring))
alien = np.repeat(0, len(offspring))
otherStats = np.array([sex, alien]).T
offspring = np.hstack([offspring, otherStats])
return offspring # should return offspring
def sim(nInit, nGen=100, nAlien=10, gParams=[1, 0.1]):
gen = 0
pop = mkpop
stats = pd.DataFrame(columns=('gen', 'W', 'WMean', 'AMean', 'WVar', 'AVar'))
while gen < nGen:
pop = migrate(pop, nAlien, gParams)
offspring = mate(pop)
var = np.var(offspring, axis=0)
mean = np.mean(offspring, axis=0)
N = len(offspring)
W = N / nInit
genStats = N.append(W, gen, mean, var)
stats = stats.append(genStats)
print(N, gen)
gen = gen + 1
return stats
print mkpop(100)
print mate(mkpop(100))
#
sim(100, 100, 10, [1, 0.1])
Running this script, outputs NameError: name 'sim' is not defined. It is apparent from the commands before the final one that all the other functions defined within this script work without a hitch. I'm not sure what is going on here, and there is probably some very easy fix that I'm overlooking. Ctags recognizes this function just fine. It's entirely possibe that sim() doesn't actually work yet, as I haven't been able to debug it.
Your sim function defined in mate function scope so it's invisible to global scope. You need to fix your indentation for sim function