как я могу использовать sympy для решения системы уравнений с условиями ограничения - PullRequest
0 голосов
/ 17 декабря 2018

пример, подобный следующему:

    x1 + x2 + x3 + x4 = 1
    x3 + x4 = 1
    x4 + x5 = 1
    x4 + x5 + x6 = 2
    x1,x2,x3,x4,x5,x6 belong to this set {0, 1}

, так что вы видите, что это линейная система уравнений.

, потому что x принадлежит {0,1} <-> x ** 2 - x = 0, поэтому я решаю это ниже ... но я думаю, что это так глупо:

In [1]: import numpy as np

In [2]: from sympy import *

In [3]: x1,x2,x3,x4,x5,x6 = symbols('x:6')

In [4]: res = solve([x1+x2+x3+x4-1, x3+x4-1, x4+x5-1, x4+x5+x6-2, x1**2-x1, x5**2-x5, x2**2-x2, x3**2-x3, x4**2-x4, x5*
   ...: *2-x5, x6**2-x6],[x1,x2,x3,x4,x5,x6])

In [5]: np.array(res)
Out[5]:
array([[0, 0, 0, 1, 0, 1],
       [0, 0, 1, 0, 1, 1]], dtype=object)

Я знаю, что к var можно добавить некоторые условия ограничения:

x = Symbol("x", positive=True)

Итак, есть ли какие-нибудь условия ограничения, которые могут быть добавлены, как это? :

x1, x2, x3, x4, x5, x6 = symbols('x:6', domain=(0, 1))

Помогите мне, плз .. спасибо!

1 Ответ

0 голосов
/ 21 декабря 2018

Вот что я придумал:

Я использую linsolve для решения линейных уравнений без ограничения области.Тогда набор решений может быть пустым, полностью определенным или зависящим от некоторых свободных переменных.Затем я пробую каждую замену свободных переменных из {0,1} и собираю только те, которые приводят к решению, так что каждая переменная находится в {0,1}.

from sympy import *

def eval_solution(concrete_solution):
    concrete_solution_eval = list(map(lambda x: x == 1 or x == 0,concrete_solution))
    if sum(concrete_solution_eval) == len(concrete_solution):
        return True

    return False

def enumerate_solutions(Sols):

    if Sols.free_symbols == set(): # no free variables. see if all variables belong to {0,1}

        concrete_solution = Sols.args[0]
        if concrete_solution == set(): # no solutions
            return []
        if eval_solution(concrete_solution):
            return [concrete_solution]
        else:
            return []
    # create a list of tuples of free variables, one for each valid value
    free_vars = []
    for i in range(2**len(Sols.free_symbols)):
        free_vars.append(tuple(Sols.free_symbols))

    # generate values to substitute for free variables
    free_vals = [list(bin(i))[2:] for i in range(2**len(Sols.free_symbols))] 
    free_vals = [tuple(map(int, list('0'*(len(Sols.free_symbols)-len(s)))+s )) for s in free_vals] 

    # zip twice to generate lists of pairs of variable and value
    free_zip = zip(free_vars,free_vals)
    free_zip_fin = list([list( zip( x[0], x[1] )) for x in free_zip ] )

    correct_solutions = []

    for substitution in free_zip_fin:
        concrete_solution = list(map(lambda x: x.subs(substitution),Sols.args[0]))
        if eval_solution(concrete_solution):
            correct_solutions.append(concrete_solution)

    return correct_solutions

x1,x2,x3,x4,x5,x6 = symbols('x1,x2,x3,x4,x5,x6')

res=linsolve([x1+x2+x3+x4-1, x3+x4-1, x4+x5-1, x4+x5+x6-2],[x1,x2,x3,x4,x5,x6])

l = enumerate_solutions(res)

print (l)

Это может или не можетбудь быстрее твоей идеи.Убедитесь сами, если это вам нужно

...