How formulat my optimization problem with Gekko? - python

I want to minimize this function:
sum[sum[Ri*{Pi² + (Qi - Qcj*Xij)²}for j in range(Nc)] for i in range(N)]
with P and Q as constants, Qc is a list of the proposed solution, and X is our decision variable (binary variable). I have already tried this code:
from gekko import GEKKO
import numpy as np
P=[13.10511598922975,11.2611396806742,10.103920431906348,8.199519500182628,
6.411296067052755,4.753519719147589,3.8977762462825973,2.6593092284662734,
1.6399999999854893]
Q=[5.06643685386732,4.4344047044589585,3.8082608015186405,3.2626022579039584,
1.2568869621197523,0.6152693459109657,0.46237064874523776,0.35226399840832523,
0.20000000001140983]
R=[0.1233, 0.014, 0.7463, 0.6984, 1.9831, 0.9053, 2.0552, 4.7953, 5.3434]
Qc=[150, 300, 450, 600,750,900,1050,1200,1350,1500,1650,1800,
1950,2100,2250,2400,2550,2700,2850,3000,3150,3300,3450,3600,
3750,3900,4050]
N=len(Q)
Nc=len(Qc)
m = GEKKO(remote=False)
X = m.Array(m.Var,(N,Nc),integer=True,lb=0,ub=1,value=0)
#""""
bv = np.array([[0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0, 0, 0, 0, 0, 0, 0, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0, 0, 1, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0, 1, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]])
for i in range(N):
for j in range(Nc):
X[i,j].value = bv[i,j]
#m.Equation(X[i,j]==bv[i,j])
#convirtir P et Q en KW
for i in range(N):
Q[i]=Q[i]*1000
P[i]=P[i]*1000
R[i]=R[i]*0.001
#constrainte ## one per line
for i in range(N):
m.Equation(m.sum([X[i][j]for j in range(Nc)])<=1)
b=m.sum([m.sum([(R[i]*((P[i]**2)+(Q[i]-Qc[j]*X[i][j])**2)) for j in range(Nc)]) for i in range(N)])
m.Minimize(b)
m.solver_options = ['minlp_gap_tol 1e-5',\
'minlp_maximum_iterations 10000',\
'minlp_max_iter_with_int_sol 2000']
m.options.SOLVER = 1
m.solve(debug=0, disp=True)
But the solution is not optimal for me when I calculate the power Loss (Ploss=R*(P²+(Q-Qc)²)).
Ploss=np.zeros(N)
for i in range(N):
for j in range(Nc):
#print(i,j,X[i][j].value[0])
Ploss[i]= R[i]*((P[i]**2)+(Q[i]-Qc[j]*X[i][j].value[0])**2)
print('the total Ploss en KW',sum(Ploss))`
The total loss for the first solution is the same when I use the solver with and without the initial value of X, the total loss is equal to 350684.76, and the objective function is equal to 9554569.42. My objective is to reduce total loss.

The Ploss calculation needs a += instead of just an = to sum the power loss over all j elements, not just the last j element. Does this help to reconcile the difference between the solver optimum and the post-processing results?
Ploss=np.zeros(N)
for i in range(N):
for j in range(Nc):
Ploss[i]+= R[i]*((P[i]**2)+(Q[i]-Qc[j]*X[i][j].value[0])**2)
print('the total Ploss en KW',sum(Ploss))

when I tried to use the hyperparameters optimization with this code:
# Define the search space for the hyperparameters
space = {'x1': hp.quniform('x1', 0, 1, Nc),
'x2': hp.quniform('x2', 0, 1, Nc),
'x3': hp.quniform('x3', 0, 1, Nc),
'x4': hp.quniform('x4', 0, 1, Nc),
'x5': hp.quniform('x5', 0, 1, Nc),
'x6': hp.quniform('x6', 0, 1, Nc),
'x7': hp.quniform('x7', 0, 1, Nc),
'x8': hp.quniform('x8', 0, 1, Nc),
'x9': hp.quniform('x9', 0, 1, Nc)}
def objective(params):
m = GEKKO(remote=False)
x = m.Array(m.Var,(N,Nc),integer=True,lb=0,ub=1)
x1,x2,x3,x4,x5,x6,x7,x8,x9 = x
#constrainte ## one per line
for i in range(N):
m.Equation(m.sum([x[i][j]for j in range(Nc)])<=1)
#constrainte## max of capacitors
m.Equation(m.sum([m.sum([Qc[j]*x[i][j]for j in range(Nc)])for i in range(N)])<=
m.sum([Q[0][i]for i in range(N)]))
b=m.sum([m.sum([((R[0][i]*T*Ke*(1/V[0][i]**2)*((P[0][i]**2)+(Q[0][i]-Qc[j]*x[i][j])**2))+
(Kc[j]*Qc[j]*x[i][j]))for j in range(Nc)]) for i in range(N)])
m.Obj(b)
m.solver_options = ['minlp_gap_tol 1e-5',\
'minlp_maximum_iterations 10000',\
'minlp_max_iter_with_int_sol 2000']
m.options.SOLVER = 1
m.solve(disp=False,debug=False)
obj = m.options.objfcnval
if m.options.APPSTATUS==1:
s=STATUS_OK
else:
s=STATUS_FAIL
m.cleanup()
return {'loss':obj, 'status': s, 'x':x}
best = fmin(objective, space, algo=tpe.suggest, max_evals=50)
sol = objective(best)
print(f"Solution Status: {sol['status']}")
print(f"Objective: {sol['loss']:.2f}")
print(f"Solution: {sol['x']}")
the solution is (isn't the optimal solution):
Solution Status: ok
Objective: 29034196329.00
Solution: [[[0.0] [0.0] [0.0] [0.0] [0.0] [1.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0]
[0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0]
[0.0] [0.0] [0.0]]
[[0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0]
[0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0]
[0.0] [0.0] [0.0]]
[[0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0]
[0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0]
[0.0] [1.0] [0.0]]
[[0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0]
[0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0]
[0.0] [0.0] [0.0]]
[[0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0]
[0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0]
[0.0] [0.0] [0.0]]
[[0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0]
[0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0]
[0.0] [0.0] [0.0]]
[[0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0]
[0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0]
[0.0] [0.0] [0.0]]
[[0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0]
[0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0]
[0.0] [0.0] [0.0]]
[[0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0]
[0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0] [0.0]
[0.0] [0.0] [0.0]]]

Related

Bezier MxN Surface in matrix form( with Python and numpy)

I am trying to rewrite slow method("bezier_surf_eval") for bezier surface with quick one(in matrix form "bezier_surface_M").
Using this formula:
Were [N] and [M] an bezier basis matrix (4x2 degree, because of 5x3 control points),
[U], [W] is surface uv params, [B] - control points
What i do wrong?
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm
from matplotlib.figure import Figure
from mpl_toolkits.mplot3d.axes3d import Axes3D
from scipy.special import comb
def bern(i, d, t):
return comb(d, i) * (t ** (d - i)) * (1 - t) ** i
def bezier_matrix(d):
return np.array([[(-1) ** (i - j) * comb(j, i) * comb(d, j) for i in range(d + 1)] for j in range(d + 1)], int)
BM = [bezier_matrix(i) for i in range(16)]
poles5x3 = np.array([
[[1.8, -0.3, 0.], [1.8, 0.13, 0.1], [1.8, 0.5, 0.]],
[[2., -0.3, 0.06], [2.1, 0.1, 0.1], [2.1, 0.5, 0.1]],
[[2.3, -0.3, 0.1], [2.3, 0.13, 0.2], [2.3, 0.5, 0.1]],
[[2.4, -0.3, 0.1], [2.5, 0.1, 0.15], [2.5, 0.5, 0.1]],
[[2.6, -0.3, 0.], [2.6, 0.1, 0.1], [2.5, 0.5, 0.]]])
def bezier_surf_eval(poles, u, v, deg_u, deg_v):
count_u, count_v = deg_u + 1, deg_v + 1
co = [0, 0, 0]
for i in range(count_u):
for j in range(count_v):
bu = bern(i, deg_u, u)
bv = bern(j, deg_v, v)
pole_co = poles[i][j]
m = bu * bv
co[0] += pole_co[0] * m
co[1] += pole_co[1] * m
co[2] += pole_co[2] * m
return co
def bezier_surface_slow(poles, resol=(16, 16)):
params_u = np.linspace(0, 1, resol[0])
params_v = np.linspace(0, 1, resol[1])
count_u, count_v, _ = poles.shape
du, dv = count_u - 1, count_v - 1
cps = poles.tolist()
coords = np.empty((*resol, 3), float)
for vi, v in enumerate(params_v):
for ui, u in enumerate(params_u):
coords[ui, vi] = bezier_surf_eval(cps, u, v, deg_u=du, deg_v=dv)
return np.array(coords, np.float32)
def bezier_surface_M(cps: np.ndarray, resol=(16, 16)):
u = np.linspace(0, 1, resol[0])
v = np.linspace(0, 1, resol[1])
count_u, count_v, _ = cps.shape
deg_u, deg_v = count_u - 1, count_v - 1
u_vec = np.array([u ** i for i in range(count_u)])
v_vec = np.array([v ** i for i in range(count_v)])
BM_u, BM_v = BM[deg_u], BM[deg_v]
return u_vec.T.dot(BM_u).dot(cps).dot(BM_v.T).dot(v_vec)
fig: Figure = plt.figure(figsize=(7, 7))
ax: Axes3D = fig.add_subplot(111, projection='3d')
# ax.scatter(px, py, pz)
# --------------
resol = 16, 16
co = bezier_surface_slow(poles5x3, resol=resol)
x, y, z = co.T
ax.plot_surface(x, y, z, cmap=cm.gray, linewidth=1, antialiased=False)
# --------------
resol = 16, 16
co = bezier_surface_M(poles5x3, resol=resol)
x, y, z = co.T
ax.plot_surface(x, y, z, cmap=cm.gray, linewidth=1, antialiased=False)
plt.show()
Looks like i solved it.
Problem was in bad order for matrices (in method "bezier_surface_M") for dot product. Multiplication with per-axis matrices with correct orders do the job.
Replaced:
u_vec.T.dot(BM_u).dot(cps).dot(BM_v.T).dot(v_vec)
With:
cps_x = cps[:, :, 0]
cps_y = cps[:, :, 1]
cps_z = cps[:, :, 2]
m1 = u_vec.T.dot(BM_u)
m2 = BM_v.T.dot(v_vec)
x = m1.dot(cps_x).dot(m2)
y = m1.dot(cps_y).dot(m2)
z = m1.dot(cps_z).dot(m2)
Maybe it can be optimized with np.tensorproduct or something like that, but i`m not as good with numpy and matrices math.
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm
from matplotlib.figure import Figure
from mpl_toolkits.mplot3d.axes3d import Axes3D
from scipy.special import comb
def bezier_matrix(d):
return np.array([[(-1) ** (i - j) * comb(j, i) * comb(d, j) for i in range(d + 1)] for j in range(d + 1)], int)
BM = [bezier_matrix(i) for i in range(16)]
poles5x3 = np.array([
[[1.8, -0.3, 0.], [1.8, 0.13, 0.1], [1.8, 0.5, 0.]],
[[2., -0.3, 0.06], [2.1, 0.1, 0.1], [2.1, 0.5, 0.1]],
[[2.3, -0.3, 0.1], [2.3, 0.13, 0.2], [2.3, 0.5, 0.1]],
[[2.4, -0.3, 0.1], [2.5, 0.1, 0.15], [2.5, 0.5, 0.1]],
[[2.6, -0.3, 0.], [2.6, 0.1, 0.1], [2.5, 0.5, 0.]]])
def bezier_surface_M(cps: np.ndarray, resol=(16, 16)):
u, v = np.linspace(0, 1, resol[0]), np.linspace(0, 1, resol[1])
count_u, count_v, _ = cps.shape
deg_u, deg_v = count_u - 1, count_v - 1
u_vec = np.array([u ** i for i in range(count_u)])
v_vec = np.array([v ** i for i in range(count_v)])
BM_u, BM_v = BM[deg_u], BM[deg_v]
cps_x = cps[:, :, 0]
cps_y = cps[:, :, 1]
cps_z = cps[:, :, 2]
m1 = u_vec.T.dot(BM_u)
m2 = BM_v.T.dot(v_vec)
x = m1.dot(cps_x).dot(m2)
y = m1.dot(cps_y).dot(m2)
z = m1.dot(cps_z).dot(m2)
return x, y, z
fig: Figure = plt.figure(figsize=(7, 7))
ax: Axes3D = fig.add_subplot(111, projection='3d')
resol = 32, 32
# --------------
x, y, z = bezier_surface_M(poles5x3, resol=resol)
ax.plot_surface(x, y, z, cmap=cm.gray, linewidth=1, antialiased=False)
plt.show()

How to execute this code when error is lowest?

In this work, I wrote a code. There are 3 points, and y(4th point) is the point which is the point sum of euclidean minimum to other 3 points.
Firt I wrote it to work for first 50 iterations. It works perfect. And it finds the right y point.
But I want it to work when, |yi+1 - yi| is higher than "error(in this case I choose it 10**-5)" value.
|yi+1 - yi| =>> euclidean distance between last and current
iteration
Here is my code;
"e" is the last iteration. But "e" updates(equals to current iteration) everytime when program exits "for loops". So in 2nd iteration "eps" equals to "0" and my code executes. I can not understand why :(
import math as m
a = ([1.0, 2.0, 3.0],
[20.0, 18.0, 25.0],
[10.0, 12.0, 42.0])
y = ([0.0, 0.0, 0.0])
x = ([0.0, 0.0, 0.0])
r = 0
t = 0
e = [0.0 , 0.0, 0.0]
eps = 10
while (eps > 10**-5):
for i in range(3):
for j in range(3):
c = (a[j][i]/(m.sqrt((a[j][0]-y[0])**2+(a[j][1]-y[1])**2+(a[j][2]-y[2])**2)))
b = 1/(m.sqrt((a[j][0]-y[0])**2+(a[j][1]-y[1])**2+(a[j][2]-y[2])**2))
r += c
t += b
x[i] = r/t
r = 0
t = 0
y = x
eps = (m.sqrt((y[0]-e[0])**2+(y[1]-e[1])**2+(y[2]-e[2])**2))
e = y
print("y= ", y)
I solved the problem. Thanks for -1. You helped a lot.
import math as m
a = ([1.0, 2.0, 3.0],
[20.0, 18.0, 25.0],
[10.0, 12.0, 42.0])
def euclideanminpoint(a):
y = ([0.0, 0.0, 0.0])
x = ([0.0, 0.0, 0.0])
r = 0
t = 0
e = [0.0 , 0.0, 0.0]
eps = 10
k = 0
while (eps > 10**-5):
for i in range(3):
for j in range(3):
c = (a[j][i]/(m.sqrt((a[j][0]-y[0])**2+(a[j][1]-y[1])**2+(a[j][2]-y[2])**2)))
b = 1/(m.sqrt((a[j][0]-y[0])**2+(a[j][1]-y[1])**2+(a[j][2]-y[2])**2))
r += c
t += b
x[i] = r/t
r = 0
t = 0
y = x
eps = (m.sqrt((y[0]-e[0])**2+(y[1]-e[1])**2+(y[2]-e[2])**2))
for i in range(3):
e[i] = y[i]
k += 1
print("i= ","y= ","\n", k, y)
euclideanminpoint(a)

TypeError: x must be a python list of GEKKO parameters, variables, or expressions

I try to solve an optimization problem with Gekko in google Collab and this error is shown (in line 91 m.Obj(m.sum(m.sum(((xl[i](D_input[i] + D_output[i])/0.5)+ (xf[i][j]((D_input[i] / ru[i][j]) + (D_output[i] / rd[i][j]) +((D_input[i] + D_output[i]) / rf[i][j])))+ (xc*((D_input[i] / ru[i][j]) + (D_output[i] / rd...):
TypeError: x must be a python list of GEKKO parameters, variables, or expressions
!pip install gekko
from gekko import GEKKO
m = GEKKO()
MU = 5
FN = 3
Cloud = 1
D_input = m.Param(value=[2, 4, 7, 6, 9])
D_output = m.Param(value=[0.2, 0.25, 0.6, 0.35, 0.81])
RF_total = m.Param(value=[10, 10, 10])
RU_total = m.Param(value=[72, 72, 72])
RD_total = m.Param(value=[72, 72, 72])
c = m.Param(value=[0.2, 0.4, 0.7, 0.6, 0.9])
tr = m.Param(value=[10, 10, 10, 10, 10])
fl = m.Param(value=[0.5, 0.5, 0.5, 0.5, 0.5])
nu = m.Const(1.37)
fc = m.Const(10)
wc = m.Const(5)
eu = m.Const(0.142)
ed = m.Const(0.142)
euc = m.Const(0.658)
edc = m.Const(0.278)
el = m.Param(value=[0.0, 0.0, 0.0, 0.0, 0.0])
eed = m.Param(value=[[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0,
0.0]])
eeu = m.Param(value=[[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0,
0.0]])
eedc = m.Param(value=[0.0, 0.0, 0.0, 0.0, 0.0])
eeuc = m.Param(value=[0.0, 0.0, 0.0, 0.0, 0.0])
eef = m.Param(value=[[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0,
0.0]])
eec = m.Param(value=[0.0, 0.0, 0.0, 0.0, 0.0])
for i in range(MU) :
el[i] = nu * c[i]
for i in range(MU) :
for j in range(FN) :
eed[i][j] = D_output[i] * ed
eeu[i][j] = D_input[i] * eu
for i in range(MU) :
for j in range(FN) :
eef[i][j] = eeu[i][j] + eed[i][j]
for i in range(MU) :
eedc[i] = edc * D_output[i]
eeuc[i] = euc * D_input[i]
for i in range(MU) :
eec[i] = eeuc[i] + eedc[i]
xf = [[m.Var(value=0,lb=0,ub=1,integer=True) for j in range(FN)] for i in range(MU)]
xc = m.Var(value=0,lb=0,ub=1,integer=True)
xl = [m.Var(value=0,lb=0,ub=1,integer=True) for i in range(MU)]
ru = [[m.Var(value=0.01, lb=0.01, ub=72.0) for j in range(FN)] for i in range(MU)]
rd = [[m.Var(value=0.01, lb=0.01, ub=72.0) for j in range(FN)] for i in range(MU)]
rf = [[m.Var(value=0.01, lb=0.01, ub=10.0) for j in range(FN)] for i in range(MU)]
for j in range(FN):
m.Equation(sum(rf[i][j] for i in range(MU)) <= 10)
for j in range(FN):
m.Equation(sum(ru[i][j] for i in range(MU)) <= 72)
for j in range(FN):
m.Equation(sum(rd[i][j] for i in range(MU)) <= 72)
for i in range(MU):
m.Equation(xc + xl[i] + sum(xf[i][j] for j in range(FN)) == 1)
for i in range(MU):
m.Equation(xl[i]*(( D_input[i] + D_output[i])/0.5) <= 7)
for j in range(FN):
for i in range(MU):
m.Equation(((xf[i][j]*((D_input[i] / ru[i][j]) + (D_output[i] / rd[i][j]) + ((D_input[i] +
D_output[i]) / rf[i][j])))) <= 7)
for i in range(MU):
m.Equation(((xc*((D_input[i] / ru[i][j]) + (D_output[i] / rd[i][j]) + (3*(D_input[i] +
D_output[i]) / 10)))) <= 7)
for i in range(MU):
m.Equation(((D_input[i] + D_output[i])/0.5) <= tr[i])
for j in range(FN):
for i in range(MU):
m.Equation(((((D_input[i] / ru[i][j]) + (D_output[i] / rd[i][j]) + ((D_input[i] + D_output[i])
/ rf[i][j])))) <= tr[i])
for i in range(MU):
m.Equation(((((D_input[i] / ru[i][j]) + (D_output[i] / rd[i][j]) + (3*(D_input[i] + D_output[i]) / 10)))) <= tr[i])
m.Obj(m.sum(m.sum(((xl[i]*(D_input[i] + D_output[i])/0.5)+\
(xf[i][j]*((D_input[i] / ru[i][j]) + (D_output[i] / rd[i][j]) +((D_input[i] + D_output[i]) /
rf[i][j])))+\
(xc*((D_input[i] / ru[i][j]) + (D_output[i] / rd[i][j]) + (3*(D_input[i] + D_output[i]) /
10))))+\
(xf[i][j]*eef[i][j]) + (xc*eec[i]) + (xl[i]*el[i]) for i in range(MU)) for j in range(FN)))
m.options.SOLVER=1
m.solver_options = ['minlp_maximum_iterations 500', \
# minlp iterations with integer solution
'minlp_max_iter_with_int_sol 10', \
# treat minlp as nlp
'minlp_as_nlp 0', \
# nlp sub-problem max iterations
'nlp_maximum_iterations 50', \
# 1 = depth first, 2 = breadth first
'minlp_branch_method 1', \
# maximum deviation from whole number
'minlp_integer_tol 0.05', \
# covergence tolerance
'minlp_gap_tol 0.01']
m.solve()
print('Results')
print('Objective: ' + str(m.options.objfcnval))
please help me
Thanks.
Use m.Array() to define multidimensional m.Param and m.Var values.
D_input = m.Array(m.Param,5)
for v in [2,4,7,6,9]:
D_input[i].value = v
or
eef = m.Array(m.Param,(5,3),value=0)
Here is a minimal example problem:
from gekko import GEKKO
import numpy as np
m = GEKKO(remote=False)
ni = 3; nj = 2; nk = 4
# solve AX=B
A = m.Array(m.Var,(ni,nj),lb=0)
X = m.Array(m.Var,(nj,nk),lb=0)
AX = np.dot(A,X)
B = m.Array(m.Var,(ni,nk),lb=0)
# equality constraints
m.Equations([AX[i,j]==B[i,j] for i in range(ni) \
for j in range(nk)])
m.Equation(5==m.sum([m.sum([A[i][j] for i in range(ni)]) \
for j in range(nj)]))
m.Equation(2==m.sum([m.sum([X[i][j] for i in range(nj)]) \
for j in range(nk)]))
# objective function
m.Minimize(m.sum([m.sum([B[i][j] for i in range(ni)]) \
for j in range(nk)]))
m.solve()
print(A)
print(X)
print(B)
Here are some additional matrix operations with Numpy:
import numpy as np
from gekko import GEKKO
m = GEKKO(remote=False)
# Random 3x3
A = np.random.rand(3,3)
# Random 3x1
b = np.random.rand(3,1)
# Gekko array 3x3
p = m.Array(m.Param,(3,3))
# Gekko array 3x1
y = m.Array(m.Var,(3,1))
# Dot product of A p
x = np.dot(A,p)
# Dot product of x y
w = np.dot(x,y)
# Dot product of p y
z = np.dot(p,y)
# Trace (sum of diag) of p
t = np.trace(p)
# solve Ax = b
s = m.axb(A,b)
m.solve()
xf = [[m.Var(value=0,lb=0,ub=1,integer=True) for j in range(FN)] for i in range(MU)]
xc = m.Var(value=0,lb=0,ub=1,integer=True)
xl = [m.Var(value=0,lb=0,ub=1,integer=True) for i in range(MU)]
ru = [[m.Var(value=0.01, lb=0.01, ub=72.0) for j in range(FN)] for i in range(MU)]
rd = [[m.Var(value=0.01, lb=0.01, ub=72.0) for j in range(FN)] for i in range(MU)]
rf = [[m.Var(value=0.01, lb=0.01, ub=10.0) for j in range(FN)] for i in range(MU)]
They are lists of lists of m.Var() objects.
We need to make it a list of m.Var() objects.
Not so familiar with Gekko but still hope this could help.

Build a dataframe from a filtered list of tuple

I have a two lists
kuid -> ['LOdRTFfn', 'Lckq4LkU', 'LcsYHodm']
And NN that is a list of tuple where the first element is a list of indexs of kuid and the other element is an array of values
NN -> [([0, 1, 2], [0.0, 1.2, 1.4]), ([1, 0, 2], [0.0, 1.4, 1.4]), ([2, 0, 1], [0.0, 1.1, 1.4])]
I'd like to keep only the indexes where the values are less then 1.3 for example:
[([0, 1], [0.0, 1.2]), ([1], [0.0]), ([2, 0], [0.0, 1.1])]
and then get the correct value of kuid and build a dataframe:
kuid la lametric
0 LOdRTFfn [LOdRTFfn, Lckq4LkU] [0.0, 1.2]
1 Lckq4LkU [Lckq4LkU] [0.0]
2 LcsYHodm [LcsYHodm, LOdRTFfn] [0.0, 1.1]
Is it possible to do this with list of comprehensions (or other fast solution) avoiding looping? The array could be very large....
Thank you
Here's one way
In [1789]: df = pd.DataFrame(dict(kuid=kuid, NN=[np.array(x) for x in NN]))
In [1790]: df['lametric'] = df.NN.apply(lambda x: x[1][x[1] < 1.3])
In [1791]: df['la'] = df.NN.apply(lambda x: [kuid[int(i)] for i in x[0][x[1] < 1.3]])
In [1792]: df
Out[1792]:
NN kuid lametric \
0 [[0.0, 1.0, 2.0], [0.0, 1.2, 1.4]] LOdRTFfn [0.0, 1.2]
1 [[1.0, 0.0, 2.0], [0.0, 1.4, 1.4]] Lckq4LkU [0.0]
2 [[2.0, 0.0, 1.0], [0.0, 1.1, 1.4]] LcsYHodm [0.0, 1.1]
la
0 [LOdRTFfn, Lckq4LkU]
1 [Lckq4LkU]
2 [LcsYHodm, LOdRTFfn]

Python: adjust coordinates

I have this Python script which should adjust the coordinates of a set of triangular elements. The script should change the coordinates of the nodes from an element towards the centre of gravity of the element. The below image is a sketch I made of the problem.
However something is wrong in my script, and I can't figure out what. The coordinates are not changed in the correct direction and extra new coordinates are generated, while I only want to adjust the existing coordinates.
Does anyone know how to correctly program this in Python?
coords = [[0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [0.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 1.0], [1.0, 1.0], [0.0, 2.0], [0.0, 2.0], [1.0, 1.0], [1.0, 2.0], [1.0, 1.0], [2.0, 1.0], [1.0, 2.0], [1.0, 2.0], [2.0, 1.0], [2.0, 2.0], [1.0, 1.0], [2.0, 0.0], [2.0, 1.0], [1.0, 0.0], [2.0, 0.0], [1.0, 1.0]]
elems = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13, 14], [15, 16, 17], [18, 19, 20], [21, 22, 23]]
#define vectors
def add_vectors(*points):
new_x = 0.0
new_y = 0.0
for point in points:
new_x += point[0]
new_y += point[1]
return [new_x, new_y]
def subtract_vectors(a, b):
new_x = a[0] - b[0]
new_y = a[1] - b[1]
return [new_x, new_y]
def mul_by_scalar(vector, scalar):
new_x = vector[0] * scalar
new_y = vector[1] * scalar
return [new_x, new_y]
#define triangles
triangles = []
for elem in elems:
triangles += [coords[e] for e in elem]
#adjust coordinates
CM = mul_by_scalar(add_vectors(*triangles), 1.0/3)
point_to_CM_vectors = []
for point in triangles:
point_to_CM_vectors.append(subtract_vectors(CM, point))
new_triangle = []
for elem in elems:
for point, motion in zip(triangles, point_to_CM_vectors):
new_triangle.append(add_vectors(point, mul_by_scalar(motion, 0.01)))
print 'triangles =', triangles
print 'new_triangle =', new_triangle
Thanks in advance for any help!
Here's a reworking of your problem using the vectorization operators provided by numpy.
import numpy as np
#define triangles
triangles = np.array([[coords[e] for e in elem] for elem in elems])
#find centroid of each triangle
CM = np.mean(triangles,axis=1)
#find vector from each point in triangle pointing towards centroid
point_to_CM_vectors = CM[:,np.newaxis] - triangles
#calculate similar triangles 1% smaller
new_triangle = triangles + 0.01*point_to_CM_vectors

Categories

Resources