Beispiel #1
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 #2
0
def main(argv):

    if len(sys.argv) < 3:
        print(
            'Please provide 3 command line arguments (e.g. input_filename, output_filename, n_results'
        )
        exit(-1)

    in_filename = ''
    out_filename = ''
    niteration = 0

    in_filename = sys.argv[1]
    out_filename = sys.argv[2]
    niteration = int(sys.argv[3])

    c = Constraint(in_filename)
    v = c.get_example()
    print(v)
    n = c.get_ndim()  #this is the chromosome size for each population
    print(n)
    # print(c.apply([0.5, 1.0, 0.0, 0.5]))

    s = 300  #population size

    ga = Genetic(
        s, n, in_filename
    )  #initializes ga type object with populaton size, chromosome size, input file name

    p = ga.get_population()
    print(p)
    print(ga.cal_pop_fitness())

    temp_solution = ga.eval_ga(niteration)
    # print(temp_solution)
    # write result to the output
    with open(out_filename, 'w') as filehandle:
        for item in temp_solution:
            s = "   ".join(str(e) for e in item)
            # print(s)
            l = s
            # l = item
            print(l)
            filehandle.write('%s\n' % l)

    filehandle.close()
Beispiel #3
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 #4
0
def main():
    # Obtain input arguments
    parser = argparse.ArgumentParser(description='Process inputs to sampler')
    parser.add_argument('input_file', default=None, type=str)
    parser.add_argument('output_file', default="output.txt", type=str)
    parser.add_argument('N', default=1000, type=int)
    parser.add_argument('--plot_bool', action="store_true")

    # Parse input arguments
    args = parser.parse_args()
    input_file = args.input_file
    output_file = args.output_file
    N = args.N
    plot_bool = args.plot_bool

    np.random.seed(0)

    # Load file and the corresponding constraint functions and valid example
    if not path.isfile(input_file) and input_file:
        raise ValueError('Input file does not exist')
    elif input_file:
        constraint = Constraint(input_file)
        x0 = np.array(constraint.get_example())
        constraints = constraint.eval_constraints
        constraint_bool = constraint.apply
        constraint_bools = constraint.apply_list
    else:
        # Used for local testing
        constraints = func_constraints
        constraint_bool = func_constraints_bool
        x0 = x0

    # Obtain bounds of input space from which initial sample guesses will
    # be uniformly drawn
    bounds = get_bounds(x0, constraint_bools)

    # Find valid uniformly distributed samples with constrained SMC
    N_star = int(N * 1.1)
    run = RunSMC(N=N_star,
                 bounds=bounds,
                 type="constrained_smc",
                 tau_T=1e7,
                 constraints=constraints)
    x, x0 = run.get_x(), run.get_x0()

    # Evaluate validity. uniqueness, and spread of results
    # Subsample result
    acc, x_valid = get_accuracy(x, constraint_bool)
    idx_x, idx_x_valid = np.arange(x.shape[0]), np.arange(x_valid.shape[0])
    x = x_valid[np.random.choice(idx_x_valid, N, replace=False)] if x_valid.shape[0] >= N else \
        x[np.random.choice(idx_x, N, replace=False)]
    std = np.std(x, axis=0)
    uniq_nums = np.unique(x, axis=0).shape[0]

    print('accuracy: {acc} std: {std} unique candidates: {uniq}'.format(
        acc=acc, std=std, uniq=uniq_nums))

    # Save output and plot if 2D and plot_bool
    np.savetxt(output_file, x, delimiter=' ')
    if x.shape[1] == 2 and plot_bool:
        plt.plot(x0[:, 0], x0[:, 1], 'o', x[:, 0], x[:, 1], '*')
        plt.show()
Beispiel #5
0
class Generator:
    """
    Generator class to generate output_file with required number of points that satisfy constraints in input_file.
    """
    def __init__(self, input_file_name):
        """
        Construct a Generator object and set up the log files.

        :param string input_file_name: Name of the constraints file
        """

        # Setup class logger
        setup_logger('log_generator.log')
        self.log = logging.getLogger('log_generator.log')

        # Set up the constraints
        self.input_file_name = input_file_name
        try:
            self.constraints = Constraint(self.input_file_name)
        except FileNotFoundError:
            self.log.critical(
                f'Constraints file not found: {self.input_file_name}')
        else:
            self.log.info(f'Setup Generator for {self.input_file_name}')

        # Set and queue to hold and explore the required points
        self.point_set = set()
        self.points_queue = deque()

    # Generate_valid_points uses a form of breadth first search to generate n points satisfying the constraints defined in input_file_name.
    def generate_valid_points(self, n_points, min_step_size=1E-30):
        """
        Generate required number of points that satisfy constraints.

        :param int n_points: Required number of points.
        :param float min_step_size: Optional minimum step size (default = 1E-30) for exploration.
        """

        # Return if constraint file is unavailable
        try:
            self.constraints
        except NameError:
            self.log.critical(
                f'Constraints file not found {self.input_file_name} not found. Terminating generation...'
            )
            return

        self.log.info(
            f'Points required: {n_points}, min_step_size: {min_step_size}')
        self.log.info(
            f'Constraints file: {self.input_file_name}, Dimension: {self.constraints.get_ndim()}, Starting point: {self.constraints.get_example()}'
        )

        # Cast as a tuple since immutability is required to put into a set.
        self.point_set.add(tuple(self.constraints.get_example()))

        # Initial step size for exploration.
        step_size = 1.0

        # Run while more points are required.
        while len(self.point_set) < n_points:

            # Add all valid points to the queue for exploration.
            for _ in self.point_set:
                self.points_queue.append(_)

            # Counter to count points found at a given step size.
            n_new_points = 0

            # Run while the queue exists and more points are required.
            while self.points_queue and len(self.point_set) < n_points:

                # Explore outward from each point in the queue and add the found valid points to the queue and set.
                current_point = self.points_queue.popleft()
                n_new_points += self.explore_point(current_point, step_size,
                                                   n_points, self.constraints)

                # End inner while loop: Done with finding points at given step size

            self.log.debug(
                f'Found: {n_new_points} with step size: {step_size}, total in set: {len(self.point_set)}'
            )

            # Decrease step_size and search again.
            step_size /= 2
            if step_size < min_step_size:
                self.log.warning(
                    f'Step size is too small: {step_size}, breaking search')
                break

            # End outer while loop: Done with finding required number of points.

        self.log.info(f'Points found: {len(self.point_set)}')
        self.log.info(f'-- Generation complete -- ')
        return

    def explore_point(self, current_point, step_size, n_points, constraints):
        """
        Explore outward from the current point in all dimensions with a given step size.
        Points that satisfy constraints are added to the queue and the point_set.
        The function returns the number of valid points found from current point.

        :param tuple current_point: Starting point of exploration
        :param float step_size: extent of exploration
        :param int n_points: required number of points
        :param Constraint constraints: set of constraints to satisfy
        """
        found_points = 0
        for i_dim in range(len(current_point)):
            for direction in [-1, +1]:
                # Update the coordinates, use round() to remove floating point errors, and cast as tuple for hash-abilty.
                next_point = list(current_point)
                round_to_digit = max(
                    self.n_digits_after_decimal(next_point[i_dim]),
                    self.n_digits_after_decimal(step_size))
                next_point[i_dim] = round(
                    next_point[i_dim] + (direction * step_size),
                    round_to_digit)
                next_point = tuple(next_point)

                try:
                    # If next_point is within the unit hypercube, meets constraints, and is not already explored, add to queue and set.
                    if self.unit_cube_check(next_point) and constraints.apply(
                            next_point) and next_point not in self.point_set:
                        self.points_queue.append(next_point)
                        self.point_set.add(next_point)
                        found_points += 1
                # ZeroDivisionError exception is logged as a warning and the script continues.
                except ZeroDivisionError:
                    self.log.warning(
                        f'{sys.exc_info()[1]}, point: {next_point}')

                # Unexpected exceptions are logged as errors and the script continues.
                except:
                    self.log.error(f'{sys.exc_info()}, point: {next_point}')

                # Return if the number of required points are found.
                if len(self.point_set) == n_points:
                    return found_points

        return found_points

    def write_to_file(self, output_file_name):
        """
        Setup output file and write coordinates to it.

        :param string output_file_name: Name of the file to write the generated points
        """

        # If constraint file was not found, point_set is empty so there is nothing to write.
        if len(self.point_set) == 0:
            self.log.error(
                f'No points generated for {self.input_file_name}. Terminating writing to {output_file_name}...'
            )
            return

        self.log.info(f'Writing: {self.input_file_name} -> {output_file_name}')

        # Warn if file already exists and will be overwritten.
        if path.exists(output_file_name):
            self.log.warning(
                f'{output_file_name} already exists, overwriting file')

        # Open file for writing and write set of points to it.
        # Use an iterator to remove the new line character from the last line.
        with open(output_file_name, "w") as output_file:
            itr = 0
            new_line = '\n'
            for point in self.point_set:
                itr += 1
                if itr == len(self.point_set): new_line = ''
                output_file.write(" ".join(map(str, point)) + new_line)

        self.log.info(f'Written {itr} lines.')
        self.log.info(f'-- Writing complete -- ')
        return

    def unit_cube_check(self, x):
        """
        Check if the given vector is within the unit hypercube.

        :param tuple x: Object that is used to represent the vector
        """
        for _ in x:
            if _ > 1 or _ < 0:
                return False
        return True

    def n_digits_after_decimal(self, x):
        """
        Return the number of digits after the decimal in x.
        :param float x: input number x
        """
        return len(str(x).split(".")[-1])
Beispiel #6
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())