Beispiel #1
0
class Optimizer():
    def __init__(self, input_file, N):
        self.input_constraints = Constraint(input_file)
        #print(self.input_constraints.get_ndim())
        #print(self.input_constraints.get_example())
        #print(self.input_constraints.get_constraints())
        #exam = np.array(list(self.input_constraints.get_example()), dtype=float)
        #print(self.input_constraints.apply(exam))
        self.x = self.sample(N)
        self.get_output()

    def sample(self, N):
        count = 0
        ndim = int(self.input_constraints.get_ndim())
        x = np.empty((0, ndim))
        while (count < int(N)):
            n_samples = int(N) * 10
            smpls = lhs(ndim, samples=n_samples)
            for i in range(len(smpls)):
                if self.input_constraints.apply(smpls[i]) and (count < int(N)):
                    #print(smpls[i])
                    x = np.append(x, np.array([smpls[i]]), axis=0)
                    count += 1
        print(count)
        print(x.shape)
        return x

    def get_output(self):
        return self.x
Beispiel #2
0
class Sampler:
    def __init__(self, filename, max_points, max_time):
        self.constraint = Constraint(filename)
        self.n_dim = self.constraint.n_dim
        self.example = self.constraint.example
        self.max_points = max_points
        self.max_time = max_time

    def test_inside(self, x):
        if np.any(np.less(x, 0.)):
            return False
        if np.any(np.greater(x, 1.)):
            return False
        return self.constraint.apply(x)

    def line_search(self, x, direction):
        tiny = 1e-6
        low, high = 0., np.sqrt(self.n_dim) + tiny
        for _ in range(20):
            middle = 0.5 * (low + high)
            inside = self.test_inside(x + middle * direction)
            if inside:
                low = middle
            else:
                high = middle
        return low

    def random_direction(self):
        vector = np.random.normal(size=self.n_dim)
        return vector / np.linalg.norm(vector)

    def hit_and_run(self):
        assert self.test_inside(self.example)

        points = [np.array(self.example)]
        start_time = time.time()
        while len(points) < self.max_points and time.time(
        ) - start_time < self.max_time:
            direction = self.random_direction()

            factor = self.line_search(points[-1], direction)

            if factor > 0.:
                new_point = points[-1] + np.random.uniform(
                ) * factor * direction
                if self.test_inside(new_point):
                    points.append(new_point)
        return points
Beispiel #3
0
def sampler(input_file, output_file, n_result):
    ct = Constraint(input_file)
    ndim = ct.get_ndim()
    current_results = []

    while len(current_results) < n_result:
        res = np.random.random(ndim)
        res = (res / sum(res) * sum(ct.get_example())).round(5)
        if not ct.apply(res):
            continue
        current_results.append(res)
    print('example:', ct.get_example())
    print('res:', res)
    with open(output_file, 'a') as f:
        for l, el in enumerate(current_results):
            string = ' '.join(map(str, el))
            # for item in string:
            f.write(string)
            f.write('\n')
    return current_results
Beispiel #4
0
def get_constraints(input_file):
    """reads the input file and creates an instance of the Constraint class
    """

    # create a new instance of the Constraint class by reading input_file
    # catch several errors: file not found, first two lines (number of
    # dimensions and starting vector) not formatted correctly, or syntax
    # error in the constraints
    try:
        space = Constraint(input_file)
    except FileNotFoundError:
        sys.exit("Error: input file not found")
    except ValueError:
        sys.exit("Error: input file formatted improperly")
    except SyntaxError:
        sys.exit("Error: syntax error in constraints")

    # get the example point and make sure it has the correct dimensionality
    example = space.get_example()
    if len(example) < space.get_ndim():
        sys.exit("Error: example point does not have enough dimensions")

    # check and make sure the example point actually satisfies all of the
    # constraints. This additionally serves to make sure the constraints
    # are specified correctly
    try:
        check_example = space.apply(example)
    except IndexError:
        sys.exit("Error: invalid constraints")
    except NameError:
        sys.exit("Error: invalid constraints")

    # if space.apply(example) returned false, then throw an error
    if not check_example:
        sys.exit("Error: example point is invalid")

    return space
Beispiel #5
0
    def validate_output_file(self, constraints_file_name, points_file_name,
                             expected):
        """
        Validates output file against constraint file to see if required number of points are available.

        :param string constraints_file_name: path to a file that contains the constraints
        :param string points_file_name: path to a file that contains the vectors to be validated
        :param int expected: Number of points that are expected in this file
        """
        self.log.info(
            f'Running validation: {constraints_file_name} <-> {points_file_name}'
        )

        # Return if constraints or points files are not found.
        try:
            constraints = Constraint(constraints_file_name)
        except FileNotFoundError:
            self.log.critical(
                f'Constraints file {constraints_file_name} not found. Skipping validation...'
            )
            return

        try:
            points_file = open(points_file_name, 'r')
        except FileNotFoundError:
            self.log.critical(
                f'Points file {points_file_name} not found. Skipping validation...'
            )
            return

        # Counters for number of points that were generated, passed, failed,
        generated = 0
        passed = 0
        failed = 0
        for itr, line in enumerate(points_file):
            x = [float(_) for _ in line.strip().split(" ")]

            # Log how many points have been checked.
            if itr != 0 and (itr % pow(10, floor(log10(itr + 1))) == 0):
                self.log.debug(f'Checked {itr}')

            # Count number of points generated/passed/failed
            generated += 1
            try:
                if constraints.apply(x):
                    passed += 1
                else:
                    self.log.warning(f'Point outside constraints: {x}')
                    failed += 1
            except:
                self.log.error(f'{sys.exc_info()[1]}, point: {x}')

        points_file.close()

        # Points file summary
        self.log.info(f'{generated} generated, {expected} expected')
        self.log.info(f'{passed} passed, {failed} failed')

        if generated != expected:
            self.log.warning(f'Unexpected number of points')

        if failed > 0:
            self.log.warning(f'{failed} points failed')

        if passed == expected or passed == generated:
            self.log.info(f'All points are valid')

        self.log.info(
            f'Validated {constraints_file_name} <-> {points_file_name}')

        self.log.info(f'-- Validation complete -- ')
        return
Beispiel #6
0
class Solution():
    def __init__(self, fname, outfile, n_results):

        self.con = Constraint(fname)
        self.num_x = self.con.n_dim
        self.n_results = n_results

        self.outfile = outfile
        with open(self.outfile, 'w') as f:
            f.write(" ".join(map(str, self.con.example)))
            f.write("\n")

        self.ineq_cons = {
            'type': 'ineq',
            'fun': lambda x: self.con.eval_con(x.tolist())
        }

        bound = [0.0, 1.0]
        self.bounds = np.asarray([bound] * self.num_x)

        # determining the magnitude of the largest initial point
        max_initial = max(self.con.example)
        if max_initial == 0.0:
            self.alpha = 1.0
        else:
            self.alpha = 1.0 / max_initial

    def solve(self):

        x0_all = np.random.random_sample(
            (self.n_results * 2, self.num_x)) / self.alpha

        output = []
        cnt = 0
        for i in range(len(x0_all)):
            x0 = x0_all[i, :]

            if self.con.apply(x0.tolist()):
                x_feasible = x0
            else:
                try:
                    res = self.optimize_feasible(x0)
                    x_feasible = res.x

                    if res.status != 0 or any(x_feasible < 0.0) or any(
                            x_feasible > 1.0) or list(x_feasible) in output:
                        continue

                except:
                    continue

            # if self.con.apply(x_feasible.tolist()):
            #     print "True"

            with open(self.outfile, 'a') as f:
                f.write(" ".join(map(str, x_feasible)))
                f.write("\n")

            output.append(list(x_feasible))

            cnt += 1
            if cnt == self.n_results:
                break

        return output

    def optimize_feasible(self, x0):
        res = optimize.minimize(self.f,
                                x0,
                                method='SLSQP',
                                constraints=[self.ineq_cons],
                                options={
                                    'ftol': 1e-8,
                                    'disp': False
                                },
                                bounds=self.bounds)

        return res

    def f(self, x):
        constr = self.con.eval_con(x.tolist())
        constr[np.where(constr > 0)] = 0
        return np.sum(np.square(constr))

    def constraint(self, x):
        constr = self.con.eval_con(x.tolist())
        return constr
Beispiel #7
0
class SCMC():
    """Use sequentially constrained Monte Carlo method to sample given constrained domains uniformly
    
    Methods
    -------
    write_ouput:
        write the final sample in given path
        
    get_correctness:
        return the correctness of the final state
        
    get_history: 
        return a List, the history all samples in the sequential diffusion process
        
    plot_results: 
        scatter plot the results along two arbitrary axes
        params
        ------
            comp1, int: first axis (h)                
            comp2, int: second axis (v)        
            n_iter, int: if want history instead of final state
            
    print_constraints:
        print the original constraints
    
    
        
    
    """
    def __init__(self,
                 input_path,
                 n_results,
                 beta_max=10**4,
                 p_beta=1,
                 p_rw_step=0,
                 track_correctness=False,
                 threshold=.999):
        self.input_path = input_path
        self.constraints = Constraint(input_path)

        constraints_funcs = self.constraints.get_functions()

        self.n_dim = self.constraints.get_ndim()
        self.n_results = n_results
        self.beta_max = beta_max
        self.p_beta = p_beta
        self.p_rw_step = p_rw_step

        #call sampling method scmc
        i_sample = init_sample(self.n_dim, self.n_results,
                               self.constraints.bounds,
                               self.constraints.get_example())
        self.i_samples = []
        self.i_samples.append(i_sample)
        self.histories = []
        self.correctnesses = []
        print(len(constraints_funcs))

        for i in range(1, len(constraints_funcs) + 1):
            history, correctness = scmc(
                self.n_dim,
                self.n_results,
                self.i_samples[i - 1],
                constraints_funcs[0:i],
                beta_max,
                self.constraints.bounds,
                p_beta,
                p_rw_step,
                track_correctness=track_correctness,
                given_example=self.constraints.get_example(),
                threshold=threshold)
            self.i_samples.append(history[-1])
            self.histories.append(history)
            self.correctnesses.append(correctness)
        self.results = self.histories[-1][-1]

#        self.history, self.correctness = scmc(self.n_dim, self.n_results, i_sample ,constraints_funcs, beta_max, self.constraints.bounds,
#                                              p_beta,p_rw_step,
#                                              track_correctness=track_correctness,
#                            given_example = self.constraints.get_example())
#        self.results = self.history[-1]
#        self.history, self.correctness = scmc(self.n_dim, self.n_results, constraints_funcs, beta_max, self.constraints.bounds,
#                                              p_beta,p_rw_step,
#                                              track_correctness=track_correctness,
#                            given_example = self.constraints.get_example())
#        self.results = self.history[-1]

#        self.write_ouput(output_path)

    def write_output(self, output_path):
        """
        save the sample to a output_path
        """
        np.savetxt(output_path, self.results)

    def get_correctness(self):
        """
        get correctness
        """
        correctness = [self.constraints.apply(x) for x in self.results]
        correctness = sum(correctness) / self.n_results
        return correctness

    def get_history(self):
        return self.history

    def get_results(self):
        """
        get the sample
        """
        return self.results

    def plot_results(self, comp1, comp2, n_iter=None):
        """
        Plot the sample in x[comp1],x[comp2] 
        """
        if n_iter is None:
            sample = self.results
        else:
            sample = self.history[n_iter - 1]

        plt.figure()
        plt.scatter(sample[:, comp1], sample[:, comp2])
        plt.xlim(0, 1)
        plt.ylim(0, 1)

    def plot_all_axis(self, n_iter=None):

        n_dim = self.n_dim
        for i in range(n_dim):
            for j in range(i + 1, n_dim):
                self.plot_results(i, j, n_iter)
                plt.xlabel('x_{}'.format(i))
                plt.ylabel('x_{}'.format(j))

    def print_constraints(self):
        print(self.constraints.get_exprs_string())