Search code examples
pythonpython-3.xscipyscipy-optimize

linear optimization using scipy failed


i need to maximize the throughput of a network using python scipy


class optimization():
    def __init__(self,nodes=nodes):
        self.nodes = nodes
        self.estimated_throughput_list=[] # list of throughputs
        for i in self.nodes:
            self.estimated_throughput_list.append(i.estimated_throughput) # adding for each node its throughput to the list
        self.d= np.ones_like(self.nodes, dtype=bool) # creating a boolean matrix having the same dimensions of the estimated_throughput_list

    def objective_function(self):
        """
        Objective function to maximize the sum of Di * xi,
        where Di is a binary variable that can take values of 0 or 1.
        x is an array of values for the variables x1, x2, ..., xn,
        and D is an array of values for the binary variables D1, D2, ..., Dn.
        """  
        return  np.dot(self.d, self.estimated_throughput_list)

    def constraint1(self):
        summation=8* 0.5 # erlang
        summation= summation+ np.dot(self.d, self.estimated_throughput_list)
        return summation
    def solution(self):
        return linprog(c=self.nodes,A_ub=self.estimated_throughput_list,b_ub=[8* 0.5],method="revised simplex")
        

i have a global list of nodes and each node containes it's estimated througput presented by estimated_throughput

the optimzation problem i am trying to solve is presented by the uploaded figure:optimzation problem

for simplicity m *h^(-1)[PDR] is replaced by (8*0.5)

in the main.py file i just call the function :

 opt=optimization()
    
 print("obj:",opt.solution())

it's my first time applying optimization in python i don't know if this is the way to solve this type of problem. if someone can guide me further in this problem that will be much appreciated.

the output was : c = np.array(c, dtype=np.float64, copy=True).squeeze() TypeError: float() argument must be a string or a real number, not 'myNode'


Solution

  • The error means what the error says. If you have some class myNode, you can't use it as an input to the scipy methods. In your case that's probably happening in c=self.nodes which has both the wrong sign and the wrong type. This works fine:

    import numpy as np
    import scipy
    from numpy.random import default_rng
    from scipy.optimize import LinearConstraint
    
    rand = default_rng(seed=0)
    n = 12
    nodes = rand.uniform(low=0.1, high=2, size=n)
    
    m = 8
    h = 2
    
    result = scipy.optimize.milp(
        c=-nodes,  # maximize dot product
        integrality=np.ones_like(nodes, dtype=bool),  # everything integral
        bounds=(0, 1),
        constraints=LinearConstraint(A=nodes, lb=-np.inf, ub=m/h),
    )
    
    print('Node throughputs:')
    print(nodes)
    print()
    print(result)
    
    Node throughputs:
    [1.31022721 0.61259476 0.1778497  0.13140251 1.64521345 1.8342356
     1.25260797 1.48604347 1.13288748 1.87663761 1.65012175 0.10520315]
    
            message: Optimization terminated successfully. (HiGHS Status 7: Optimal)
            success: True
             status: 0
                fun: -3.994173190069585
                  x: [ 0.000e+00  1.000e+00  1.000e+00  1.000e+00  0.000e+00
                       1.000e+00  0.000e+00  0.000e+00  1.000e+00  0.000e+00
                      -0.000e+00  1.000e+00]
     mip_node_count: 44
     mip_dual_bound: -3.994173190069585
            mip_gap: 0.0