Solving a Linear Diophantine Equation(see description for examples)

前端 未结 8 904
忘掉有多难
忘掉有多难 2020-12-16 20:27

Let me start off by clarifying that(before you guys dismiss me), this is not a homework problem and I\'m not a university student. :)

EDIT Thanks to

8条回答
  •  借酒劲吻你
    2020-12-16 20:57

    The reason why there is no library that does this is similar to why you won't find a library to do permutations - you generate so much data that this is probably the wrong thing to do.

    More precisely, if you have n variables whose sum totals X, then you will have O(Xn-1) answers. X and n don't have to be very large for this to become an issue.

    That said, here is some Python that fairly efficiently figures out all of the necessary information to encode the answer:

    def solve_linear_diophantine (*coeff_tuple):
        coeff = list(coeff_tuple)
        constant = coeff.pop()
    
        cached = []
        for i in range(len(coeff)):
            # Add another cache.
            cached.append({})
    
        def solve_final (i, remaining_constant):
            if remaining_constant in cached[i]:
                return cached[i][remaining_constant]
            answer = []
            if i+1 == len(coeff):
                if 0 == remaining_constant%coeff[i]:
                    answer = [(remaining_constant/coeff[i], [])]
            else:
                for j in range(remaining_constant/coeff[i] + 1):
                    finish = solve_final(i+1, remaining_constant - j*coeff[i])
                    if finish is not None:
                        answer.append((j, finish))
            if 0 == len(answer):
                cached[i][remaining_constant] = None
                return None
            else:
                cached[i][remaining_constant] = answer
                return answer
    
        return solve_final(0, constant)
    

    When I say "encode", the data structure looks like this. For each possible coefficient, we'll get an array of (coefficient, [subanswers]). Whenever possible it reuses subanswers to make the data structure as small as possible. If you cant you can recursively expand this back out into an array of answers, and in so doing you'll be pretty efficient. (In fact it is O(nX).) You'll do very little repeating of logic to discover the same facts over and over again. (However the returned list may get very large simply because there is a large list of answers to be returned.)

提交回复
热议问题