# Path: platypus/core.py
# class Solution(object):
#     """Class representing a solution to a problem.
#     
#     Attributes
#     ----------
#     problem: Problem
#         The problem.
#     variables: FixedLengthArray of objects
#         The values of the variables.
#     objectives: FixedLengthArray of float
#         The values of the objectives.  These values will only be assigned after
#         the solution is evaluated.
#     constraints: FixedLengthArray of float
#         The values of the constraints.  These values will only be assigned
#         after the solution is evaluated.
#     constraint_violation: float
#         The magnitude of the constraint violation.
#     feasible: bool
#         True if the solution does not violate any constraints; False otherwise.
#     evaluated: bool
#         True if the solution is evaluated; False otherwise.
#     """
#     
#     def __init__(self, problem):
#         """Creates a new solution for the given problem."""
#         super(Solution, self).__init__()
#         self.problem = problem
#         self.variables = FixedLengthArray(problem.nvars)
#         self.objectives = FixedLengthArray(problem.nobjs)
#         self.constraints = FixedLengthArray(problem.nconstrs)
#         self.constraint_violation = 0.0
#         self.evaluated = False
#         
#     def evaluate(self):
#         """Evaluates this solution."""
#         self.problem(self)
#         
#     def __repr__(self):
#         return self.__str__()
#         
#     def __str__(self):
#         return "Solution[" + ",".join(list(map(str, self.variables))) + "|" + ",".join(list(map(str, self.objectives))) + "|" + str(self.constraint_violation) + "]"
#     
#     def __deepcopy__(self, memo):
#         """Overridden to avoid cloning the problem definition."""
#         result = Solution(self.problem)
#         memo[id(self)] = result
#         
#         for k, v in self.__dict__.items():
#             if k != "problem":
#                 setattr(result, k, copy.deepcopy(v, memo))
#                 
#         return result
# 
# POSITIVE_INFINITY = float("inf")
# 
# EPSILON = sys.float_info.epsilon
# 
# class PlatypusError(Exception):
#     pass


import sys
import math
import random
import inspect
import operator
import functools
from functools import reduce
from .core import Solution, POSITIVE_INFINITY, EPSILON, PlatypusError

    # back substitution
    x = [0.0]*N
    
    for i in range(N-1, -1, -1):
        sum = 0.0
        
        for j in range(i+1, N):
            sum += A[i][j] * x[j]
            
        x[i] = (b[i] - sum) / A[i][i]

    return x

def choose(n, k):
    if 0 <= k <= n:
        ntok = 1
        ktok = 1
        for t in range(1, min(k, n - k) + 1):
            ntok *= n
            ktok *= t
            n -= 1
        return ntok / ktok
    else:
        return 0

def euclidean_dist(x, y):
    """Computes the Euclidean distance between two points."""
    if isinstance(x, Solution):
        x = x.objectives

# Path: platypus/core.py
# class Solution(object):
#     """Class representing a solution to a problem.
#     
#     Attributes
#     ----------
#     problem: Problem
#         The problem.
#     variables: FixedLengthArray of objects
#         The values of the variables.
#     objectives: FixedLengthArray of float
#         The values of the objectives.  These values will only be assigned after
#         the solution is evaluated.
#     constraints: FixedLengthArray of float
#         The values of the constraints.  These values will only be assigned
#         after the solution is evaluated.
#     constraint_violation: float
#         The magnitude of the constraint violation.
#     feasible: bool
#         True if the solution does not violate any constraints; False otherwise.
#     evaluated: bool
#         True if the solution is evaluated; False otherwise.
#     """
#     
#     def __init__(self, problem):
#         """Creates a new solution for the given problem."""
#         super(Solution, self).__init__()
#         self.problem = problem
#         self.variables = FixedLengthArray(problem.nvars)
#         self.objectives = FixedLengthArray(problem.nobjs)
#         self.constraints = FixedLengthArray(problem.nconstrs)
#         self.constraint_violation = 0.0
#         self.evaluated = False
#         
#     def evaluate(self):
#         """Evaluates this solution."""
#         self.problem(self)
#         
#     def __repr__(self):
#         return self.__str__()
#         
#     def __str__(self):
#         return "Solution[" + ",".join(list(map(str, self.variables))) + "|" + ",".join(list(map(str, self.objectives))) + "|" + str(self.constraint_violation) + "]"
#     
#     def __deepcopy__(self, memo):
#         """Overridden to avoid cloning the problem definition."""
#         result = Solution(self.problem)
#         memo[id(self)] = result
#         
#         for k, v in self.__dict__.items():
#             if k != "problem":
#                 setattr(result, k, copy.deepcopy(v, memo))
#                 
#         return result
# 
# POSITIVE_INFINITY = float("inf")
# 
# EPSILON = sys.float_info.epsilon
# 
# class PlatypusError(Exception):
#     pass


# Path: platypus/tools.py
import sys
import math
import random
import inspect
import operator
import functools
from functools import reduce
from .core import Solution, POSITIVE_INFINITY, EPSILON, PlatypusError


    # back substitution
    x = [0.0]*N
    
    for i in range(N-1, -1, -1):
        sum = 0.0
        
        for j in range(i+1, N):
            sum += A[i][j] * x[j]
            
        x[i] = (b[i] - sum) / A[i][i]

    return x

def choose(n, k):
    if 0 <= k <= n:
        ntok = 1
        ktok = 1
        for t in range(1, min(k, n - k) + 1):
            ntok *= n
            ktok *= t
            n -= 1
        return ntok / ktok
    else:
        return 0

def euclidean_dist(x, y):
    """Computes the Euclidean distance between two points."""
    if isinstance(x, Solution):
        x = x.objectives

    if isinstance(y, Solution):