Related
I voxelize the STL file with the program below and save it as a vtk file.
The code itself is fine, as the program below works fine.
However, I want to convert it to numpy.array format and save it in npz format as well. Using vtk_to_numpy doesn't work, what should I do?
The ultimate goal is to convert it to numpy.array format and use it for 3d deeplearning.
e.g.
Taking 333 voxel data as an example,
I want to generate np.array with shape (3,3,3) like below
[
[[0,0,0],
[0,1,0],
[0,0,0]]
[[1,1,1],
[1,1,1],
[0,0,0]]
[[1,1,1],
[0,0,0],
[0,0,0]]
]
import vtk
import time
import numpy as np
import vtk.util.numpy_support as vnp
######## data ########
filename_in = "<your STL>.stl"
filename_out = "out.vtk"
mesh_size = 100
tol = 1e-7
cubicORrect = "rect"
##################################
start = time.time()
reader = vtk.vtkSTLReader()
reader.SetFileName(filename_in)
reader.Update()
closed_poly = reader.GetOutput()
# x_min:0 x_max:1, y_min:2,y_max:3,z_min:4,z_max:5
bounds = closed_poly.GetBounds()
max_size = max([bounds[1] - bounds[0], bounds[3] -
bounds[2], bounds[5] - bounds[4]])
cell_dims = [mesh_size, mesh_size, mesh_size] # x, y, z
if cubicORrect == "cubic":
mesh_pitch = [max_size/cell_dims[0],
max_size/cell_dims[1],
max_size/cell_dims[2]]
else:
mesh_pitch = [(bounds[1] - bounds[0])/cell_dims[0],
(bounds[3] - bounds[2])/cell_dims[1],
(bounds[5] - bounds[4])/cell_dims[2]]
mins = [bounds[0], bounds[2], bounds[4]]
px, py, pz = mesh_pitch
mx, my, mz = (cell_dims+np.array([1, 1, 1])) * mesh_pitch # max
points = vtk.vtkPoints()
coords = np.stack(np.mgrid[:mx:px, :my:py, :mz:pz], -1).reshape(-1, 3) + mins
points.SetData(vnp.numpy_to_vtk(coords))
structured_base_mesh = vtk.vtkStructuredGrid()
structured_base_mesh.SetExtent(
0, cell_dims[0], 0, cell_dims[1], 0, cell_dims[2])
structured_base_mesh.SetPoints(points)
append = vtk.vtkAppendFilter()
append.AddInputData(structured_base_mesh)
append.Update()
base_mesh = append.GetOutput()
cell_centers = vtk.vtkCellCenters()
cell_centers.SetInputData(base_mesh)
cell_centers.Update()
poly_points = cell_centers.GetOutput()
select_enclosed = vtk.vtkSelectEnclosedPoints()
select_enclosed.SetInputData(poly_points)
select_enclosed.SetSurfaceData(closed_poly)
select_enclosed.SetTolerance(tol)
select_enclosed.Update()
isInsideOrOutside = select_enclosed.GetOutput(
).GetPointData().GetArray("SelectedPoints")
structured_base_mesh.GetCellData().AddArray(isInsideOrOutside)
threshold = vtk.vtkThreshold()
threshold.SetInputArrayToProcess(
0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, "SelectedPoints")
threshold.SetInputData(structured_base_mesh)
threshold.ThresholdBetween(0, 1)
threshold.Update()
writer = vtk.vtkDataSetWriter()
writer.SetFileName(filename_out)
writer.SetInputData(threshold.GetOutput())
writer.Update()
nparray = vnp.vtk_to_numpy(threshold.GetOutput().GetCellData().GetArray("SelectedPoints"))
Steps to create the 3d shaped numpy array:
get the vtkDataArray you want. Something like threshold.GetOutput().GetPointData().GetArary(<arrayname>)
turn it into numpy array using vtk_to_numpy. This returns a 'flat' array: 1D list of all values
reshape it according the the mesh dimensions (threshold.GetOutput().GetDimensions())
Inspirated from this answer https://discourse.vtk.org/t/convert-vtk-array-to-numpy-array/3152/4
import vtk
import time
import numpy as np
import vtk.util.numpy_support as vnp
######## data ########
filename_in = "<your STL>.stl"
filename_out = "out.vtk"
mesh_size = 100
tol = 1e-7
cubicORrect = "rect"
##################################
start = time.time()
reader = vtk.vtkSTLReader()
reader.SetFileName(filename_in)
reader.Update()
closed_poly = reader.GetOutput()
# x_min:0 x_max:1, y_min:2,y_max:3,z_min:4,z_max:5
bounds = closed_poly.GetBounds()
max_size = max([bounds[1] - bounds[0], bounds[3] -
bounds[2], bounds[5] - bounds[4]])
cell_dims = [mesh_size, mesh_size, mesh_size] # x, y, z
if cubicORrect == "cubic":
mesh_pitch = [max_size/cell_dims[0],
max_size/cell_dims[1],
max_size/cell_dims[2]]
else:
mesh_pitch = [(bounds[1] - bounds[0])/cell_dims[0],
(bounds[3] - bounds[2])/cell_dims[1],
(bounds[5] - bounds[4])/cell_dims[2]]
mins = [bounds[0], bounds[2], bounds[4]]
px, py, pz = mesh_pitch
mx, my, mz = (cell_dims+np.array([1, 1, 1])) * mesh_pitch # max
points = vtk.vtkPoints()
coords = np.stack(np.mgrid[:mx:px, :my:py, :mz:pz], -1).reshape(-1, 3) + mins
points.SetData(vnp.numpy_to_vtk(coords))
structured_base_mesh = vtk.vtkStructuredGrid()
structured_base_mesh.SetExtent(
0, cell_dims[0], 0, cell_dims[1], 0, cell_dims[2])
structured_base_mesh.SetPoints(points)
append = vtk.vtkAppendFilter()
append.AddInputData(structured_base_mesh)
append.Update()
base_mesh = append.GetOutput()
cell_centers = vtk.vtkCellCenters()
cell_centers.SetInputData(base_mesh)
cell_centers.Update()
poly_points = cell_centers.GetOutput()
select_enclosed = vtk.vtkSelectEnclosedPoints()
select_enclosed.SetInputData(poly_points)
select_enclosed.SetSurfaceData(closed_poly)
select_enclosed.SetTolerance(tol)
select_enclosed.Update()
isInsideOrOutside = select_enclosed.GetOutput(
).GetPointData().GetArray("SelectedPoints")
structured_base_mesh.GetCellData().AddArray(isInsideOrOutside)
threshold = vtk.vtkThreshold()
threshold.SetInputArrayToProcess(
0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, "SelectedPoints")
threshold.SetInputData(structured_base_mesh)
threshold.ThresholdBetween(0, 1)
threshold.Update()
writer = vtk.vtkDataSetWriter()
writer.SetFileName(filename_out)
writer.SetInputData(threshold.GetOutput())
writer.Update()
nparray = vnp.vtk_to_numpy(threshold.GetOutput().GetCellData().GetArray("SelectedPoints"))
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 10 months ago.
Improve this question
This problem has been occurring for a couple months now with any project that uses complicated sets of equations (such as for composite mechanics analysis or thrust/fluid flow analysis). Simple calculations, iterative methods, and Numpy matrices seem to work fine on their own though. And just to be sure, I have tried completely uninstalling and reinstalling Python and Pycharm, but the same problem persists.
For the past couple months, any code that incorporates more complex mathematics, such as those described above, will output different values despite all input values and calculations being constant. The different codes have no means of variation or randomness. I've noticed these incorrect outputs usually occur within arrays/matrices, and I can tell the output values are incorrect because the expected numbers are instead absurdly large.
For example, an element within a matrix is expected to be 5.197e+7, but instead, the code outputs 3.322e+257 for that same element. However, upon running the code a second time, the code produces an output of 2.822e+204 for the exact same element. Only upon the third run does the code output the correct value for that element, which is 5.197e+7. This process can take anywhere from 1 to 15 separate runs for the same, unchanging code in order to output the correct value.
Another interesting aspect is that the calculations I am coding usually require multiple iterations of said code. However, even though I am resetting the arrays that temporarily save all values (other than final values that no longer affect the calculations), whatever is causing these "errors is being carried through the code until the end of the iterations. To my understanding, this shouldn't be the case since, at the end of an iteration, the code is setting all values, other than the known initial values, to 0 and recalculating. This would mean that the code is continuously making the same error.
Below are some examples of the program's expected output vs actual outputs.
Expected Output for First Iteration
NM = [[ 2.57939977e+04]
[ 3.03926820e+04]
[-3.55271368e-13]
[ 1.00000000e+00]
[ 1.00000000e+00]
[ 2.60208521e-16]]
[A] =
[[1.50155575e+08 4.45004838e+07 0.00000000e+00]
[4.44974703e+07 1.07288531e+08 0.00000000e+00]
[0.00000000e+00 0.00000000e+00 5.19662175e+07]]
[D] =
[[60.771 7.663 4.019]
[ 7.659 12.322 4.019]
[ 4.019 4.019 9.567]]
1st Attempt: Actual Output for First Iteration
NM =
[[2.57939977e+004]
[7.26576487e+225]
[2.35904846e+253]
[7.25895469e+242]
[1.18107381e+291]
[1.61312569e+291]]
[A] =
[[1.50155575e+08 4.45004838e+07 0.00000000e+00]
[4.44974703e+07 1.07288531e+08 0.00000000e+00]
[0.00000000e+00 0.00000000e+00 5.19662175e+07]]
[D] =
[[60.771 7.663 4.019]
[ 7.659 12.322 4.019]
[ 4.019 4.019 9.567]]
2nd Try: First Iteration
NM = [[2.18479897e+158]
[3.03926820e+004]
[1.62552246e+034]
[1.00000121e+000]
[1.07935186e+000]
[2.60208521e-016]]
[A] =
[[1.50155575e+08 4.45004838e+07 0.00000000e+00]
[4.44974703e+07 1.07288531e+08 0.00000000e+00]
[0.00000000e+00 0.00000000e+00 5.19662175e+07]]
[D] =
[[60.771 7.663 4.019]
[ 7.659 12.322 4.019]
[ 4.019 4.019 9.567]]
3rd Try: First Iteration
NM = [[ 2.57939977e+004]
[ 3.03926820e+004]
[-3.55271368e-013]
[ 4.54183603e+225]
[ 6.28847407e+094]
[ 2.60208521e-016]]
[A] =
[[1.50155575e+08 4.45004838e+07 0.00000000e+00]
[4.44974703e+07 1.07288531e+08 0.00000000e+00]
[0.00000000e+00 0.00000000e+00 5.19662175e+07]]
[D] =
[[60.771 7.663 4.019]
[ 7.659 12.322 4.019]
[ 4.019 4.019 9.567]]
4th Try: First Iteration
NM = [[ 2.57939977e+04]
[ 3.03926820e+04]
[-3.55271368e-13]
[ 1.00000000e+00]
[ 1.00000000e+00]
[ 2.60208521e-16]]
[A] =
[[1.50155575e+008 4.45004838e+007 0.00000000e+000]
[4.44974703e+007 1.07288531e+008 0.00000000e+000]
[0.00000000e+000 0.00000000e+000 2.39203287e+198]]
[D] =
[[60.771 7.663 4.019]
[ 7.659 12.322 4.019]
[ 4.019 4.019 9.567]]
As can be seen, the fourth iteration finally produced the correct NM matrix; however, the [A] matrix goes from having the correct values to an incorrect A[3][3] element. However, after a few more attempts at re-running the program, the program finally outputs all three correct matrices. As stated before, this can take anywhere between 1 and 15 attempts.
At this point, I'm lost with what could be causing these issues. I've given my code to others to run on their own computers and the program seems to have no issue. Any advice on how I can resolve this would be greatly appreciated. The full code and instructions for viewing the first iteration is below. If anything else is needed, please let me know.
To Re-create
Run the code making sure C.stress_critical_loads() is commented out and C.tsai_wu() is not commented out in the main method.
After running, scroll to the top of the output and then scroll down until the first instances of NM, [A], [B], and [D].
If you see an error message in the middle of the output code, it's because the NM matrix is wrong. The error message goes away when the NM matrix is correct. The program also runs despite the error message.
Thanks again for any advice anyone can give.
import numpy as np
import math
from tabulate import *
def stress_transformation_matrix(x):
# This function calculates the stress transformation
# matrix given an input value for the ply angle
return np.array([
[math.cos(x)**2, math.sin(x)**2, 2*math.sin(x)*math.cos(x)],
[math.sin(x)**2, math.cos(x)**2, -2*math.sin(x)*math.cos(x)],
[-math.sin(x)*math.cos(x), math.sin(x)*math.cos(x), math.cos(x)**2 - math.sin(x)**2]
])
def strain_transformation_matrix(x):
# This function calculates the strain transformation
# matrix given an input value for the ply angle
return np.array([
[math.cos(x)**2, math.sin(x)**2, math.sin(x)*math.cos(x)],
[math.sin(x)**2, math.cos(x)**2, -math.sin(x)*math.cos(x)],
[-2*math.sin(x)*math.cos(x), 2*math.sin(x)*math.cos(x), math.cos(x)**2-math.sin(x)**2]
])
def local_stiffness_matrix(E11, E22, G12, v12, v21):
# This function calculates the local stiffness
# given the material properties at each ply
return np.array([
[E11 / (1 - v12 * v21), v21 * E11 / (1 - v12 * v21), 0],
[v12 * E22 / (1 - v12 * v21), E22 / (1 - v12 * v21), 0],
[0, 0, G12]
])
class Properties:
def __init__(self):
# Material Properties
self.M_E11 = np.array([181E9, 204E9, 138E9, 38.6E9, 76E9])
self.M_E22 = np.array([10.3E9, 18.5E9, 9E9, 8.3E9, 5.5E9])
self.M_G12 = np.array([7.17E9, 5.59E9, 7.1E9, 4.14E9, 2.3E9])
self.M_v12 = np.array([0.280, 0.230, 0.300, 0.260, 0.340])
self.M_v21 = np.array([0.016, 0.021, 0.019, 0.056, 0.33])
self.E11 = np.array([])
self.E22 = np.array([])
self.G12 = np.array([])
self.v12 = np.array([])
self.v21 = np.array([])
# Ultimate Failure Strengths
self.P_SLT = np.array([1500E6, 1260E6, 1447E6, 1062E6, 1400E6])
self.P_SLc = np.array([1500E6, 2499E6, 1447E6, 610E6, 235E6])
self.P_STt = np.array([40E6, 61E6, 52E6, 31E6, 12E6])
self.P_STc = np.array([246E6, 202E6, 206E6, 118E6, 53E6])
self.P_SLTs = np.array([68E6, 67E6, 93E6, 72E6, 34E6])
self.SLT = np.array([])
self.SLc = np.array([])
self.STt = np.array([])
self.STc = np.array([])
self.SLTs = np.array([])
# Ultimate Failure Strains
self.P_epsLtf = np.array([1.087E-2, 0, 1.380E-2, 2.807E-2, 0])
self.P_epsLcf = np.array([0.652E-2, 0, 1.175E-2, 1.754E-2, 0])
self.P_epsCtf = np.array([0.245E-2, 0, 0.436E-2, 0.456E-2, 0])
self.P_epsCcf = np.array([1.818E-2, 0, 2E-2, 1.2E-2, 0])
self.P_epsLTs = np.array([4E-2, 0, 2E-2, 4E-2, 0])
self.epsLtf = np.array([])
self.epsLcf = np.array([])
self.epsCtf = np.array([])
self.epsCcf = np.array([])
self.epsLTs = np.array([])
# Strength Ratios for stress and strain
self.R11_s = np.array([])
self.R22_s = np.array([])
self.R12_s = np.array([])
self.R11_e = np.array([])
self.R22_e = np.array([])
self.R12_e = np.array([])
self.R_crit_s = np.array([])
self.R_crit_e = np.array([])
# Tsai-Wu Coefficients
self.F11 = np.array([])
self.F22 = np.array([])
self.F12 = np.array([])
self.F66 = np.array([])
self.F1 = np.array([])
self.F2 = np.array([])
# Stiffness and Transformation Matrices
self.Q = np.array([])
self.Q_hat = np.array([])
self.T = np.array([])
self.T_hat = np.array([])
# ABD Matrices
self.A = np.empty(shape=(3, 3))
self.B = np.empty(shape=(3, 3))
self.D = np.empty(shape=(3, 3))
self.ABD = np.empty(shape=(6, 6))
# Laminate Loads
self.Nxx = 200
self.Nyy = 200
self.Nxy = 0
self.Mxx = 1
self.Myy = 1
self.Mxy = 0
self.N_mech = np.array([])
self.M_mech = np.array([])
self.NT = np.empty(shape=(3, 1))
self.MT = np.empty(shape=(3, 1))
self.NM = np.array([])
self.Nxx_cs = np.array([])
self.Mxx_cs = np.array([])
self.Nxx_ce = np.array([])
self.Mxx_ce = np.array([])
# Mid-plane Strains and Curvatures
self.e0_k = np.array([])
self.e0 = np.array([])
self.k0 = np.array([])
# Stresses and Strains
self.sg = np.array([]) # global stress
self.sl = np.array([]) # local stress
self.eg = np.array([]) # global strain
self.el = np.array([]) # local strain
# Ply Orientations
self.lam = None # total laminate thickness
self.z_lam = np.array([]) # laminate thickness from to pto bottom
self.z_m = np.array([]) # mid-plane laminate thickness
# Table and Material Properties
self.mat = np.array([])
self.mat_list = np.array([])
# Total Ply Failure
self.Beta = np.array([])
# Angle at Each Ply (deg)
self.angle = np.array([0, 0, 45, 45, -45, -45, 90, 90, -45, -45, 45, 45, 0, 0])
self.a = np.array([])
# Thickness at Each Ply (m)
self.z = np.array([0.125E-3, 0.125E-3, 0.125E-3, 0.125E-3, 0.125E-3, 0.125E-3, 0.125E-3, 0.125E-3, 0.125E-3,
0.125E-3, 0.125E-3, 0.125E-3, 0.125E-3, 0.125E-3])
# Number of Ply
self.n = self.angle.size
# Material at Each Ply
self.m = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
# 0: T300/5208
# 1: B(4) 5505
# 2: AS4/3501
# 3: Scotchply 1002
# 4: Kevlar49/Epoxy
# Thermal Properties
self.a1 = -0.018E-6 # longitudinal thermal expansion, deg. C
self.a2 = 24.3E-6 # transverse thermal expansion, deg. C
self.a3 = 0 # shear thermal expansion, deg. C
self.dT = 100 # change in temperature, deg. C
def ply_angle(self):
a = np.array([])
for i in range(self.n):
a = np.append(a, math.radians(self.angle[i]))
self.a = a
def ply(self):
# set total laminate ply failure array
self.Beta = np.full(self.n, 1)
# Determine the thickness of each ply
self.lam = sum(self.z)
print('Total Thickness =', self.lam)
for i in range(self.n):
self.z_lam = np.append(self.z_lam, -self.lam / 2 + (i + 1) * self.z[i])
print('Top-Bottom =', self.z_lam)
for i in range(self.n):
self.z_m = np.append(self.z_m, -self.lam / 2 - self.z[i] / 2 + (i + 1) * self.z[i])
print('Mid-plane =', self.z_m)
def material(self):
for i in range(self.n):
m = self.m[i]
# Material Properties
self.E11 = np.append(self.E11, self.M_E11[m])
self.E22 = np.append(self.E22, self.M_E22[m])
self.G12 = np.append(self.G12, self.M_G12[m])
self.v12 = np.append(self.v12, self.M_v12[m])
self.v21 = np.append(self.v21, self.M_v21[m])
self.mat_list = np.append(self.mat_list, m)
# Ultimate Failure Strengths
self.SLT = np.append(self.SLT, self.P_SLT[m])
self.SLc = np.append(self.STc, self.P_SLc[m])
self.STt = np.append(self.STt, self.P_STt[m])
self.STc = np.append(self.STc, self.P_STc[m])
self.SLTs = np.append(self.SLTs, self.P_SLTs[m])
# Ultimate Failure Strains
self.epsLtf = np.append(self.epsLtf, self.P_epsLtf[m])
self.epsLcf = np.append(self.epsLcf, self.P_epsLcf[m])
self.epsCtf = np.append(self.epsCtf, self.P_epsCtf[m])
self.epsCcf = np.append(self.epsCcf, self.P_epsCcf[m])
self.epsLTs = np.append(self.epsLTs, self.P_epsLTs[m])
# Tsai-Wu Coefficients
self.F11 = np.append(self.F11, 1 / (self.P_SLT[m] * self.P_SLc[m]))
self.F22 = np.append(self.F22, 1 / (self.P_STt[m] * self.P_STc[m]))
self.F12 = np.append(self.F12, -math.sqrt(self.F11[i] * self.F22[i]) / 2)
self.F66 = np.append(self.F66, 1 / self.P_SLTs[m] ** 2)
self.F1 = np.append(self.F1, 1 / self.P_SLT[m] - 1 / self.P_SLc[m])
self.F2 = np.append(self.F2, 1 / self.P_STt[m] - 1 / self.P_STc[m])
if m == 0: self.mat = np.append(self.mat, 'T300/5208')
elif m == 1: self.mat = np.append(self.mat, 'B(4)/5505')
elif m == 2: self.mat = np.append(self.mat, 'AS4/3501')
elif m == 3: self.mat = np.append(self.mat, 'Scotchply 1002')
else: self.mat = np.append(self.mat, 'Kevlar49/Epoxy')
print('F11 = ', self.F11)
print('F22 =', self.F22)
print('F12 =', self.F12)
print('F66 =', self.F66)
print('F1 =', self.F1)
print('F2 =', self.F2)
def mechanical_loads(self):
self.N_mech = np.array([
[self.Nxx],
[self.Nyy],
[self.Nxy]
])
self.M_mech = np.array([
[self.Mxx],
[self.Myy],
[self.Mxy]
])
def local_thermal_coef(self):
al = np.array([
[self.a1],
[self.a2],
[self.a3]
])
return al
def material_properties(self):
# Creates a table for the material properties of each different ply
mat_list = list(map(int, set(self.mat_list)))
for i in mat_list:
data = np.array([[self.E11[i], self.E22[i], self.G12[i], self.v12[i], self.v21[i]]])
Q = local_stiffness_matrix(self.E11[i], self.E22[i], self.G12[i], self.v12[i], self.v21[i])
print('\nMaterial =', self.mat[i], '(in SI units)')
print(tabulate(data, headers=['E11', 'E22', 'G12', 'v12', 'v21']))
print('\nMaterial =', self.mat[i], '(in Pa)')
print('[Q] =\n', np.round(Q, 3))
print('')
def table(self):
# Creates a table of ply number, thickness, orientation and material
table = np.array([])
for i in range(self.n):
data = np.array([[i+1, self.mat[i], self.z[i], math.degrees(self.a[i])]])
if i == 0:
table = np.append(table, data)
else:
table = np.vstack([table, data])
print(tabulate(table, headers=['Lamina', 'Material', 'Thickness', 'Orientation']))
class Calculations(Properties):
def __init__(self):
super().__init__()
self.NM = np.array([]) # Loads and Moments
self.e0_k = np.array([]) # Mid-plane strains and curvatures
self.fail_order = np.array([]) # Ply order of failure
def a_matrix(self):
for i in range(self.n):
T = stress_transformation_matrix(self.a[i])
T_hat = strain_transformation_matrix(self.a[i])
if self.Beta[i] == 1:
Q = local_stiffness_matrix(self.E11[i], self.E22[i], self.G12[i], self.v12[i], self.v21[i])
else:
Q = np.array([
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
])
Q_hat = np.matmul(np.linalg.inv(T), Q)
Q_hat = np.matmul(Q_hat, T_hat)
A = Q_hat * (self.z_lam[i] - (self.z_lam[i] - self.z[i]))
self.A = np.add(self.A, A)
# print('\nLamina', i, '\t\u03B8 =', math.degrees(self.a[i]), 't =', self.z[i], 'Material =', self.mat[i-1])
# print('[Q\u0302] =\n', np.round(Q_hat, 3))
print('\nLaminate Stiffness Matrices\n[A] =\n', np.round(self.A, 3))
def b_matrix(self):
for i in range(self.n):
T = stress_transformation_matrix(self.a[i])
T_hat = strain_transformation_matrix(self.a[i])
if self.Beta[i] == 1:
Q = local_stiffness_matrix(self.E11[i], self.E22[i], self.G12[i], self.v12[i], self.v21[i])
else:
Q = np.array([
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
])
Q_hat = np.matmul(np.linalg.inv(T), Q)
Q_hat = np.matmul(Q_hat, T_hat)
B = Q_hat * (self.z_lam[i] ** 2 - (self.z_lam[i] - self.z[i]) ** 2)
self.B = np.add(self.B, B)
self.B /= 2
print('\n[B] =\n', np.round(self.B, 3))
def d_matrix(self):
for i in range(self.n):
T = stress_transformation_matrix(self.a[i])
T_hat = strain_transformation_matrix(self.a[i])
if self.Beta[i] == 1:
Q = local_stiffness_matrix(self.E11[i], self.E22[i], self.G12[i], self.v12[i], self.v21[i])
else:
Q = np.array([
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
])
Q_hat = np.matmul(np.linalg.inv(T), Q)
Q_hat = np.matmul(Q_hat, T_hat)
D = Q_hat * (self.z_lam[i] ** 3 - (self.z_lam[i] - self.z[i]) ** 3)
self.D = np.add(self.D, D)
self.D /= 3
print('\n[D] =\n', np.round(self.D, 3))
def matrices_combined(self):
self.a_matrix() # call A matrix method
self.b_matrix() # call B matrix method
self.d_matrix() # call D matrix method
self.ABD = np.array([
[np.array(self.A[0][0]), np.array(self.A[0][1]), np.array(self.A[0][2]), np.array(self.B[0][0]), np.array(self.B[0][1]), np.array(self.B[0][2])],
[np.array(self.A[1][0]), np.array(self.A[1][1]), np.array(self.A[1][2]), np.array(self.B[1][0]), np.array(self.B[1][1]), np.array(self.B[1][2])],
[np.array(self.A[2][0]), np.array(self.A[2][1]), np.array(self.A[2][2]), np.array(self.B[2][0]), np.array(self.B[2][1]), np.array(self.B[2][2])],
[np.array(self.B[0][0]), np.array(self.B[0][1]), np.array(self.B[0][2]), np.array(self.D[0][0]), np.array(self.D[0][1]), np.array(self.D[0][2])],
[np.array(self.B[1][0]), np.array(self.B[1][1]), np.array(self.B[1][2]), np.array(self.D[1][0]), np.array(self.D[1][1]), np.array(self.D[1][2])],
[np.array(self.B[2][0]), np.array(self.B[2][1]), np.array(self.B[2][2]), np.array(self.D[2][0]), np.array(self.D[2][1]), np.array(self.D[2][2])],
])
def calculated_loads(self):
self.NM = np.matmul(self.ABD, self.e0_k)
print('\nResulting Loads and Moments\n', np.round(self.NM, 3))
def thermal_loads(self):
al = self.local_thermal_coef()
for i in range(self.n):
T = stress_transformation_matrix(self.a[i])
T_hat = strain_transformation_matrix(self.a[i])
if self.Beta[i] == 1:
Q = local_stiffness_matrix(self.E11[i], self.E22[i], self.G12[i], self.v12[i], self.v21[i])
else:
Q = np.array([
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
])
Q_hat = np.matmul(np.linalg.inv(T), Q)
Q_hat = np.matmul(Q_hat, T_hat)
ag = np.matmul(np.linalg.inv(T_hat), al)
NT = np.matmul(Q_hat, ag) * (self.z_lam[i] - (self.z_lam[i] - self.z[i]))
self.NT = np.add(self.NT, NT)
MT = np.matmul(Q_hat, ag) * (self.z_lam[i] ** 2 - (self.z_lam[i] - self.z[i]) ** 2)
self.MT = np.add(self.MT, MT)
self.NT *= self.dT
self.MT *= (self.dT / 2)
def combined_loads(self):
# Combine the mechanical and thermal loads
self.mechanical_loads()
self.thermal_loads()
N = self.N_mech + self.NT
M = self.M_mech + self.MT
self.NM = np.vstack((N, M))
print('\nNM =', self.NM)
def calculated_midplane_strains_curvatures(self):
self.matrices_combined() # call ABD matrix method
# self.loads()
self.e0_k = np.matmul(np.linalg.inv(self.ABD), self.NM)
# print('\nResulting Mid-Plane Strains and Curvatures\n', self.e0_k)
self.e0 = np.array([
self.e0_k[0],
self.e0_k[1],
self.e0_k[2]
])
self.k0 = np.array([
self.e0_k[3],
self.e0_k[4],
self.e0_k[5]
])
def calculated_stresses_and_strains(self):
self.combined_loads() # call calculated loads method
self.calculated_midplane_strains_curvatures() # call mid-plane strains and curvature method
for i in range(self.n):
eg = np.array([self.e0 + self.z_m[i] * self.k0])
if i == 0:
self.eg = np.array(eg)
else:
self.eg = np.append(self.eg, eg, axis=0)
for i in range(self.n):
T_hat = strain_transformation_matrix(self.a[i])
el = np.matrix(np.matmul(T_hat, self.eg[i]))
if i == 0:
self.el = np.array(el)
else:
self.el = np.append(self.el, el, axis=1)
# All values of local strains are 1x3 arrays, so
# each time the strain is needed, the specific
# array must be selected and then transposed
self.el = np.transpose(self.el)
# print('[Local Strain] =', self.el)
for i in range(self.n):
Q = local_stiffness_matrix(self.E11[i], self.E22[i], self.G12[i], self.v12[i], self.v21[i])
sl = np.matrix(np.matmul(Q, np.transpose(np.matrix(self.el[i]))))
if i == 0:
self.sl = np.array(sl)
else:
self.sl = np.append(self.sl, sl, axis=1)
# All values of local stress are 1x3 arrays, so
# each time the stress is needed, the specific
# array must be selected and then transposed
self.sl = np.transpose(self.sl)
print('\n[Local Stress] =\n', self.sl)
def stress_strength_ratio_11(self):
for i in range(self.n):
sl = np.transpose(self.sl[i])
if float(sl[0]) >= 0:
self.R11_s = np.append(self.R11_s, self.SLT[i] / float(sl[0]))
else:
self.R11_s = np.append(self.R11_s, self.SLc[i] / abs(float(sl[0])))
def stress_strength_ratio_22(self):
for i in range(self.n):
sl = np.transpose(self.sl[i])
if float(sl[1]) >= 0:
self.R22_s = np.append(self.R22_s, self.STt[i] / float(sl[1]))
else:
self.R22_s = np.append(self.R22_s, self.STc[i] / abs(float(sl[1])))
def stress_strength_ratio_12(self):
for i in range(self.n):
sl = np.transpose(self.sl[i])
self.R12_s = np.append(self.R12_s, self.SLTs[i] / abs(float(sl[2])))
def stress_critical_loads(self):
self.calculated_stresses_and_strains()
self.stress_strength_ratio_11() # call R11 method
self.stress_strength_ratio_22() # call R22 method
self.stress_strength_ratio_12() # call R12 method
for i in range(self.n):
R = np.array([
[self.R11_s[i], self.R22_s[i], self.R12_s[i]]
])
if self.Beta[i] == 1:
R_crit = np.min(R)
else:
R_crit = 9999
self.R_crit_s = np.append(self.R_crit_s, R_crit)
self.Nxx_cs = np.append(self.Nxx_cs, R_crit * self.Nxx)
self.Mxx_cs = np.append(self.Mxx_cs, R_crit * self.Mxx)
Nxx_c = np.min(self.Nxx_cs)
N_pos = np.where(self.Nxx_cs == Nxx_c)[0]
Mxx_c = np.min(self.Mxx_cs)
self.fail_order = np.append(self.fail_order, N_pos + 1)
print('\nPly Failure in ply', N_pos + 1)
print('R_crit =', np.min(self.R_crit_s))
print('Critical in-plane loading at ply', N_pos + 1, '=', Nxx_c, '')
print('Critical bending loading at ply', N_pos + 1, '=', Mxx_c, '')
print('Stress: Nxx_c =', Nxx_c)
print('Stress: Mxx_c =', Mxx_c)
Beta = np.full(self.n, 0)
if not np.array_equal(self.Beta, Beta):
self.Beta[N_pos] = 0
print(self.Beta)
# Reset all values
self.A = np.zeros(shape=(3, 3))
self.B = np.zeros(shape=(3, 3))
self.D = np.zeros(shape=(3, 3))
self.ABD = np.zeros(shape=(6, 6))
self.eg = np.zeros([])
self.el = np.zeros([])
self.sl = np.zeros([])
self.NT = np.zeros(shape=(3, 1))
self.MT = np.zeros(shape=(3, 1))
self.NM = np.zeros(shape=(6, 1))
self.R11_s = np.zeros([])
self.R22_s = np.zeros([])
self.R12_s = np.zeros([])
self.R_crit_s = np.zeros([])
self.Nxx_cs = np.zeros([])
self.Mxx_cs = np.zeros([])
# re-run calculations
if not np.array_equal(self.Beta, Beta):
self.stress_critical_loads()
else:
print('Ply Fail Order =', self.fail_order)
def tsai_wu(self):
self.calculated_stresses_and_strains()
a = np.array([])
b = np.array([])
c = np.array([])
R1 = np.array([])
R2 = np.array([])
for i in range(self.n):
sl = np.transpose(self.sl[i])
a = np.append(a, self.F11[i] * sl[0] ** 2 + 2 * self.F12[i] * sl[0] * sl[1]
+ self.F22[i] * sl[1] ** 2 + self.F66[i] * sl[2] ** 2)
b = np.append(b, self.F1[i] * sl[0] + self.F2[i] * sl[1])
c = np.append(c, -1)
for i in range(self.n):
if self.Beta[i] == 1:
R1 = np.append(R1, (-b[i] + math.sqrt(b[i]**2 - 4 * a[i] * c[i])) / (2 * a[i]))
R2 = np.append(R2, (-b[i] - math.sqrt(b[i]**2 - 4 * a[i] * c[i])) / (2 * a[i]))
else:
R1 = np.append(R1, 9999)
R2 = np.append(R2, -9999)
R_crit = np.min(R1)
R_crit_pos = np.where(R1 == R_crit)[0]
# print('R1 =', R1)
# print('R2 =', R2)
print('\nR_cr at ply', R_crit_pos + 1, '=', R_crit, '')
self.fail_order = np.append(self.fail_order, R_crit_pos + 1)
NTW_xxc = R_crit * self.Nxx
MTW_xxc = R_crit * self.Mxx
print('N_xx,cr for ply', R_crit_pos + 1, '=', NTW_xxc)
print('M_xx,cr for ply', R_crit_pos + 1, '=', MTW_xxc)
Beta = np.full(self.n, 0)
if not np.array_equal(self.Beta, Beta):
self.Beta[R_crit_pos] = 0
print('\nFailure Progression =', self.Beta)
# Reset all values
self.A = np.zeros(shape=(3, 3))
self.B = np.zeros(shape=(3, 3))
self.D = np.zeros(shape=(3, 3))
self.ABD = np.zeros(shape=(6, 6))
self.eg = np.zeros([])
self.el = np.zeros([])
self.sl = np.zeros([])
self.NT = np.zeros(shape=(3, 1))
self.MT = np.zeros(shape=(3, 1))
self.NM = np.zeros(shape=(6, 1))
# re-run all values
if not np.array_equal(self.Beta, Beta):
self.tsai_wu()
else:
print('Ply Fail Order =', self.fail_order)
def main():
C = Calculations()
C.ply_angle()
C.ply()
C.material()
C.material_properties()
C.table()
# Comment out for Tsai-Wu failure calculations
# print('\nCritical Stress Criterion')
# C.stress_critical_loads()
# Comment out for Maximum Stress failure calculations
print('\nTsai-Wu Criterion\n')
C.tsai_wu()
if __name__ == '__main__':
main()
I don't know if it's the cause of your problem, but your code has six calls to np.empty. I don't see any later initialization of these arrays.
np.empty causes the array to not be initialized, and the memory will contain random garbage. Try replace those with np.zeros and see if you get better results.
I am getting this weird issue where the dlib.rectangle is working when I try it in python shell, but doesn't work when i try it in a script in the same shell.
def get_faces2(self, image, get_largest=True, return_shape=False):
res = None
shp = None
_, _, pts = self.detector.detect(Image.fromarray(image), landmarks=True)
if pts is not None:
if get_largest:
pts = [pts[0]]
res = np.zeros((len(pts), self.out_size, self.out_size, 3), dtype=np.uint8)
shp = []
for i, pt in enumerate(pts):
face = np.array((min(pt[:, 0]), min(pt[:, 1]), max(pt[:, 0]), max(pt[:, 1])))
w, h = face[2] - face[0], face[3] - face[1]
ex = np.abs(h - w) / 2.
if h > w:
face[[0, 2]] = face[0] - ex, face[2] + ex
else:
face[[1, 3]] = face[1] - ex, face[3] + ex
ex = max(h, w) * 0.5
face[:] = face[0] - ex, face[1] - ex, face[2] + ex, face[3] + ex
rec = dlib.rectangle(*face)
shaped = self.shaper(image, rec)
shp.append(shaped)
aligned = dlib.get_face_chip(image, shaped, size=self.out_size)
res[i] = aligned
if return_shape:
return res, shp, pts
return res
giving me following error:
File "create_masked_face_dataset.py", line 48, in
face, shaped, _ = mtcnn.get_faces2(image, return_shape=True)
File "D:\project\FaceNetPytoch-Mask-master\FaceDetector.py", line 116, in get_faces2
rec = dlib.rectangle(*face)
Boost.Python.ArgumentError: Python argument types in
rectangle.init(rectangle, numpy.float32, numpy.float32, numpy.float32, numpy.float32)
did not match C++ signature:
init(struct _object * __ptr64, long left, long top, long right, long bottom)
init(struct _object * __ptr64)
Please help me on my periodic capacitated vehicle routing problem.
Find the same question here on google-groups.
What I am trying to model:
1 depot
multiple customers (let's assume 4)
multiple days (let's assume 3)
Multiple vehicle types with price per km and specific capacity
Every customer has: delivery frequency and demand per delivery
Every customer has to be assigned to a delivery pattern. Multiple delivery patterns are possible for each frequency. The pattern indicates if a delivery is possible on that day or not. For a frequency of 1 and 3 working days: [[1,0,0],[0,1,0],[0,0,1]], a frequency of 2 [[1,1,0],[1,0,1],[1,1,0]], a frequency of 3: [1,1,1]these are the possible patterns.
The demand of each customer per delivery is the same, for every day a delivery is performed
So we have a set of customers that have to be delivered by one depo. Multiple Vehicle Types are available for the job. The day of service is flexible because only the frequency is fixed to a customer, but there are multiple possibilities to fulfill the demand.
What I did so far:
I copied every node by the number of working days.
I restrict the start and end to the depo nodes of each day.
I multiply the vehicles by the number of days.
Furthermore, I handle the days as different kinds of cargo. I do assign a capacity of zero to the vehicle when it should not be used on that day.
[[10, 15, 15, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 10, 15, 15, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 10, 15, 15]]
The first 3 vehicles are for day one, the second three are day two
and the last 3 are day 3.
For the demand matrix I use the same trick. In a case of 4 customers + 1 depot the demand matrix could look like this
[[0, 3, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 3, 4, 5, 2, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2]]
The second entry in the first list (3) and the 7th entry in the second list (3) are for the same customer just on two different days. The nodes were copied.
This works good so far. But it's not what I want to do.
I do assign a demand for every customer and day by hand, but I want to assign the demand by a chosen delivery pattern for each customer.
The model could assign pattern [1,0,1] to one customer with a frequency of 2 and a pattern of [0,0,1] to another customer. This would result in the possibility to plan a tour on day 3 with both demands combined.
I need help to define a dimension that manages the assignment of patterns to customers which results in "flexible" demand matrix.
Thank you for your help.
Full Code:
"""Periodic Capacited Vehicles Routing Problem (PCVRP)."""
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
import numpy as np
def dublicate_nodes(base_distance_matrix, num_days):
matrix = []
for i in range(num_days):
day_element = []
for node in range(len(base_distance_matrix)):
node_element = []
for day in range(num_days):
node_element.append(base_distance_matrix[node])
day_element.append(np.concatenate(node_element).tolist())
matrix.extend(day_element)
#print(matrix)
return matrix
def depo_nodes(num_days, num_verhicles, num_nodes):
depo_array = []
for day in range(num_days):
for veh in range(int(num_verhicles/num_days)):
depo_array.append(day*num_nodes)
#print(depo_array)
return depo_array
def veh_types_costs(cost_array, num_per_type, num_days):
cost_array_km = []
for day in range(num_days):
for i in range(len(cost_array)):
for num in range(num_per_type[i]):
cost_array_km.append(cost_array[i])
#print(cost_array_km)
return(cost_array_km)
def veh_capacity_matrix(num_vehicle_per_type, vehicle_capacity_type, num_days):
matrix= []
for index in range(num_days):
matrix_element = []
for day in range(num_days):
for i, num in enumerate(num_vehicle_per_type):
for times in range(num):
if day == index:
matrix_element.append(vehicle_capacity_type[i]);
else:
matrix_element.append(0)
matrix.append(matrix_element)
#print(matrix)
return matrix
def create_data_model():
data = {}
data["num_days"] = 3 #Anzahl Tage
### Definition der Fahrezugtypen
data["num_vehicle_per_type"] = [1, 2] #Anzahl Fahrzeuge pro Typ
data["vehicle_costs_type_per_km"] = [1, 0.01] #Kosten pro km pro Fahrzeugtyp
data["vehicle_costs_type_per_stop"] = [1, 1000] #Kosten pro Stop pro Fahrzeugtyp
data['price_per_km'] = veh_types_costs(data["vehicle_costs_type_per_km"], data["num_vehicle_per_type"], data["num_days"]) #Matrix für price_per_km je Fahrzeug ertsellen
data["price_per_stop"] = veh_types_costs(data["vehicle_costs_type_per_stop"], data["num_vehicle_per_type"], data["num_days"])
data["vehicle_capacity_type"] = [10, 15] # Kapaität pro Fahrzeugtyp
data['vehicle_capacities_matrix'] = veh_capacity_matrix(data["num_vehicle_per_type"], data["vehicle_capacity_type"], data["num_days"]) #Kapazitäten pro Fahrzeugs pro Tag
print('vehicle_capacities_matrix')
print(data['vehicle_capacities_matrix'])
data["num_vehicles_per_day"] = sum(data["num_vehicle_per_type"]) #Gesamtanzahl der Fahrzeuge pro Tag
data['num_vehicles'] = data["num_days"] * data["num_vehicles_per_day"]# Gesamtanzahl der Fahrzeuge in gesamten Zeitraum
###Distanzmatrix bestimmen
data["base_distance_matrix"] = [
[
0, 548, 776, 696, 582
],
[
548, 0, 684, 308, 194
],
[
776, 684, 0, 992, 878
],
[
696, 308, 992, 0, 114
],
[
582, 194, 878, 114, 0
]
] #Distanzmatrix mit allen Kunden einzeln
data['distance_matrix'] = dublicate_nodes(data["base_distance_matrix"], data["num_days"]) # Distanzmatrix mit mehrfachen Nodes pro Kunden, je Tag ein Node
###Start und Ende festlegen
data["num_nodes"] = len(data["base_distance_matrix"]) # Anzahl Kunden
data['starts'] = depo_nodes(data["num_days"], data['num_vehicles'], data["num_nodes"]) #Deponodes (Start) für die einzelnen Fahrzeuge (Tage)
data['ends'] = depo_nodes(data["num_days"], data['num_vehicles'], data["num_nodes"]) #Deponodes (Ende) für die einzelnen Fahrzeuge (Tage)
###Demand pro Kunde
data['demands_matrix'] = [[0, 3, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0, 3, 4, 5, 2, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2]] #Demandmatrix mit je einer list pro Tag
return data
def print_solution(data, manager, routing, solution):
"""Prints solution on console."""
total_distance = 0
total_load = 0
for vehicle_id in range(data['num_vehicles']):
if vehicle_id % data["num_vehicles_per_day"] == 0:
print(("------Tag {}------").format(int(vehicle_id/data["num_vehicles_per_day"])))
if routing.IsVehicleUsed(assignment= solution, vehicle=vehicle_id) == False:
continue
index = routing.Start(vehicle_id)
if vehicle_id >= data["num_vehicles_per_day"]:
plan_output = 'Route for vehicle {}:\n'.format(abs(vehicle_id-data["num_vehicles_per_day"]*int(vehicle_id/data["num_vehicles_per_day"])))
else:
plan_output = 'Route for vehicle {}:\n'.format(vehicle_id)
route_costs = 0
route_load = 0
while not routing.IsEnd(index):
node_index = manager.IndexToNode(index)
capacity_ID = int(vehicle_id/data["num_vehicles_per_day"])
route_load += data['demands_matrix'][capacity_ID][node_index]
plan_output += ' {0} Load({1}) -> '.format(node_index, route_load)
previous_index = index
index = solution.Value(routing.NextVar(index))
route_costs += routing.GetArcCostForVehicle(
previous_index, index, vehicle_id)
plan_output += ' {0} Load({1})\n'.format(manager.IndexToNode(index),
route_load)
plan_output += 'Costs of the route: {}€\n'.format(route_costs)
plan_output += 'Load of the route: {}\n'.format(route_load)
print(plan_output)
total_distance += route_costs
total_load += route_load
print('Total costs of all routes: {}€'.format(total_distance))
print('Total load of all routes: {}'.format(total_load))
def main():
"""Periodic CVRP problem."""
# Instantiate the data problem.
data = create_data_model()
# Create the routing index manager.
manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), data['num_vehicles'], data['starts'],
data['ends'])
# Create Routing Model.
routing = pywrapcp.RoutingModel(manager)
### Kostenfunktion je Fahrzeug festlegen ###
def create_cost_callback(dist_matrix, km_costs, stop_costs):
# Create a callback to calculate distances between cities.
def distance_callback(from_index, to_index):
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
return int(dist_matrix[from_node][to_node]) * (km_costs) + (stop_costs)
return distance_callback
for i in range(data['num_vehicles']):
cost_callback = create_cost_callback(data['distance_matrix'], data["price_per_km"][i],
data["price_per_stop"][i]) # Callbackfunktion erstellen
cost_callback_index = routing.RegisterTransitCallback(cost_callback) # registrieren
routing.SetArcCostEvaluatorOfVehicle(cost_callback_index, i) # Vehicle zuordnen
#Define Capacities for Vehicles for every Day
def create_demand_callback(demand_matrix, demand_index):
# Create a callback to calculate capacity usage.
def demand_callback(from_index):
#Returns the demand of the node.
# Convert from routing variable Index to demands NodeIndex.
from_node = manager.IndexToNode(from_index)
return demand_matrix[demand_index][from_node]
return demand_callback
for i in range(data["num_days"]): #Jedes Fahrzeug hat pro Tag eine andere Kapazität
demand_callback = create_demand_callback(data['demands_matrix'], i)
demand_callback_index = routing.RegisterUnaryTransitCallback(demand_callback)
dimension_name = 'Capacity_day_{}'.format(i)
routing.AddDimensionWithVehicleCapacity(
demand_callback_index,
0, # null capacity slack
data['vehicle_capacities_matrix'][i], # vehicle maximum capacities
True, # start cumul to zero
dimension_name)
# Setting first solution heuristic.
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (
routing_enums_pb2.FirstSolutionStrategy.AUTOMATIC)
search_parameters.local_search_metaheuristic = (
routing_enums_pb2.LocalSearchMetaheuristic.AUTOMATIC)
search_parameters.time_limit.FromSeconds(1)
# Solve the problem.
solution = routing.SolveWithParameters(search_parameters)
# Print solution on console.
if solution:
print_solution(data, manager, routing, solution)
return solution
if __name__ == '__main__':
solution_array = []
solution = main()
So I found a solution for my problem.
The solving time for problems greater than 40 customers could be better.
I would appreciate improvement suggestions.
"""Periodic Capacited Vehicles Routing Problem with delivery pattern(PCVRP)."""
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
import numpy as np
import random
import math
import pandas as pd
def dublicate_nodes(base_distance_matrix, num_days):
matrix = []
for i in range(num_days):
day_element = []
for node in range(len(base_distance_matrix)):
node_element = []
for day in range(num_days):
node_element.append(base_distance_matrix[node])
day_element.append(np.concatenate(node_element).tolist())
matrix.extend(day_element)
#print(matrix)
return matrix
def depo_nodes(num_days, num_verhicles, num_nodes):
depo_array = []
for day in range(num_days):
for veh in range(int(num_verhicles/num_days)):
depo_array.append(day*num_nodes)
#print(depo_array)
return depo_array
def veh_types_costs(cost_array, num_per_type, num_days):
cost_array_km = []
for day in range(num_days):
for i in range(len(cost_array)):
for num in range(num_per_type[i]):
cost_array_km.append(cost_array[i])
#print(cost_array_km)
return(cost_array_km)
def veh_capacity_matrix(num_vehicle_per_type, vehicle_capacity_type, num_days):
matrix= []
for index in range(num_days):
matrix_element = []
for day in range(num_days):
for i, num in enumerate(num_vehicle_per_type):
for times in range(num):
if day == index:
matrix_element.append(vehicle_capacity_type[i]);
else:
matrix_element.append(0)
matrix.append(matrix_element)
#print(matrix)
return matrix
def dist_matrix(koordianten):
matrix =[]
for k_1 in koordianten:
matrix_element = []
for k_2 in koordianten:
matrix_element.append(np.linalg.norm(k_1-k_2))
matrix.append(matrix_element)
#print(matrix)
return matrix
def demand_matrix(demand_matrix_day,num_days):
matrix = []
for index in range(num_days):
matrix_element = []
for day in range(num_days):
if day == index:
matrix_element = matrix_element +demand_matrix_day
else:
matrix_element = matrix_element +(list(np.zeros(len(demand_matrix_day))))
matrix.append(matrix_element)
return matrix
def kunden_indizes(ID_list, num_days):
indizes = {}
for ID in ID_list:
indizes[ID] = []
for index, key in enumerate(indizes):
for i in range(len(ID_list)*num_days):
if (i % len(ID_list)) == index:
indizes[key].append(i)
#print(indizes)
return indizes
def create_data_model(node_num):
data = {}
data["num_days"] = 5 #Anzahl Tage
###Kundenset
num_IDs = node_num
base = [0]
data["IDs"] = list(range(0, num_IDs))
#data["IDs"] = [0, 1, 2, 3, 4]
print(data["IDs"])
data["demand"] = [random.randint(1,30) for i in range(0,num_IDs)]
#data["demand"] =[0, 16, 8, 1, 7]
data["demand"][0] = 0
print("demand", data["demand"])
data["frequenz"] = [random.randint(1,5) for i in range(0,num_IDs)]
#data["frequenz"] =[0, 3, 5, 2, 1]
data["frequenz"][0] = 0
print("freq ",data["frequenz"])
summe_dem =0
for index, demand in enumerate(data["demand"]):
summe_dem += data["demand"][index] * data["frequenz"][index]
print("DEMANDSUMME: ",summe_dem)
data["koordianten"] = np.random.rand(num_IDs, 2)*1000
#data["koordianten"] = np.array([(0, 0), (4, 0), (4, 4), (0, 4), (3, 3)])*100
data["koordianten"][0] = (0,0)
#print("koord ", data["koordianten"])
data["PAT"] = {
5:
[[1, 1, 1, 1, 1]],
4:
[[0, 1, 1, 1, 1],
[1, 0, 1, 1, 1],
[1, 1, 0, 1, 1],
[1, 1, 1, 0, 1],
[1, 1, 1, 1, 0]],
3: [[0, 1, 0, 1, 1],
[1, 0, 1, 0, 1],
[1, 1, 0, 1, 0],
[0, 1, 1, 0, 1],
[1, 0, 1, 1, 0],
],
2: [[1, 0, 1, 0, 0],
[0, 1, 0, 1, 0],
[0, 0, 1, 0, 1],
[1, 0, 0, 1, 0],
[0, 1, 0, 0, 1]],
1: [[1, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 1]],
}
### Definition der Fahrezugtypen
data["vehicle_costs_type_per_km"] = [1, 0.01] #Kosten pro km pro Fahrzeugtyp
data["vehicle_costs_type_per_stop"] = [1, 1000] #Kosten pro Stop pro Fahrzeugtyp
data["vehicle_capacity_type"] = [100, 200] # Kapaität pro Fahrzeugtyp
data["num_vehicle_per_type"] = [math.ceil(summe_dem /data["vehicle_capacity_type"][0]), math.ceil(summe_dem /data["vehicle_capacity_type"][1])] # Anzahl Fahrzeuge pro Typ
data['price_per_km'] = veh_types_costs(data["vehicle_costs_type_per_km"], data["num_vehicle_per_type"], data["num_days"]) #Matrix für price_per_km je Fahrzeug ertsellen
data["price_per_stop"] = veh_types_costs(data["vehicle_costs_type_per_stop"], data["num_vehicle_per_type"], data["num_days"])
data['vehicle_capacities_matrix'] = veh_capacity_matrix(data["num_vehicle_per_type"], data["vehicle_capacity_type"], data["num_days"]) #Kapazitäten pro Fahrzeugs pro Tag
#print('vehicle_capacities_matrix')
#print(data['vehicle_capacities_matrix'])
data["num_vehicles_per_day"] = sum(data["num_vehicle_per_type"]) #Gesamtanzahl der Fahrzeuge pro Tag
data['num_vehicles'] = data["num_days"] * data["num_vehicles_per_day"]# Gesamtanzahl der Fahrzeuge in gesamten Zeitraum
###Distanzmatrix bestimmen
data["base_distance_matrix"] = dist_matrix(data["koordianten"])
data['distance_matrix'] = dublicate_nodes(data["base_distance_matrix"], data["num_days"]) # Distanzmatrix mit mehrfachen Nodes pro Kunden, je Tag ein Node
###Start und Ende festlegen
data["num_nodes"] = len(data["base_distance_matrix"]) # Anzahl Kunden
data['starts'] = depo_nodes(data["num_days"], data['num_vehicles'], data["num_nodes"]) #Deponodes (Start) für die einzelnen Fahrzeuge (Tage)
data['ends'] = depo_nodes(data["num_days"], data['num_vehicles'], data["num_nodes"]) #Deponodes (Ende) für die einzelnen Fahrzeuge (Tage)
###Demand pro Kunde
data["kunden_indizes"] = kunden_indizes(data["IDs"], data["num_days"])
data["demands_matrix"] = demand_matrix(demand_matrix_day=data["demand"], num_days=data["num_days"])
#print(data["demands_matrix"])
return data
def print_solution(data, manager, routing, solution):
"""Prints solution on console."""
total_distance = 0
total_load = 0
for vehicle_id in range(data['num_vehicles']):
if vehicle_id % data["num_vehicles_per_day"] == 0:
print(("------Tag {}------").format(int(vehicle_id/data["num_vehicles_per_day"])))
if routing.IsVehicleUsed(assignment= solution, vehicle=vehicle_id) == False:
continue
index = routing.Start(vehicle_id)
if vehicle_id >= data["num_vehicles_per_day"]:
plan_output = 'Route for vehicle {}:\n'.format(abs(vehicle_id-data["num_vehicles_per_day"]*int(vehicle_id/data["num_vehicles_per_day"])))
else:
plan_output = 'Route for vehicle {}:\n'.format(vehicle_id)
route_costs = 0
route_load = 0
while not routing.IsEnd(index):
node_index = manager.IndexToNode(index)
capacity_ID = int(vehicle_id/data["num_vehicles_per_day"])
route_load += data['demands_matrix'][capacity_ID][node_index]
plan_output += ' {0} Load({1}) -> '.format(node_index, route_load)
previous_index = index
index = solution.Value(routing.NextVar(index))
route_costs += routing.GetArcCostForVehicle(
previous_index, index, vehicle_id)
plan_output += ' {0} Load({1})\n'.format(manager.IndexToNode(index),
route_load)
plan_output += 'Costs of the route: {}€\n'.format(route_costs)
plan_output += 'Load of the route: {}\n'.format(route_load)
print(plan_output)
total_distance += route_costs
total_load += route_load
print('Total costs of all routes: {}€'.format(total_distance))
print('Total load of all routes: {}'.format(total_load))
def main(node_num):
"""Periodic CVRP problem."""
# Instantiate the data problem.
data = create_data_model(node_num)
# Create the routing index manager.
manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), data['num_vehicles'], data['starts'],
data['ends'])
# Create Routing Model.
routing = pywrapcp.RoutingModel(manager)
### Kostenfunktion je Fahrzeug festlegen ###
def create_cost_callback(dist_matrix, km_costs, stop_costs):
# Create a callback to calculate distances between cities.
def distance_callback(from_index, to_index):
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
return int(dist_matrix[from_node][to_node]) * (km_costs) + (stop_costs)
return distance_callback
for i in range(data['num_vehicles']):
cost_callback = create_cost_callback(data['distance_matrix'], data["price_per_km"][i],
data["price_per_stop"][i]) # Callbackfunktion erstellen
cost_callback_index = routing.RegisterTransitCallback(cost_callback) # registrieren
routing.SetArcCostEvaluatorOfVehicle(cost_callback_index, i) # Vehicle zuordnen
#Define Capacities for Vehicles for every Day
def create_demand_callback(demand_matrix, demand_index):
# Create a callback to calculate capacity usage.
def demand_callback(from_index):
#Returns the demand of the node.
# Convert from routing variable Index to demands NodeIndex.
from_node = manager.IndexToNode(from_index)
return demand_matrix[demand_index][from_node]
return demand_callback
for i in range(data["num_days"]): #Jedes Fahrzeug hat pro Tag eine andere Kapazität
demand_callback = create_demand_callback(data['demands_matrix'], i)
demand_callback_index = routing.RegisterUnaryTransitCallback(demand_callback)
dimension_name = 'Capacity_day_{}'.format(i)
routing.AddDimensionWithVehicleCapacity(
demand_callback_index,
0, # null capacity slack
data['vehicle_capacities_matrix'][i], # vehicle maximum capacities
True, # start cumul to zero
dimension_name)
#Drop visits that would exceed the frequency
for index, key in enumerate(data["kunden_indizes"]):
if index == 0:
continue
#routing.solver().Add(sum(routing.ActiveVar(manager.NodeToIndex(i)) for i in data["kunden_indizes"][key]) == data["frequenz"][index])
bool_array = []
for index, freq in enumerate(data["frequenz"]):
if index == 0:
continue
bool_array_part =[]
for index_pat, pat in enumerate(data["PAT"][freq]):
#print(index,freq,index_pat)
bool_name = str(index) +str(freq) + str(index_pat)
bool_array_part.append(routing.solver().BoolVar(bool_name))
bool_array.append(bool_array_part)
#print(bool_array)
for i in bool_array:
routing.solver().Add(sum(i) == 1)
node_array = []
for index, freq in enumerate(data["frequenz"]):
if index == 0:
continue
node_array_part = []
for index_pat, pat in enumerate(data["PAT"][freq]):
node_array_sub_part = []
for index_day, day_value in enumerate(pat):
if day_value == 1:
node_array_sub_part.append(data["kunden_indizes"][index][index_day])
#print(node_array_part)
node_array_part.append(node_array_sub_part)
node_array.append(node_array_part)
#print(node_array)
for index, bool in enumerate(bool_array):
for i in range(len(bool)):
#print(node_array[index][i])
#print(bool_array[index][i])
routing.solver().Add(sum(routing.ActiveVar(manager.NodeToIndex(i)) for i in node_array[index][i]) * bool_array[index][i] == bool_array[index][i] * len(node_array[index][i]))
#routing.solver().Add(routing.ActiveVar(manager.NodeToIndex(5)) == 1)
penalty = 0
for node in range(0, len(data['distance_matrix'])):
if node in data["kunden_indizes"][0]:
continue
else:
routing.AddDisjunction([manager.NodeToIndex(node)], penalty)
# Setting first solution heuristic.
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (
routing_enums_pb2.FirstSolutionStrategy.AUTOMATIC)
search_parameters.local_search_metaheuristic = (
routing_enums_pb2.LocalSearchMetaheuristic.AUTOMATIC)
#search_parameters.time_limit.FromSeconds(300)
# Solve the problem.
solution = routing.SolveWithParameters(search_parameters)
# Print solution on console.
if solution:
print_solution(data, manager, routing, solution)
print()
print("Statistics")
print(' - wall time : %f s' % (int(routing.solver().WallTime())/1000))
solvingtime = int(routing.solver().WallTime())/1000
return solvingtime
if __name__ == '__main__':
node_num_array = [10,20,30,40,50,60,70,80,90,100]
solvingtime_array = []
num_array =[]
for i in node_num_array:
for j in range(0,4):
solvingtime = main(i)
solvingtime_array.append(solvingtime)
num_array.append(i)
print(i, "-->",solvingtime)
print(solvingtime_array)
print(num_array)
df_results = pd.DataFrame(data= {"num_nodes":num_array, "solvingtime":solvingtime_array})
#encoding="latin_1", sep=";")
print(df_results)
Hi I'm trying to call a bunch of variables into a function, but the numpy.nadarray error keeps getting thrown.
Function in question :
def alpha(rotate_axis,angle):
rotate_axis = (input("What the is the axis of rotation? x1, x2 or x3 "))
angle = int(input("What is the angle of rotation in degrees?"))
#transforming deg -> rad
angle_r = radians(angle[0])
cos = np.cos(angle_r)
sin = np.sin(angle_r)
if rotate_axis == "x1":
rotation = np.array([[1,0,0],[0,cos,-sin],[0,sin,cos]])
elif rotate_axis == "x2":
rotation = np.array([[cos, 0, sin], [0, 1, 0], [-sin,0, cos]])
elif rotate_axis == "x3":
rotation = np.array([[cos, -sin, 0], [sin, cos, 0], [0, 0, 1]])
#print("Direction cosines:",rotation)
#producing alpha matrix
#decomposing rotation consines
a11 = rotation[0][0]
a12 = rotation[0][1]
a13 = rotation[0][2]
a21 = rotation[1][0]
a22 = rotation[1][1]
a23 = rotation[1][2]
a31 = rotation[2][0]
a32 = rotation[2][1]
a33 = rotation[2][2]
alpha = np.array([[ a11**2, a12**2, a13**2, 2*a12*a13, 2*a13*a11, 2*a11*a12],
[ a21**2, a22**2, a23**2, 2*a22*a23, 2*a23*a21, 2*a21*a22],
[ a31**2, a32**2, a33**2, 2*a32*a33, 2*a33*a31, 2*a31*a32],
[ a21*a31, a22*a32, a23*a33, a22*a33 + a23*a32, a21*a33 + a23*a31, a22*a31 + a21*a32],
[ a31*a11, a32*a12, a33*a13, a12*a33 + a13*a32, a13*a31 + a11*a33, a11*a32 + a12*a31],
[ a11*a21, a12*a22, a23*a33, a12*a23 + a13*a32, a13*a21 + a11*a23, a11*a22 + a12*a21],
])
return alpha
This is me calling the function (which throws an error)
alpha_110 = alpha("x3",45)
No error for me with this code and python 3.6 :
I took out the input, it's quite useless to have rotate_axis and angle as parameters if you erase the value by an input at every function beginning.
# -*-coding:Utf-8 -*
# Import des packages
import numpy as np
from math import radians
import os
def alpha(rotate_axis,angle):
#transforming deg -> rad
angle_r = radians(angle)
cos = np.cos(angle_r)
sin = np.sin(angle_r)
if rotate_axis == "x1":
rotation = np.array([[1,0,0],[0,cos,-sin],[0,sin,cos]])
elif rotate_axis == "x2":
rotation = np.array([[cos, 0, sin], [0, 1, 0], [-sin,0, cos]])
elif rotate_axis == "x3":
rotation = np.array([[cos, -sin, 0], [sin, cos, 0], [0, 0, 1]])
#print("Direction cosines:",rotation)
#producing alpha matrix
#decomposing rotation consines
a11 = rotation[0][0]
a12 = rotation[0][1]
a13 = rotation[0][2]
a21 = rotation[1][0]
a22 = rotation[1][1]
a23 = rotation[1][2]
a31 = rotation[2][0]
a32 = rotation[2][1]
a33 = rotation[2][2]
alpha = np.array([[ a11**2, a12**2, a13**2, 2*a12*a13, 2*a13*a11, 2*a11*a12],
[ a21**2, a22**2, a23**2, 2*a22*a23, 2*a23*a21, 2*a21*a22],
[ a31**2, a32**2, a33**2, 2*a32*a33, 2*a33*a31, 2*a31*a32],
[ a21*a31, a22*a32, a23*a33, a22*a33 + a23*a32, a21*a33 + a23*a31, a22*a31 + a21*a32],
[ a31*a11, a32*a12, a33*a13, a12*a33 + a13*a32, a13*a31 + a11*a33, a11*a32 + a12*a31],
[ a11*a21, a12*a22, a23*a33, a12*a23 + a13*a32, a13*a21 + a11*a23, a11*a22 + a12*a21],
])
return alpha
alpha_110 = alpha("x3",45)
print (alpha_110)
os.system("pause")