Пример #1
0
def Shinohara1(retI = False):
	""" no = 12: Shinohara1

	{ y(0) = p*p*p*p*p - 10.*p*p*p*q*q + 5.*p*q*q*q*q
			- 2.*p*p*p*p + 12.*p*p*q*q - 2.*q*q*q*q
			+ 10.*p*p*p - 30.*p*q*q - 9.*p + 3.
	{ y(1) = q*q*q*q*q - 10.*p*p*q*q*q + 5.*p*p*p*p*q
			- 8.*p*p*p*q + 8.*p*q*q*q + 30.*p*p*q
			-10.*q*q*q - 9.*q
	true value = ?

	"""
	y = [0.0 for i in range(2)]
	x[0], x[1] = fd.oovars('x0', 'x1')
	p = x[0]
	q= x[1]
	y[0] = p*p*p*p*p - 10.*p*p*p*q*q + 5.*p*q*q*q*q\
			- 2.*p*p*p*p + 12.*p*p*q*q - 2.*q*q*q*q\
			+ 10.*p*p*p - 30.*p*q*q - 9.*p + 3.
	y[1] = q*q*q*q*q - 10.*p*p*q*q*q + 5.*p*p*p*p*q\
			- 8.*p*p*p*q + 8.*p*q*q*q + 30.*p*p*q\
			-10.*q*q*q - 9.*q
	if retI == True:
		return np.matrix([[interval(-5.1, 5.)], [interval(-5., 5.1)]])
	return y
Пример #2
0
def Shinohara3(retI = False):
	""" no = 14: Shinohara3

	{ y(0) = p*p*p - 2.*p*q + r + 0.75*p + 1.
	{ y(1) = p*p*q - q*q - p*r +s + 0.75*q + 0.25
	{ y(2) = p*p*r - p*s - q*r + t + 0.75*r + 0.75
	{ y(3) = p*p*s - p*t - q*s + 0.75*s
	{ y(4) = p*p*t - q*t + 0.75*t - 0.25
	true value = ?

	"""
	y = [0.0 for i in range(5)]
	x[0], x[1], x[2], x[3], x[4] = fd.oovars('x0', 'x1', 'x2', 'x3', 'x4')
	p = x[0];
	q = x[1];
	r = x[2];
	s = x[3];
	t = x[4];
	y[0] = p*p*p - 2.*p*q + r + 0.75*p + 1.
	y[1] = p*p*q - q*q - p*r +s + 0.75*q + 0.25
	y[2] = p*p*r - p*s - q*r + t + 0.75*r + 0.75
	y[3] = p*p*s - p*t - q*s + 0.75*s
	y[4] = p*p*t - q*t + 0.75*t - 0.25
	if retI == True:
		return np.matrix([[interval(-1.5, 2.)],\
						  [interval(-0.6, 3.)],\
						  [interval(-1.5, 2.5)],\
						  [interval(-0.5, 1.9)],\
						  [interval(-1., 1.)]])
	return y
Пример #3
0
    def solve(self, *args, **kw):
        if len(args) > 1:
            self.err('''
            incorrect number of arguments for solve(), 
            must be at least 1 (solver), other must be keyword arguments''')
        solver = args[0] if len(args) != 0 else kw.get('solver', self.solver)

        graph = self.graph  # must be networkx instance
        nodes = graph.nodes()
        edges = graph.edges()

        n = len(nodes)

        node2index = dict([(node, i) for i, node in enumerate(nodes)])
        index2node = dict([(i, node) for i, node in enumerate(nodes)])

        import FuncDesigner as fd, openopt
        x = fd.oovars(n, domain=bool)
        objective = fd.sum(x)
        startPoint = {x: [0] * n}

        fixedVars = {}

        includedNodes = getattr(kw, 'includedNodes', None)
        if includedNodes is None:
            includedNodes = getattr(self, 'includedNodes', ())
        for node in includedNodes:
            fixedVars[x[node2index[node]]] = 1

        excludedNodes = getattr(kw, 'excludedNodes', None)
        if excludedNodes is None:
            excludedNodes = getattr(self, 'excludedNodes', ())
        for node in excludedNodes:
            fixedVars[x[node2index[node]]] = 0

        if openopt.oosolver(solver).__name__ == 'interalg':
            constraints = [
                fd.NAND(x[node2index[i]], x[node2index[j]]) for i, j in edges
            ]
            P = openopt.GLP
        else:
            constraints = [
                x[node2index[i]] + x[node2index[j]] <= 1 for i, j in edges
            ]
            P = openopt.MILP

        p = P(objective,
              startPoint,
              constraints=constraints,
              fixedVars=fixedVars,
              goal='max')

        for key, val in kw.items():
            setattr(p, key, val)
        r = p.solve(solver, **kw)
        r.solution = [index2node[i] for i in range(n) if r.xf[x[i]] == 1]
        r.ff = len(r.solution)
        return r
Пример #4
0
    def solve(self, *args, **kw):
        if len(args) > 1:
            self.err('''
            incorrect number of arguments for solve(), 
            must be at least 1 (solver), other must be keyword arguments''')
        solver = args[0] if len(args) != 0 else kw.get('solver', self.solver)
        
        graph = self.graph # must be networkx instance
        nodes = graph.nodes()
        edges = graph.edges()
        
        n = len(nodes)
        
        node2index = dict([(node, i) for i, node in enumerate(nodes)])
        index2node = dict([(i, node) for i, node in enumerate(nodes)])
        
        import FuncDesigner as fd, openopt
        x = fd.oovars(n, domain=bool)
        objective = fd.sum(x)
        startPoint = {x:[0]*n}
        
        fixedVars = {}
       
        includedNodes = getattr(kw, 'includedNodes', None)
        if includedNodes is None:
            includedNodes = getattr(self, 'includedNodes', ())
        for node in includedNodes:
            fixedVars[x[node2index[node]]] = 1

        excludedNodes = getattr(kw, 'excludedNodes', None)
        if excludedNodes is None:
            excludedNodes = getattr(self, 'excludedNodes', ())
        for node in excludedNodes:
            fixedVars[x[node2index[node]]] = 0

        if openopt.oosolver(solver).__name__ == 'interalg':
            constraints =  [fd.NAND(x[node2index[i]], x[node2index[j]]) for i, j in edges]
            P = openopt.GLP
        else:
            constraints =  [x[node2index[i]]+x[node2index[j]] <=1 for i, j in edges]
            P = openopt.MILP
            
        p = P(objective, startPoint, constraints = constraints, fixedVars = fixedVars, goal = 'max')
        
        for key, val in kw.items():
            setattr(p, key, val)
        r = p.solve(solver, **kw)
        r.solution = [index2node[i] for i in range(n) if r.xf[x[i]] == 1]
        r.ff = len(r.solution)
        return r
Пример #5
0
def GE1(retI = False):
	""" no = 10: GE1

	{ -1/(1 + x1) + x2/(1 + x2) = 0
	{ 1/(1 + x1) - x2/(x1 + x2) = 0
	true value = ?

	"""
	y = [0.0 for i in range(2)]
	x[0], x[1] = fd.oovars('x0', 'x1')
	y[0] = -1./(1. + x[0]) + x[1]/(1. + x[1])
	y[1] = 1./(1. + x[0]) - x[1]/(x[0] + x[1])
	if retI == True:
		return np.matrix([[interval(0.01, 100.)], [interval(0.001, 100.)]])
		#return np.matrix([[interval(0.1, 10.)], [interval(0.01, 11.)]])
	return y
Пример #6
0
def sincos_function(retI = False):
	""" no = 4: function including sine and cosine

	{ sin(x1)*cos(x1) - x2 = 0
	{ x1^2 - 6*x1 + 8 - x2 = 0
	true value
	(x1, x2) = (,), (,)

	"""
	y = [0.0 for i in range(2)]
	x[0], x[1] = fd.oovars('x0', 'x1')
	y[0] = fd.sin(x[0]) * fd.cos(x[0]) - x[1]
	y[1] = x[0] * x[0] - 6 * x[0] + 8 - x[1]
	if retI == True:
		return np.matrix([[interval(-6.1, 6.)], [interval(-6., 6.)]])
	return y
Пример #7
0
def sample_function_1(retI = False):
	""" no = 1: sample function 1

	{ x1^2 - x2 = 0
	{ (1/2)*x1 - x2 = 0
	true value
	(x1, x2) = (0, 0), (0.5, 0.25)

	"""
	y = [0.0 for i in range(2)]
	x[0], x[1] = fd.oovars('x0', 'x1')
	y[0] = x[0] * x[0] - x[1]
	y[1] = 0.5 * x[0] - x[1]
	if retI == True:
		return np.matrix([[interval(-2.2, 2.1)], [interval(-1., 2.)]])
	return y
Пример #8
0
def sin_function(retI = False):
	""" no = 3: function including sin

	{ (pi/2)*sin(x1) - x2 = 0
	{ x1 - x2 = 0
	true value
	(x1, x2) = (0, 0), (1.57079633.., 1.57079633..), (-1.5709633.., -1.57079633..)

	"""
	y = [0.0 for i in range(2)]
	x[0], x[1] = fd.oovars('x0', 'x1')
	#y[0] = 1.57079633 * fd.sin(x[0]) - x[1]
	y[0] = (np.pi/2) * fd.sin(x[0]) - x[1]
	y[1] = x[0] - x[1]
	if retI == True:
		return np.matrix([[interval(-3.1, 3.)], [interval(-2., 2.)]])
	return y
Пример #9
0
def sample_function_2(retI = False):
	""" no = 2: sample function 2

	{ x1^2 - x2 = 0
	{ -x1^2 + 2*x1 - x2 = 0
	true value
	(x1, x2) = (0, 0), (1, 1)

	"""
	y = [0.0 for i in range(2)]
	x[0], x[1] = fd.oovars('x0', 'x1')
	y[0] = x[0] * x[0] - x[1]
	y[1] = -x[0] * x[0] + 2 * x[0]  - x[1]
	if retI == True:
		return np.matrix([[interval(-11., 10.)], [interval(-10., 11.)]])
		#return np.matrix([[interval(-10., 10.)], [interval(-10., 10.)]])
	return y
Пример #10
0
def Duffing(retI = False):
	""" no = 11: Duffing-equation

	{ y(0) = -x(0) + B + 0.1 * x(1) + 0.75 * (x(0)*x(0)*x(0) + x(0) *x(1) * x(1))
	{ y(1) = - x(1) + 0.1 * x(0) + 0.75 * (x(0)*x(0)*x(1) + x(1)*x(1)*x(1))
	true value = 5?

	"""
	B = 0.
	#B = 0.15
	y = [0.0 for i in range(2)]
	x[0], x[1] = fd.oovars('x0', 'x1')
	y[0] = -1.*x[0] + B + 0.1*x[1] + 0.75*(x[0]*x[0]*x[0] + x[0]*x[1]*x[1])
	y[1] = -1.*x[1] + 0.1*x[0] + 0.75*(x[0]*x[0]*x[1] + x[1]*x[1]*x[1])
	if retI == True:
		return np.matrix([[interval(-1e+8-1., 1e+8)], [interval(-1e+8, 1e+8+1.)]])
		#return np.matrix([[interval(-1e+5-1., 1e+5)], [interval(-1e+5, 1e+5+1.)]])
	return y
Пример #11
0
def Nosol(retI = False):
	""" no = 9: No-solutions

	{ x1^2 - x2 = 0
	{ x1^2 - x2 + param
	true value
	(x1, x2) = None

	"""
	#param = 0.01
	param = 0.001
	y = [0.0 for i in range(2)]
	x[0], x[1] = fd.oovars('x0', 'x1')
	y[0] = x[0]*x[0] - x[1]
	y[1] = x[0]*x[0] - x[1] + param
	if retI == True:
		return np.matrix([[interval(-1., 1.)], [interval(-1., 1.)]])
	return y
Пример #12
0
def default_function(retI = False):
	""" no = 0: default function

	{ x1^2 + x2^2 -1 = 0
	{ x1 - x2 = 0
	one true solution which sample function has is below:
	x1 = x2 = (2^(1/2))/2
	(=~ 0.70710678)

	"""
	y = [0.0 for i in range(2)]
	x[0], x[1] = fd.oovars('x0', 'x1')
	y[0] = x[0] * x[0] + x[1] * x[1] - 1
	y[1] = x[0] - x[1]
	if retI == True:
		#return np.matrix([[interval(-1.1, 1.)], [interval(-1., 1.)]])
		return np.matrix([[interval(-1., 1.)], [interval(-1., 1.)]])
	return y
Пример #13
0
def badCond(retI = False):
	""" no = 7: BadCond

	{ x1^2 - x2 = 0
	{ (1 - param) * x1^2 - x2 + param = 0
	true value
	(x1, x2) = (, ), (, )

	"""
	#param = 0.0000001
	#param = 0.01
	param = 0.001
	y = [0.0 for i in range(2)]
	x[0], x[1] = fd.oovars('x0', 'x1')
	y[0] = x[0]*x[0] - x[1]
	y[1] = (1 - param)*x[0]*x[0] - x[1] + param
	if retI == True:
		return np.matrix([[interval(-10., 10.)], [interval(-10., 10.)]])
	return y
Пример #14
0
def function_3_dim(retI = False):
	""" no = 5: function of 3-dimention

	{ x1 + x2 + x3 = 6
	{ 3*x1 + 2*x2 -2*x3 = 1
	{ 2*x1 - x2 + 3*x3 = 9
	true value
	(x1, x2, x3) = (1, 2, 3)

	"""
	y = [0.0 for i in range(3)]
	x[0], x[1], x[2] = fd.oovars('x0', 'x1', 'x2')
	y[0] = x[0] + x[1] + x[2] - 6
	y[1] = 3*x[0] + 2*x[1] - 2*x[2] - 1
	y[2] = 2*x[0] - x[1] + 3*x[2] - 9
	if retI == True:
		#return np.matrix([[interval(-1.1, 5.)], [interval(-1., 5.)], [interval(-1., 5.1)]])
		return np.matrix([[interval(-50.1, 50.)], [interval(-50., 50.)], [interval(-50., 50.1)]])
	return y
Пример #15
0
def Burden(retI = False):
	""" no = 8: Burden

	{ x1*(4 - 0.0003*x1 - 0.0004*x2) = 0
	{ x2*(2 - 0.0002*x1 - 0.0001*x2) = 0
	true value
	(x1, x2) = ?

	"""
	#param = 0.0001
	param = 0.1
	y = [0.0 for i in range(2)]
	x[0], x[1] = fd.oovars('x0', 'x1')
	y[0] = x[0]*(4. - 3.*param*x[0] - 4.*param*x[1])
	y[1] = x[1]*(2. - 2.*param*x[0] - 1.*param*x[1])
	if retI == True:
		#return np.matrix([[interval(0., pow(10., 10))], [interval(0., pow(10., 10))]])
		return np.matrix([[interval(-1., pow(10., 10))], [interval(0., pow(10., 10)+1)]])
	return y
Пример #16
0
def function_3_dim_2(retI = False):
	""" no = 6: function of 3-dimention

	{ x1*x2 - 9 = 0
	{ x2*x3 - 6 = 0
	{ x3*x1 - 6 = 0
	true value
	(x1, x2, x3) = (3, 3, 2), (-3, -3, -2)

	"""
	y = [0.0 for i in range(3)]
	x[0], x[1], x[2] = fd.oovars('x0', 'x1', 'x2')
	y[0] = x[0] * x[1] - 9
	y[1] = x[1] * x[2] - 6
	y[2] = x[2] * x[0] - 6
	if retI == True:
		#return np.matrix([[interval(-6.1, 5.)], [interval(-5., 6.)], [interval(-6., 7.1)]])
		#return np.matrix([[interval(-10.1, 15.)], [interval(-15., 20.)], [interval(-16., 10.1)]])
		return np.matrix([[interval(-100, 100.)], [interval(-100., 100.)], [interval(-100., 100.)]])
	return y
Пример #17
0
def automaticdiffertest():
    
    #from FuncDesigner import *

    a, b, c = fd.oovars('a', 'b', 'c')

    f1, f2 = fd.sin(a) + fd.cos(b) - fd.log2(c) + fd.sqrt(b), fd.sum(c) + c * fd.cosh(b) / fd.arctan(a) + c[0] * c[1] + c[-1] / (a * c.size)

    f3 = f1*f2 + 2*a + fd.sin(b) * (1+2*c.size + 3*f2.size)

    f = 2*a*b*c + f1*f2 + f3 + fd.dot(a+c, b+c)

    point = {a:1, b:2, c:[3, 4, 5]} # however, you'd better use numpy arrays instead of Python lists

    print(f(point))

    print(f.D(point))

    print(f.D(point, a))

    print(f.D(point, [b]))

    print(f.D(point, fixedVars = [a, c]))
Пример #18
0
def Shinohara2(retI = False):
	""" no = 13: Shinohara2

	{ y(0) = p*p*p*p*p - 10.*p*p*p*q*q + 5.*p*q*q*q*q
		- 3.*p*p*p*p + 18.*p*p*q*q - 3.*q*q*q*q
		- 2.*p*p*p + 6.*p*q*q + 3.*p*p*q - q*q*q
		+ 12.*p*p - 12.*q*q - 10.*p*q - 8.*p + 8.*q;
	{ y(1) = 5.*p*p*p*p*q - 10.*p*p*q*q*q + q*q*q*q*q
		- 12.*p*p*p*q + 12.*p*q*q*q - p*p*p + 3.*p*q*q
		- 6.*p*p*q + 2.*q*q*q + 5.*p*p - 5.*q*q
		+ 24.*p*q - 8.*p - 8.*q + 4.;
	true value = ?
	output:
	0 = [[[-2.09868411349,-2.09868411345]]
	    [[-0.455089860584,-0.455089860541]]]
	1 = [[[0.999999999995,1.0]]
	    [[-4.51311746098e-12,4.51285733701e-12]]]
	2 = [[[0.0986841134678,0.0986841134678]]
	    [[0.455089860562,0.455089860562]]]

	"""
	y = [0.0 for i in range(2)]
	x[0], x[1] = fd.oovars('x0', 'x1')
	p = x[0]
	q= x[1]
	y[0] = p*p*p*p*p - 10.*p*p*p*q*q + 5.*p*q*q*q*q\
		- 3.*p*p*p*p + 18.*p*p*q*q - 3.*q*q*q*q\
		- 2.*p*p*p + 6.*p*q*q + 3.*p*p*q - q*q*q\
		+ 12.*p*p - 12.*q*q - 10.*p*q - 8.*p + 8.*q
	y[1] = 5.*p*p*p*p*q - 10.*p*p*q*q*q + q*q*q*q*q\
		- 12.*p*p*p*q + 12.*p*q*q*q - p*p*p + 3.*p*q*q\
		- 6.*p*p*q + 2.*q*q*q + 5.*p*p - 5.*q*q\
		+ 24.*p*q - 8.*p - 8.*q + 4.
	if retI == True:
		return np.matrix([[interval(-3.1, 3.)], [interval(-3., 3.1)]])
	return y
Пример #19
0
def set_routine(p,  *args, **kw):
    if len(args) > 1:
        p.err('''
        incorrect number of arguments for solve(), 
        must be at least 1 (solver), other must be keyword arguments''')
    solver = args[0] if len(args) != 0 else kw.get('solver', p.solver)
    
    import FuncDesigner as fd, openopt
    is_interalg = openopt.oosolver(solver).__name__ == 'interalg'
    
    graph = p.graph # must be networkx instance
    nodes = graph.nodes()
    edges = graph.edges()
    
    n = len(nodes)
    
    node2index = dict((node, i) for i, node in enumerate(nodes))
    index2node = dict((i, node) for i, node in enumerate(nodes))
    
    
    x = fd.oovars(n, domain=bool)
    objective = fd.sum(x)
    startPoint = {x:[0]*n}
    
    fixedVars = {}
   
    includedNodes = getattr(kw, 'includedNodes', None)
    if includedNodes is None:
        includedNodes = getattr(p, 'includedNodes', ())
    for node in includedNodes:
        fixedVars[x[node2index[node]]] = 1

    excludedNodes = getattr(kw, 'excludedNodes', None)
    if excludedNodes is None:
        excludedNodes = getattr(p, 'excludedNodes', ())
    for node in excludedNodes:
        fixedVars[x[node2index[node]]] = 0

    if p.probType == 'DSP':
        constraints = []
        engine = fd.OR if is_interalg else lambda List: fd.sum(List) >= 1
        Engine = lambda d, n: engine([x[node2index[k]] for k in (list(d.keys())+[n])]) 
        for node in nodes:
            adjacent_nodes_dict = graph[node]
            if len(adjacent_nodes_dict) == 0:
                fixedVars[x[node2index[node]]] = 1
                continue
            constraints.append(Engine(adjacent_nodes_dict, node))
    else:
        constraints = \
        [fd.NAND(x[node2index[i]], x[node2index[j]]) for i, j in edges] \
        if is_interalg else \
        [x[node2index[i]]+x[node2index[j]] <=1 for i, j in edges]
    
    P = openopt.GLP if is_interalg else openopt.MILP
    goal = 'min' if p.probType == 'DSP' else 'max' 
    p = P(objective, startPoint, constraints = constraints, fixedVars = fixedVars, goal = goal)
    
    for key, val in kw.items():
        setattr(p, key, val)
    r = p.solve(solver, **kw)
    r.solution = [index2node[i] for i in range(n) if r.xf[x[i]] == 1]
    r.ff = len(r.solution)
    return r
Пример #20
0
	h = []
	for i in range(n):
		if i == j:
			h.append(12+n/(i+1.0))
		elif i == j + 1:
			h.append(0)
		elif j == i + 2:
			h.append(0)
		else:
			h.append(15/((i+1)+0.1*(j+1)))
	H.append(h)
			
#print H
#H = [[15,0,4.83871],
#     [12.5,13.5,0],
#	 	 [0,6.52174,13]]
#print H
x = fd.oovars(n)
f = fd.dot(fd.dot(x, H), x)
startPoint = {x: np.zeros(n)}
constraints = []
constraints.append(x > np.zeros(n))
constraints.append(fd.sum(x) == 1)
p = QP(f, startPoint, constraints=constraints)
r = p.solve("qlcp")
x_opt = r(x)
print(math.sqrt(r.ff))

# problem
# http://abel.ee.ucla.edu/cvxopt/examples/tutorial/qp.html
Пример #21
0
    def solve(self, *args, **kw):
        if len(args) > 1:
            self.err('''
            incorrect number of arguments for solve(), 
            must be at least 1 (solver), other must be keyword arguments''')
        if self.start is None and not self.returnToStart:
            self.err('for returnToStart=False mode you should provide start, other cases are unimplemented yet')
        solver = args[0] if len(args) != 0 else kw.get('solver', self.solver)
        KW = self.__init_kwargs.copy()
        KW.update(kw)
        
        objective = KW.get('objective', self.objective)
        if isinstance(objective, (list, tuple, set)):
            nCriteria = len(self.objective)
            if 3 * nCriteria != np.asarray(self.objective).size:
                objective = [(objective[3*i], objective[3*i+1], objective[3*i+2]) for i in range(int(round(np.asarray(self.objective).size / 3)))]
            if len(objective) == 1:
                KW['fTol'], KW['goal'] = objective[0][1:]
        else:
            objective = [(self.objective, KW.get('fTol', getattr(self, 'fTol')), KW.get('goal', getattr(self, 'goal')))]

        nCriteria = len(objective)
        isMOP = nCriteria > 1
        mainCr = objective[0][0]
         
        import FuncDesigner as fd, openopt as oo 
        solverName = solver if type(solver) == str else solver.__name__
        is_interalg = solverName == 'interalg'
        is_glp = solverName == 'sa'
        if is_glp:
            assert nCriteria == 1, 'you cannot solve multiobjective tsp by the solver'
            
        is_interalg_raw_mode = is_interalg and KW.get('dataHandling', oo.oosolver(solver).dataHandling) in ('auto','raw')
        KW.pop('objective', None)
        P = oo.MOP if nCriteria > 1 else oo.GLP if is_interalg else oo.MILP if not is_glp else oo.GLP

        import networkx as nx
        graph = self.graph # must be networkx Graph instance
        
        init_graph_is_directed = graph.is_directed()
        init_graph_is_multigraph = graph.is_multigraph()
        if not init_graph_is_multigraph or not init_graph_is_directed:
            graph = nx.MultiDiGraph(graph) #if init_graph_is_directed else nx.MultiGraph(graph)
        
        nodes = graph.nodes()
        edges = graph.edges()
        n = len(nodes)
        m = len(edges)

        node2index = dict([(node, i) for i, node in enumerate(nodes)])
        
        # TODO: implement MOP with interalg_gdp mode (requires interpolation interval analysis for non-monotone funcs)
        interalg_gdp = 1
        if not is_interalg:# or isMOP:
            # !!!!!!!!!!!!! TODO: add handling of MOP with interalg_gdp?
            interalg_gdp = 0 
            
        if interalg_gdp:
            x = []
            edge_ind2x_ind_val = {}
        else:
            pass
            #x = fd.oovars(m, domain=bool)

        #cr_values = dict([(obj[0], []) for obj in objective])
        cr_values = {}
        constraints = []
        EdgesDescriptors, EdgesCoords = [], []
        # mb rework it by successors etc?
        
        Funcs = {}
        Cons = KW.pop('constraints', [])
        if type(Cons) not in (list, tuple):
            Cons = [Cons]
        usedValues = getUsedValues(Cons)
        usedValues.update(getUsedValues([obj[0] for obj in objective]))
        
        MainCr = mainCr if type(mainCr) in (str, np.str_) else list(usedValues)[0]
        
        isMainCrMin = objective[0][2] in ('min', 'minimum')
        node_out_edges_num = []
        for node in nodes:
            Edges = graph[node]
            node_out_edges_num.append(len(Edges))
            out_nodes = Edges.keys()
            if len(out_nodes) == 0:
                self.err('input graph has node %s that does not lead to any other node; solution is impossible' % node)            
            
            if init_graph_is_multigraph and not isMOP and type(mainCr) in [str, np.str_]:
                W = {}
                for out_node in out_nodes:
                    ww = list(Edges[out_node].values())
                    for w in ww:
                        tmp = W.get(out_node, None)
                        if tmp is None:
                            W[out_node] = w
                            continue
                        th = tmp[mainCr]
                        w_main_cr_val = w[mainCr]
                        if isMainCrMin  == (th > w_main_cr_val):
                            W[out_node] = w
                Out_nodes, W = np.array(list(W.keys())), np.array(list(W.values()))
            else:
                W = np.hstack([list(Edges[out_node].values()) for out_node in out_nodes])
                Out_nodes = np.hstack([[out_node] * len(Edges[out_node]) for out_node in out_nodes])
            
            if interalg_gdp:
                rr = np.array([w[MainCr] for w in W])
                if isMainCrMin:
                    rr = -rr
                elif objective[0][2] not in ('max', 'maximum'):
                    self.err('unimplemented for fixed value goal in TSP yet, only min/max is possible for now')

                ind = rr.argsort()
                W = W[ind]
                Out_nodes = Out_nodes[ind]

            lc = 0
            for i, w in enumerate(W):
                if interalg_gdp:
                    edge_ind2x_ind_val[len(EdgesCoords)] = (len(x), lc)
                lc += 1
                EdgesCoords.append((node, Out_nodes[i]))
                EdgesDescriptors.append(w)

                for key, val in w.items():
                    # for undirected:
                    #if node2index[key] < node2index[out_node]: continue
                    Val = val if self.returnToStart or node != self.start else 0
                    if key in cr_values:
                        cr_values[key].append(Val)
                    else:
                        cr_values[key] = [Val]
            if interalg_gdp:
                x.append(fd.oovar(domain = np.arange(lc)))            
        
        m = len(EdgesCoords) # new value
        
        if is_glp:
            if type(mainCr) not in (str, np.str_):
                self.err('for the solver "sa" only text name objectives are implemented (e.g. "time", "price")')
            if init_graph_is_multigraph:
                self.err('the solver "sa" cannot handle multigraphs yet')
            if len(Cons) != 0:
                self.err('the solver "sa" cannot handle constrained TSP yet')
            M = np.empty((n, n))
            M.fill(np.nan)
            Cr_values = np.array(cr_values[mainCr])
            isMax = objective[0][-1] in ('max', 'maximum')
            if isMax:
                Cr_values = -Cr_values
            for i, w in enumerate(EdgesDescriptors):
                node_in, node_out = EdgesCoords[i]
                M[node_in, node_out] = Cr_values[i]
            S = np.abs(Cr_values).sum() + 1.0
            
            # TODO: check it
            M[np.isnan(M)] = S
            
            prob = P(lambda x: 0, np.zeros(n), iprint = 1)
            prob.f = lambda x: np.nan if not hasattr(prob, 'ff') else (prob.ff if isMax else -prob.ff)
            prob.M = dict([((i, j), M[i, j]) for i in range(n) for j in range(n) if i != j])
            r = prob.solve(solver, **KW)
            xf = [nodes[j] for j in np.array(r.xf, int)]
            r.nodes = xf#.tolist() 
            if self.start is not None:
                j = r.nodes.index(self.start)
                r.nodes = r.nodes[j:] + r.nodes[:j]
            if self.returnToStart:
                r.nodes += [r.nodes[0]]
            r.edges = [(r.nodes[i], r.nodes[i+1]) for i in range(n-1)] 
            r.Edges = [(r.nodes[i], r.nodes[i+1], graph[r.nodes[i]][r.nodes[i+1]][0]) for i in range(n-1)] 
            if self.returnToStart:
                r.edges.append((r.nodes[-2], r.nodes[0]))
                print(r.nodes[-1], r.nodes[0], type(r.nodes[-1]), type(r.nodes[0]), graph[2])
                r.Edges.append((r.nodes[-2], r.nodes[0], graph[r.nodes[-2]][r.nodes[0]][0]))
            #r.xf = r.xk = r.nodes
            # TODO: Edges
            return r
            
        
        #TODO: fix ooarray lb/ub
        #u = np.array([1] + [fd.oovar(lb=2, ub=n) for i in range(n-1)])
        u = fd.hstack((1, fd.oovars(n-1, lb=2, ub=n)))
        for i in range(1, u.size):
            u[i]('u' + str(i))
            
        
        if is_interalg_raw_mode:
            for i in range(n-1):
                u[1+i].domain = np.arange(2, n+1)
        
        if interalg_gdp: 
            assert len(x) == n
            x = fd.ooarray(x)
            
            # TODO: remove it when proper enum implementation in FD engine will be done
            for i in range(n):
                x[i]._init_domain = x[i].domain
                constraints.append(x[i]-x[i]._init_domain[-1] <= 0)
                x[i].domain = np.arange(int(2 ** np.ceil(np.log2(node_out_edges_num[i]))))
#            for i in range(n-1):
#                u[1+i]._init_domain = u[1+i].domain
#                constraints.append(u[1+i]-u[1+i]._init_domain[-1] <= 0)
#                u[1+i].domain = np.arange(u[1+i]._init_domain[0], u[1+i]._init_domain[0]+int(2 ** np.ceil(np.log2(u[1+i]._init_domain[-1]-u[1+i]._init_domain[0]+1))))
#                u[1+i].ub = u[1+i].domain[-1]

        else:
            x = fd.oovars(m, domain=bool) # new m value
        for i in range(x.size):
            x[i]('x'+str(i))
            
            
#        if init_graph_is_directed:
        dictFrom = dict([(node, []) for node in nodes])
        dictTo = dict([(node, []) for node in nodes])
        for i, edge in enumerate(EdgesCoords):
            From, To = edge
            dictFrom[From].append(i)
            dictTo[To].append(i)
        
        
        engine = fd.XOR
        
        # number of outcoming edges = 1
        if not interalg_gdp:
            for node, edges_inds in dictFrom.items():
                # !!!!!!!!!! TODO for interalg_raw_mode: and if all edges have sign similar to goal
                if 1 and is_interalg_raw_mode:
                    c = engine([x[j] for j in edges_inds])
                else:
                    nEdges = fd.sum([x[j] for j in edges_inds]) 
                    c =  nEdges >= 1 if self.allowRevisit else nEdges == 1
                constraints.append(c)

        # number of incoming edges = 1
        for node, edges_inds in dictTo.items():
            if len(edges_inds) == 0:
                self.err('input graph has node %s that has no edge from any other node; solution is impossible' % node)
            
            if interalg_gdp:
                x_inds, x_vals = [], []
                for elem in edges_inds:
                    x_ind, x_val = edge_ind2x_ind_val[elem]
                    x_inds.append(x_ind)
                    x_vals.append(x_val)
                c = engine([(x[x_ind] == x_val)(tol = 0.5) for x_ind, x_val in zip(x_inds, x_vals)])
            else:
                if 1 and is_interalg_raw_mode and engine == fd.XOR:
                    c = engine([x[j] for j in edges_inds])
                else:            
                    nEdges = fd.sum([x[j] for j in edges_inds]) 
                    c =  nEdges >= 1 if self.allowRevisit else nEdges == 1
            constraints.append(c)
        
        # MTZ
        for i, (I, J) in enumerate(EdgesCoords):
            ii, jj = node2index[I], node2index[J]
            if ii != 0 and jj != 0:
                if interalg_gdp:
                    x_ind, x_val = edge_ind2x_ind_val[i]
                    c = fd.ifThen((x[x_ind] == x_val)(tol=0.5), u[ii] - u[jj]  <= - 1.0)
                elif is_interalg_raw_mode:
                    c = fd.ifThen(x[i], u[ii] - u[jj]  <= - 1.0)#u[jj] - u[ii]  >= 1)
                else:
                    c = u[ii] - u[jj] + 1 <= (n-1) * (1-x[i])
                constraints.append(c)
        
        # handling objective(s)
        FF = []
        
        for optCrName in usedValues:
            
            tmp = cr_values.get(optCrName, [])

            if len(tmp) == 0:
                self.err('seems like graph edgs have no attribute "%s" to perform optimization on it' % optCrName)
            elif len(tmp) != m:
                self.err('for optimization creterion "%s" at least one edge has no this attribute' % optCrName)
            if interalg_gdp:
                F = []
                lc = 0
                for X in x:
                    domain = X._init_domain
                    vals = [tmp[i] for i in range(lc, lc + domain.size)]
                    lc += domain.size
                    #F = sum(x)
                    #F.append(fd.interpolator(domain, vals, k=1, s=0.00000001)(X))
                    F.append(fd.interpolator(domain, vals, k=1)(X))
                    #print(domain, vals)
                F = fd.sum(F)
            else:
                F = fd.sum(x*tmp)
            Funcs[optCrName] = F
        
        for obj in objective:
            FF.append((Funcs[obj[0]] if type(obj[0]) in (str, np.str_) else obj[0](Funcs), obj[1], obj[2]))

        for c in Cons:
            tmp = c(Funcs)
            if type(tmp) in (list, tuple, set):
                constraints += list(tmp)
            else:
                constraints.append(tmp)
        
        startPoint = {x:[0]*(m if not interalg_gdp else n)}
        startPoint.update(dict([(U, i+2) for i, U in enumerate(u[1:])]))

        p = P(FF if isMOP else FF[0][0], startPoint, constraints = constraints)#, fixedVars = fixedVars)
        for param in ('start', 'returnToStart'):
            KW.pop(param, None)
        r = p.solve(solver, **KW)

        if P != oo.MOP:
            r.ff = p.ff
            if interalg_gdp:
                x_ind_val2edge_ind = dict([(elem[1], elem[0]) for elem in edge_ind2x_ind_val.items()])
                SolutionEdges = [(EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i]) for i in [x_ind_val2edge_ind[(ind, x[ind](r))] for ind in range(n)]]
            else:
                SolutionEdges = [(EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i]) for i in range(m) if r.xf[x[i]] == 1]
            if len(SolutionEdges) == 0: 
                r.nodes = r.edges = r.Edges = []
                return r
                
            S = dict([(elem[0], elem) for elem in SolutionEdges])
            
            SE = [SolutionEdges[0]]
            for i in range(len(SolutionEdges)-1):
                SE.append(S[SE[-1][1]])
            SolutionEdgesCoords = [(elem[0], elem[1]) for elem in SE]

            nodes = [edge[1] for edge in SolutionEdgesCoords]
            if self.start is not None:
                shift_ind = nodes.index(self.start)
                nodes = nodes[shift_ind:] + nodes[:shift_ind]
            
            if self.returnToStart:
                nodes.append(nodes[0])

            edges = SolutionEdgesCoords[1:] + [SolutionEdgesCoords[0]]
            Edges = SE[1:] + [SE[0]]
            if self.start is not None:
                edges, Edges = edges[shift_ind:] + edges[:shift_ind], Edges[shift_ind:] + Edges[:shift_ind]
            if not self.returnToStart:
                edges, Edges = edges[:-1], Edges[:-1]
            r.nodes, r.edges, r.Edges = nodes, edges, Edges
        else:
            r.solution = 'for MOP see r.solutions instead of r.solution'
            tmp_c, tmp_v = r.solutions.coords, r.solutions.values
#            if interalg_gdp:
#                x_ind_val2edge_ind = dict([(elem[1], elem[0]) for elem in edge_ind2x_ind_val.items()])
#                SolutionEdges = [(EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i]) for i in [x_ind_val2edge_ind[(ind, x[ind](r))] for ind in range(n)]]
#            else:
#                SolutionEdges = [(EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i]) for i in range(m) if r.xf[x[i]] == 1]
            if interalg_gdp: # default for MOP
                x_ind_val2edge_ind = dict([(elem[1], elem[0]) for elem in edge_ind2x_ind_val.items()])
                r.solutions = MOPsolutions([[(EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i]) for i in [x_ind_val2edge_ind[(ind, x[ind](Point))] for ind in range(n)]] for Point in r.solutions])
            else:# non-default
                r.solutions = MOPsolutions([[(EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i]) for i in range(m) if Point[x[i]] == 1] for Point in r.solutions])
                
            r.solutions.values = tmp_v
        return r
Пример #22
0
    def solve(self, *args, **kw):
        import FuncDesigner as fd, openopt as oo

        if len(args) > 1:
            self.err('''
            incorrect number of arguments for solve(), 
            must be at least 1 (solver), other must be keyword arguments''')
        solver = args[0] if len(args) != 0 else kw.get('solver', self.solver)
        KW = self.__init_kwargs.copy()
        KW.update(kw)
        items = self.items
        n = len(items)
        objective = KW.get('objective', self.objective)
        if isinstance(objective, (list, tuple, set)):
            nCriteria = len(self.objective)
            if 3 * nCriteria != np.asarray(self.objective).size:
                objective = [
                    (objective[3 * i], objective[3 * i + 1],
                     objective[3 * i + 2]) for i in range(
                         int(round(np.asarray(self.objective).size / 3)))
                ]
            if len(objective) == 1:
                KW['fTol'], KW['goal'] = objective[0][1:]
        else:
            objective = [(self.objective, KW.get('fTol', getattr(self,
                                                                 'fTol')),
                          KW.get('goal', getattr(self, 'goal')))]

        nCriteria = len(objective)
        isMOP = nCriteria > 1
        #mainCr = objective[0][0]

        solverName = solver if type(solver) == str else solver.__name__
        is_interalg = solverName == 'interalg'
        is_glp = False  #solverName == 'sa'
        if is_glp:
            assert nCriteria == 1, 'you cannot solve multiobjective KSP by the solver'

        #is_interalg_raw_mode = is_interalg and KW.get('dataHandling', oo.oosolver(solver).dataHandling) in ('auto','raw')
        KW.pop('objective', None)
        P = oo.MOP if nCriteria > 1 else oo.GLP if is_interalg else oo.MILP if not is_glp else oo.GLP

        x = fd.oovars(n, domain=bool)
        requireCount = False
        for i, obj in enumerate(items):
            if 'n' in obj:
                x[i].domain = np.arange(obj['n'] + 1) if is_interalg else int
                x[i].ub = obj['n']
                x[i].lb = 0
                requireCount = True

        #cr_values = dict([(obj[0], []) for obj in objective])

        constraints = []

        Funcs = {}
        Cons = KW.pop('constraints', [])
        if type(Cons) not in (list, tuple):
            Cons = [Cons]
        usedValues = getUsedValues(Cons)
        usedValues.update(getUsedValues([obj[0] for obj in objective]))
        cr_values = {}
        for val in usedValues:
            if val == 'nItems':
                cr_values[val] = 1
            else:
                cr_values[val] = [obj[val] for obj in items]


#        MainCr = mainCr if type(mainCr) in (str, np.str_) else list(usedValues)[0]
#
#        isMainCrMin = objective[0][2] in ('min', 'minimum')

# handling objective(s)
        FF = []

        for optCrName in usedValues:
            F = fd.sum(x * cr_values[optCrName])
            Funcs[optCrName] = F

        for obj in objective:
            FF.append((Funcs[obj[0]](obj[0]) if type(obj[0]) in (str, np.str_)
                       else obj[0](Funcs), obj[1], obj[2]))

        for c in Cons:
            tmp = c(Funcs)
            if type(tmp) in (list, tuple, set):
                constraints += list(tmp)
            else:
                constraints.append(tmp)

        startPoint = {x: [0] * n}

        p = P(FF if isMOP else FF[0][0], startPoint,
              constraints=constraints)  #, fixedVars = fixedVars)
        if not isMOP:
            p.goal = self.goal
        r = p.solve(solver, **KW)

        if P != oo.MOP:
            r.ff = p.ff

        if isMOP:
            #assert not requireCount, 'MOP with nItem > 1 is unimplemented yet'
            r.solution = 'for MOP see r.solutions instead of r.solution'
            #tmp_c, tmp_v = r.solutions.coords, r.solutions.values
            if len(r.solutions):
                S = []
                for s in r.solutions:
                    tmp = [((i, int(s[x[i]])) if requireCount else i)
                           for i in range(n) if s[x[i]] >= 1]
                    if 'name' in items[0]:
                        tmp = [
                            (items[i]['name'], k) for i, k in tmp
                        ] if requireCount else [items[i]['name'] for i in tmp]
                    S.append(dict(tmp) if requireCount else tmp)
                Vals = dict([(ff[0].name, r.solutions.values[:, i])
                             for i, ff in enumerate(FF)])

                Dicts = [s.copy() for s in S]
                for v in usedValues:
                    if v != 'nItems':
                        for i, d in enumerate(Dicts):
                            d[v] = Vals[v][i]
                r.solutions = MOPsolutions(Dicts)
                r.solutions.coords = S
                r.solutions.values = Vals
        else:
            tmp = [((i, int(r.xf[x[i]])) if requireCount else i)
                   for i in range(n) if r.xf[x[i]] >= 1]
            if 'name' in items[0]:
                tmp = [(items[i]['name'], k) for i, k in tmp
                       ] if requireCount else [items[i]['name'] for i in tmp]
            r.xf = dict(tmp) if requireCount else tmp
        return r
Пример #23
0
    def solve(self, *args, **kw):
        if len(args) > 1:
            self.err('''
            incorrect number of arguments for solve(), 
            must be at least 1 (solver), other must be keyword arguments''')
        if self.start is None and not self.returnToStart:
            self.err(
                'for returnToStart=False mode you should provide start, other cases are unimplemented yet'
            )
        solver = args[0] if len(args) != 0 else kw.get('solver', self.solver)
        KW = self.__init_kwargs.copy()
        KW.update(kw)

        objective = KW.get('objective', self.objective)
        if isinstance(objective, (list, tuple, set)):
            nCriteria = len(self.objective)
            if 3 * nCriteria != np.asarray(self.objective).size:
                objective = [
                    (objective[3 * i], objective[3 * i + 1],
                     objective[3 * i + 2]) for i in range(
                         int(round(np.asarray(self.objective).size / 3)))
                ]
            if len(objective) == 1:
                KW['fTol'], KW['goal'] = objective[0][1:]
        else:
            objective = [(self.objective, KW.get('fTol', getattr(self,
                                                                 'fTol')),
                          KW.get('goal', getattr(self, 'goal')))]

        nCriteria = len(objective)
        isMOP = nCriteria > 1
        mainCr = objective[0][0]

        import FuncDesigner as fd, openopt as oo
        solverName = solver if type(solver) == str else solver.__name__
        is_interalg = solverName == 'interalg'
        is_glp = solverName == 'sa'
        if is_glp:
            assert nCriteria == 1, 'you cannot solve multiobjective tsp by the solver'

        is_interalg_raw_mode = is_interalg and KW.get(
            'dataHandling',
            oo.oosolver(solver).dataHandling) in ('auto', 'raw')
        KW.pop('objective', None)
        P = oo.MOP if nCriteria > 1 else oo.GLP if is_interalg else oo.MILP if not is_glp else oo.GLP

        import networkx as nx
        graph = self.graph  # must be networkx Graph instance

        init_graph_is_directed = graph.is_directed()
        init_graph_is_multigraph = graph.is_multigraph()
        if not init_graph_is_multigraph or not init_graph_is_directed:
            graph = nx.MultiDiGraph(
                graph)  #if init_graph_is_directed else nx.MultiGraph(graph)

        nodes = graph.nodes()
        edges = graph.edges()
        n = len(nodes)
        m = len(edges)

        node2index = dict([(node, i) for i, node in enumerate(nodes)])

        # TODO: implement MOP with interalg_gdp mode (requires interpolation interval analysis for non-monotone funcs)
        interalg_gdp = 1
        if not is_interalg:  # or isMOP:
            # !!!!!!!!!!!!! TODO: add handling of MOP with interalg_gdp?
            interalg_gdp = 0

        if interalg_gdp:
            x = []
            edge_ind2x_ind_val = {}
        else:
            pass
            #x = fd.oovars(m, domain=bool)

        #cr_values = dict([(obj[0], []) for obj in objective])
        cr_values = {}
        constraints = []
        EdgesDescriptors, EdgesCoords = [], []
        # mb rework it by successors etc?

        Funcs = {}
        Cons = KW.pop('constraints', [])
        if type(Cons) not in (list, tuple):
            Cons = [Cons]
        usedValues = getUsedValues(Cons)
        usedValues.update(getUsedValues([obj[0] for obj in objective]))

        MainCr = mainCr if type(mainCr) in (str,
                                            np.str_) else list(usedValues)[0]

        isMainCrMin = objective[0][2] in ('min', 'minimum')
        node_out_edges_num = []
        for node in nodes:
            Edges = graph[node]
            node_out_edges_num.append(len(Edges))
            out_nodes = Edges.keys()
            if len(out_nodes) == 0:
                self.err(
                    'input graph has node %s that does not lead to any other node; solution is impossible'
                    % node)

            if init_graph_is_multigraph and not isMOP and type(mainCr) in [
                    str, np.str_
            ]:
                W = {}
                for out_node in out_nodes:
                    ww = list(Edges[out_node].values())
                    for w in ww:
                        tmp = W.get(out_node, None)
                        if tmp is None:
                            W[out_node] = w
                            continue
                        th = tmp[mainCr]
                        w_main_cr_val = w[mainCr]
                        if isMainCrMin == (th > w_main_cr_val):
                            W[out_node] = w
                Out_nodes, W = np.array(list(W.keys())), np.array(
                    list(W.values()))
            else:
                W = np.hstack(
                    [list(Edges[out_node].values()) for out_node in out_nodes])
                Out_nodes = np.hstack([[out_node] * len(Edges[out_node])
                                       for out_node in out_nodes])

            if interalg_gdp:
                rr = np.array([w[MainCr] for w in W])
                if isMainCrMin:
                    rr = -rr
                elif objective[0][2] not in ('max', 'maximum'):
                    self.err(
                        'unimplemented for fixed value goal in TSP yet, only min/max is possible for now'
                    )

                ind = rr.argsort()
                W = W[ind]
                Out_nodes = Out_nodes[ind]

            lc = 0
            for i, w in enumerate(W):
                if interalg_gdp:
                    edge_ind2x_ind_val[len(EdgesCoords)] = (len(x), lc)
                lc += 1
                EdgesCoords.append((node, Out_nodes[i]))
                EdgesDescriptors.append(w)

                for key, val in w.items():
                    # for undirected:
                    #if node2index[key] < node2index[out_node]: continue
                    Val = val if self.returnToStart or node != self.start else 0
                    if key in cr_values:
                        cr_values[key].append(Val)
                    else:
                        cr_values[key] = [Val]
            if interalg_gdp:
                x.append(fd.oovar(domain=np.arange(lc)))

        m = len(EdgesCoords)  # new value

        if is_glp:
            if type(mainCr) not in (str, np.str_):
                self.err(
                    'for the solver "sa" only text name objectives are implemented (e.g. "time", "price")'
                )
            if init_graph_is_multigraph:
                self.err('the solver "sa" cannot handle multigraphs yet')
            if len(Cons) != 0:
                self.err('the solver "sa" cannot handle constrained TSP yet')
            M = np.empty((n, n))
            M.fill(np.nan)
            Cr_values = np.array(cr_values[mainCr])
            isMax = objective[0][-1] in ('max', 'maximum')
            if isMax:
                Cr_values = -Cr_values
            for i, w in enumerate(EdgesDescriptors):
                node_in, node_out = EdgesCoords[i]
                M[node_in, node_out] = Cr_values[i]
            S = np.abs(Cr_values).sum() + 1.0

            # TODO: check it
            M[np.isnan(M)] = S

            prob = P(lambda x: 0, np.zeros(n), iprint=1)
            prob.f = lambda x: np.nan if not hasattr(prob, 'ff') else (
                prob.ff if isMax else -prob.ff)
            prob.M = dict([((i, j), M[i, j]) for i in range(n)
                           for j in range(n) if i != j])
            r = prob.solve(solver, **KW)
            xf = [nodes[j] for j in np.array(r.xf, int)]
            r.nodes = xf  #.tolist()
            if self.start is not None:
                j = r.nodes.index(self.start)
                r.nodes = r.nodes[j:] + r.nodes[:j]
            if self.returnToStart:
                r.nodes += [r.nodes[0]]
            r.edges = [(r.nodes[i], r.nodes[i + 1]) for i in range(n - 1)]
            r.Edges = [(r.nodes[i], r.nodes[i + 1],
                        graph[r.nodes[i]][r.nodes[i + 1]][0])
                       for i in range(n - 1)]
            if self.returnToStart:
                r.edges.append((r.nodes[-2], r.nodes[0]))
                print(r.nodes[-1], r.nodes[0], type(r.nodes[-1]),
                      type(r.nodes[0]), graph[2])
                r.Edges.append((r.nodes[-2], r.nodes[0],
                                graph[r.nodes[-2]][r.nodes[0]][0]))
            #r.xf = r.xk = r.nodes
            # TODO: Edges
            return r

        #TODO: fix ooarray lb/ub
        #u = np.array([1] + [fd.oovar(lb=2, ub=n) for i in range(n-1)])
        u = fd.hstack((1, fd.oovars(n - 1, lb=2, ub=n)))
        for i in range(1, u.size):
            u[i]('u' + str(i))

        if is_interalg_raw_mode:
            for i in range(n - 1):
                u[1 + i].domain = np.arange(2, n + 1)

        if interalg_gdp:
            assert len(x) == n
            x = fd.ooarray(x)

            # TODO: remove it when proper enum implementation in FD engine will be done
            for i in range(n):
                x[i]._init_domain = x[i].domain
                constraints.append(x[i] - x[i]._init_domain[-1] <= 0)
                x[i].domain = np.arange(
                    int(2**np.ceil(np.log2(node_out_edges_num[i]))))
#            for i in range(n-1):
#                u[1+i]._init_domain = u[1+i].domain
#                constraints.append(u[1+i]-u[1+i]._init_domain[-1] <= 0)
#                u[1+i].domain = np.arange(u[1+i]._init_domain[0], u[1+i]._init_domain[0]+int(2 ** np.ceil(np.log2(u[1+i]._init_domain[-1]-u[1+i]._init_domain[0]+1))))
#                u[1+i].ub = u[1+i].domain[-1]

        else:
            x = fd.oovars(m, domain=bool)  # new m value
        for i in range(x.size):
            x[i]('x' + str(i))


#        if init_graph_is_directed:
        dictFrom = dict([(node, []) for node in nodes])
        dictTo = dict([(node, []) for node in nodes])
        for i, edge in enumerate(EdgesCoords):
            From, To = edge
            dictFrom[From].append(i)
            dictTo[To].append(i)

        engine = fd.XOR

        # number of outcoming edges = 1
        if not interalg_gdp:
            for node, edges_inds in dictFrom.items():
                # !!!!!!!!!! TODO for interalg_raw_mode: and if all edges have sign similar to goal
                if 1 and is_interalg_raw_mode:
                    c = engine([x[j] for j in edges_inds])
                else:
                    nEdges = fd.sum([x[j] for j in edges_inds])
                    c = nEdges >= 1 if self.allowRevisit else nEdges == 1
                constraints.append(c)

        # number of incoming edges = 1
        for node, edges_inds in dictTo.items():
            if len(edges_inds) == 0:
                self.err(
                    'input graph has node %s that has no edge from any other node; solution is impossible'
                    % node)

            if interalg_gdp:
                x_inds, x_vals = [], []
                for elem in edges_inds:
                    x_ind, x_val = edge_ind2x_ind_val[elem]
                    x_inds.append(x_ind)
                    x_vals.append(x_val)
                c = engine([(x[x_ind] == x_val)(tol=0.5)
                            for x_ind, x_val in zip(x_inds, x_vals)])
            else:
                if 1 and is_interalg_raw_mode and engine == fd.XOR:
                    c = engine([x[j] for j in edges_inds])
                else:
                    nEdges = fd.sum([x[j] for j in edges_inds])
                    c = nEdges >= 1 if self.allowRevisit else nEdges == 1
            constraints.append(c)

        # MTZ
        for i, (I, J) in enumerate(EdgesCoords):
            ii, jj = node2index[I], node2index[J]
            if ii != 0 and jj != 0:
                if interalg_gdp:
                    x_ind, x_val = edge_ind2x_ind_val[i]
                    c = fd.ifThen((x[x_ind] == x_val)(tol=0.5),
                                  u[ii] - u[jj] <= -1.0)
                elif is_interalg_raw_mode:
                    c = fd.ifThen(x[i],
                                  u[ii] - u[jj] <= -1.0)  #u[jj] - u[ii]  >= 1)
                else:
                    c = u[ii] - u[jj] + 1 <= (n - 1) * (1 - x[i])
                constraints.append(c)

        # handling objective(s)
        FF = []

        for optCrName in usedValues:

            tmp = cr_values.get(optCrName, [])

            if len(tmp) == 0:
                self.err(
                    'seems like graph edgs have no attribute "%s" to perform optimization on it'
                    % optCrName)
            elif len(tmp) != m:
                self.err(
                    'for optimization creterion "%s" at least one edge has no this attribute'
                    % optCrName)
            if interalg_gdp:
                F = []
                lc = 0
                for X in x:
                    domain = X._init_domain
                    vals = [tmp[i] for i in range(lc, lc + domain.size)]
                    lc += domain.size
                    #F = sum(x)
                    #F.append(fd.interpolator(domain, vals, k=1, s=0.00000001)(X))
                    F.append(fd.interpolator(domain, vals, k=1)(X))
                    #print(domain, vals)
                F = fd.sum(F)
            else:
                F = fd.sum(x * tmp)
            Funcs[optCrName] = F

        for obj in objective:
            FF.append(
                (Funcs[obj[0]] if type(obj[0]) in (str,
                                                   np.str_) else obj[0](Funcs),
                 obj[1], obj[2]))

        for c in Cons:
            tmp = c(Funcs)
            if type(tmp) in (list, tuple, set):
                constraints += list(tmp)
            else:
                constraints.append(tmp)

        startPoint = {x: [0] * (m if not interalg_gdp else n)}
        startPoint.update(dict([(U, i + 2) for i, U in enumerate(u[1:])]))

        p = P(FF if isMOP else FF[0][0], startPoint,
              constraints=constraints)  #, fixedVars = fixedVars)
        for param in ('start', 'returnToStart'):
            KW.pop(param, None)
        r = p.solve(solver, **KW)

        if P != oo.MOP:
            r.ff = p.ff
            if interalg_gdp:
                x_ind_val2edge_ind = dict([
                    (elem[1], elem[0]) for elem in edge_ind2x_ind_val.items()
                ])
                SolutionEdges = [
                    (EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i])
                    for i in
                    [x_ind_val2edge_ind[(ind, x[ind](r))] for ind in range(n)]
                ]
            else:
                SolutionEdges = [(EdgesCoords[i][0], EdgesCoords[i][1],
                                  EdgesDescriptors[i]) for i in range(m)
                                 if r.xf[x[i]] == 1]
            if len(SolutionEdges) == 0:
                r.nodes = r.edges = r.Edges = []
                return r

            S = dict([(elem[0], elem) for elem in SolutionEdges])

            SE = [SolutionEdges[0]]
            for i in range(len(SolutionEdges) - 1):
                SE.append(S[SE[-1][1]])
            SolutionEdgesCoords = [(elem[0], elem[1]) for elem in SE]

            nodes = [edge[1] for edge in SolutionEdgesCoords]
            if self.start is not None:
                shift_ind = nodes.index(self.start)
                nodes = nodes[shift_ind:] + nodes[:shift_ind]

            if self.returnToStart:
                nodes.append(nodes[0])

            edges = SolutionEdgesCoords[1:] + [SolutionEdgesCoords[0]]
            Edges = SE[1:] + [SE[0]]
            if self.start is not None:
                edges, Edges = edges[shift_ind:] + edges[:shift_ind], Edges[
                    shift_ind:] + Edges[:shift_ind]
            if not self.returnToStart:
                edges, Edges = edges[:-1], Edges[:-1]
            r.nodes, r.edges, r.Edges = nodes, edges, Edges
        else:
            r.solution = 'for MOP see r.solutions instead of r.solution'
            tmp_c, tmp_v = r.solutions.coords, r.solutions.values
            #            if interalg_gdp:
            #                x_ind_val2edge_ind = dict([(elem[1], elem[0]) for elem in edge_ind2x_ind_val.items()])
            #                SolutionEdges = [(EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i]) for i in [x_ind_val2edge_ind[(ind, x[ind](r))] for ind in range(n)]]
            #            else:
            #                SolutionEdges = [(EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i]) for i in range(m) if r.xf[x[i]] == 1]
            if interalg_gdp:  # default for MOP
                x_ind_val2edge_ind = dict([
                    (elem[1], elem[0]) for elem in edge_ind2x_ind_val.items()
                ])
                r.solutions = MOPsolutions([[
                    (EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i])
                    for i in [
                        x_ind_val2edge_ind[(ind, x[ind](Point))]
                        for ind in range(n)
                    ]
                ] for Point in r.solutions])
            else:  # non-default
                r.solutions = MOPsolutions([[
                    (EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i])
                    for i in range(m) if Point[x[i]] == 1
                ] for Point in r.solutions])

            r.solutions.values = tmp_v
        return r
Пример #24
0
    def solve(self, *args, **kw):
        import FuncDesigner as fd, openopt as oo 
        
        if len(args) > 1:
            self.err('''
            incorrect number of arguments for solve(), 
            must be at least 1 (solver), other must be keyword arguments''')
        solver = args[0] if len(args) != 0 else kw.get('solver', self.solver)
        KW = self.__init_kwargs.copy()
        KW.update(kw)
        items = self.items
        n = len(items)
        objective = KW.get('objective', self.objective)
        if isinstance(objective, (list, tuple, set)):
            nCriteria = len(self.objective)
            if 3 * nCriteria != np.asarray(self.objective).size:
                objective = [(objective[3*i], objective[3*i+1], objective[3*i+2]) for i in range(int(round(np.asarray(self.objective).size / 3)))]
            if len(objective) == 1:
                KW['fTol'], KW['goal'] = objective[0][1:]
        else:
            objective = [(self.objective, KW.get('fTol', getattr(self, 'fTol')), KW.get('goal', getattr(self, 'goal')))]

        nCriteria = len(objective)
        isMOP = nCriteria > 1
        #mainCr = objective[0][0]
        
        solverName = solver if type(solver) == str else solver.__name__
        is_interalg = solverName == 'interalg'
        is_glp = False#solverName == 'sa'
        if is_glp:
            assert nCriteria == 1, 'you cannot solve multiobjective KSP by the solver'
            
        #is_interalg_raw_mode = is_interalg and KW.get('dataHandling', oo.oosolver(solver).dataHandling) in ('auto','raw')
        KW.pop('objective', None)
        P = oo.MOP if nCriteria > 1 else oo.GLP if is_interalg else oo.MILP if not is_glp else oo.GLP

        
        x = fd.oovars(n, domain=bool)
        requireCount  = False
        for i, obj in enumerate(items):
            if 'n' in obj:
                x[i].domain = np.arange(obj['n']+1) if is_interalg else int
                x[i].ub = obj['n']
                x[i].lb = 0
                requireCount  = True

        #cr_values = dict([(obj[0], []) for obj in objective])
        
        constraints = []
        
        Funcs = {}
        Cons = KW.pop('constraints', [])
        if type(Cons) not in (list, tuple):
            Cons = [Cons]
        usedValues = getUsedValues(Cons)
        usedValues.update(getUsedValues([obj[0] for obj in objective]))
        cr_values = {}
        for val in usedValues:
            if val == 'nItems':
                cr_values[val] = 1
            else:
                cr_values[val] = [obj[val] for obj in items]
        
#        MainCr = mainCr if type(mainCr) in (str, np.str_) else list(usedValues)[0]
#        
#        isMainCrMin = objective[0][2] in ('min', 'minimum')
        
        # handling objective(s)
        FF = []
        
        for optCrName in usedValues:
            F = fd.sum(x * cr_values[optCrName])
            Funcs[optCrName] = F
        
        for obj in objective:
            FF.append((Funcs[obj[0]](obj[0]) if type(obj[0]) in (str, np.str_) else obj[0](Funcs), obj[1], obj[2]))

        for c in Cons:
            tmp = c(Funcs)
            if type(tmp) in (list, tuple, set):
                constraints += list(tmp)
            else:
                constraints.append(tmp)
        
        startPoint = {x:[0]*n}

        p = P(FF if isMOP else FF[0][0], startPoint, constraints = constraints)#, fixedVars = fixedVars)
        if not isMOP:
            p.goal=self.goal
        r = p.solve(solver, **KW)
        
        if P != oo.MOP:
            r.ff = p.ff
            
        if isMOP:
            #assert not requireCount, 'MOP with nItem > 1 is unimplemented yet'
            r.solution = 'for MOP see r.solutions instead of r.solution'
            #tmp_c, tmp_v = r.solutions.coords, r.solutions.values  
            if len(r.solutions):
                S = []
                for s in r.solutions:
                    tmp = [((i, int(s[x[i]])) if requireCount else i) for i in range(n) if s[x[i]]>=1]
                    if 'name' in items[0]:
                        tmp = [(items[i]['name'], k) for i, k in tmp] if requireCount else [items[i]['name'] for i in tmp]
                    S.append(dict(tmp) if requireCount else tmp)
                Vals = dict([(ff[0].name, r.solutions.values[:, i]) for i, ff in enumerate(FF)])

                Dicts = [s.copy() for s in S]
                for v in usedValues:
                    if v != 'nItems':
                        for i, d in enumerate(Dicts):
                            d[v] = Vals[v][i]
                r.solutions = MOPsolutions(Dicts)
                r.solutions.coords = S
                r.solutions.values = Vals
        else:
            tmp = [((i, int(r.xf[x[i]])) if requireCount else i) for i in range(n) if r.xf[x[i]]>=1]
            if 'name' in items[0]:
                tmp = [(items[i]['name'], k) for i, k in tmp] if requireCount else [items[i]['name'] for i in tmp]
            r.xf = dict(tmp) if requireCount else tmp
        return r
Пример #25
0
    def solve(self, *args, **kw):
        import FuncDesigner as fd, openopt as oo 
        
        if len(args) > 1:
            self.err('''
            incorrect number of arguments for solve(), 
            must be at least 1 (solver), other must be keyword arguments''')
        solver = args[0] if len(args) != 0 else kw.get('solver', self.solver)
        KW = self.__init_kwargs.copy()
        KW.update(kw)
        bins, items = self.bins, self.items
        #n = len(items)
#        objective = KW.get('objective', self.objective)
#        if isinstance(objective, (list, tuple, set)):
#            nCriteria = len(self.objective)
#            if 3 * nCriteria != np.asarray(self.objective).size:
#                objective = [(objective[3*i], objective[3*i+1], objective[3*i+2]) for i in range(int(round(np.asarray(self.objective).size / 3)))]
#            if len(objective) == 1:
#                KW['fTol'], KW['goal'] = objective[0][1:]
#        else:
#            objective = [(self.objective, KW.get('fTol', getattr(self, 'fTol')), KW.get('goal', getattr(self, 'goal')))]

        nCriteria = 1#len(objective)
        isMOP = nCriteria > 1

        #mainCr = objective[0][0]
        
        solverName = solver if type(solver) == str else solver.__name__
        is_interalg = solverName == 'interalg'
        is_glp = False#solverName == 'sa'
        if is_glp:
            assert nCriteria == 1, 'you cannot solve multiobjective KSP by the solver'
            
        #is_interalg_raw_mode = is_interalg and KW.get('dataHandling', oo.oosolver(solver).dataHandling) in ('auto','raw')
        KW.pop('objective', None)
        P = oo.MOP if nCriteria > 1 else oo.GLP if is_interalg else oo.MILP if not is_glp else oo.GLP

        item_numbers = [item.get('n', 1) for item in items]
        nItemTypes = len(items)
        nItems = sum(item_numbers)
        
        Cons = KW.pop('constraints', [])
        if type(Cons) not in (list, tuple):
            Cons = [Cons]
        
        Funcs = {}
        
        usedValues = getUsedValues(Cons)
        bins_keys = set(bins.keys())
        for Set in (bins_keys, usedValues):
            if 'n' in Set:
                Set.remove('n')
        UsedValues = usedValues.copy()
        
        UsedValues.update(bins_keys)
        
        cr_values = {}
        for val in UsedValues:
            if val == 'nItems':
                cr_values[val] = 1
            else:
                cr_values[val] = [obj[val] for obj in items]
        
        nBins = bins.get('n', -1)
        if nBins == -1:
            if len(UsedValues) == 1 and type(bins) == dict:
                Tmp_items = sum(list(cr_values.values()[0]))
                Tmp_bins = bins[list(UsedValues)[0]]
                approx_n_bins = int(np.ceil((2.0 * Tmp_items) / Tmp_bins))
            else:
                approx_n_bins = nItems
            nBins = approx_n_bins
            
        X = fd.oovars(nBins * nItemTypes, domain=int, lb=0).view(np.ndarray).reshape(nItemTypes, nBins)
        
        requireCount  = False
        for item in items:
            if 'n' in item:
#                x[i].domain = np.arange(obj['n']+1) if is_interalg else int
#                x[i].ub = obj['n']
#                x[i].lb = 0
                requireCount  = True
                break
        
        y = fd.oovars(nBins, domain = bool)('y')
        aux_objective = fd.sum(y)
        
        #cr_values = dict([(obj[0], []) for obj in objective])
        
#        MainCr = mainCr if type(mainCr) in (str, np.str_) else list(usedValues)[0]
#        
#        isMainCrMin = objective[0][2] in ('min', 'minimum')
        
        # handling objective(s)
#        FF = []
        
        
        
        for optCrName in UsedValues:
            F = [fd.sum(X[:, j].view(fd.ooarray) * cr_values[optCrName]) for j in range(nBins)]
            Funcs[optCrName] = F
        
        FUNCS = [dict((optCrName, Funcs[optCrName][j]) for optCrName in UsedValues) for j in range(nBins)]
                
#        for obj in objective:
#            FF.append((Funcs[obj[0]](obj[0]) if type(obj[0]) in (str, np.str_) else obj[0](Funcs), obj[1], obj[2]))

        constraints = []
        
        # 1. Constraints from p.constraints

        for c in Cons:
            tmp = [c(F) for F in FUNCS]
            constraints += tmp
        
        # 2. Constraints from bins parameters
        for k, v in bins.items():
            if k != 'n':
                constraints += [fd.sum(X[:, j].view(fd.ooarray) * cr_values[k]) <= v*y[j] for j in range(nBins)]
        
        # 3. Number of items of type i from all bins equals to item_numbers[i]
        constraints += [fd.sum(X[i].view(fd.ooarray)) == item_numbers[i] for i in range(nItemTypes)]
        
        startPoint = dict((X[i, j], 0) for i in range(nItemTypes) for j in range(nBins))
        startPoint[y] = [0]*nBins
        
        p = P(aux_objective, startPoint, constraints = constraints)
#        p = P(FF if isMOP else FF[0][0], startPoint, constraints = constraints)#, fixedVars = fixedVars)
        if not isMOP:
            p.goal=self.goal
        r = p.solve(solver, **KW)
        
        if P != oo.MOP:
            r.ff = p.ff
            
        if isMOP:
            assert 0, 'unimplemented'
#            #assert not requireCount, 'MOP with nItem > 1 is unimplemented yet'
#            r.solution = 'for MOP see r.solutions instead of r.solution'
#            #tmp_c, tmp_v = r.solutions.coords, r.solutions.values  
#            if len(r.solutions):
#                S = []
#                for s in r.solutions:
#                    tmp = [((i, int(s[x[i]])) if requireCount else i) for i in range(n) if s[x[i]]>=1]
#                    if 'name' in items[0]:
#                        tmp = [(items[i]['name'], k) for i, k in tmp] if requireCount else [items[i]['name'] for i in tmp]
#                    S.append(dict(tmp) if requireCount else tmp)
#                Vals = dict([(ff[0].name, r.solutions.values[:, i]) for i, ff in enumerate(FF)])
#
#                Dicts = [s.copy() for s in S]
#                for v in usedValues:
#                    if v != 'nItems':
#                        for i, d in enumerate(Dicts):
#                            d[v] = Vals[v][i]
#                r.solutions = MOPsolutions(Dicts)
#                r.solutions.coords = S
#                r.solutions.values = Vals
        else:
            if requireCount:
                xf = [dict((item.get('name',i), int(r.xf[X[i, j]])) for i, item in enumerate(items) if r.xf[X[i, j]]>0) for j in range(nBins) if r.xf[y[j]]]
            else:
                xf = [tuple(item.get('name',i) for i, item in enumerate(items) if r.xf[X[i, j]]==1) for j in range(nBins) if r.xf[y[j]]]
            
            r.values = dict((optCrName, tuple(sum(item[optCrName]*r.xf[X[i, j]] for i, item in enumerate(items)) for j in range(nBins) if r.xf[y[j]])) for optCrName in UsedValues)
            r.xf = xf
#            tmp = [((i, int(r.xf[x[i]])) if requireCount else i) for i in range(n) if r.xf[x[i]]>=1]
#            if 'name' in items[0]:
#                tmp = [(items[i]['name'], k) for i, k in tmp] if requireCount else [items[i]['name'] for i in tmp]
#            r.xf = dict(tmp) if requireCount else tmp
        return r