| import argparse |
| import os |
| import numpy as np |
| from utils.data_utils import check_extension, save_dataset |
|
|
|
|
| def generate_tsp_data(dataset_size, tsp_size): |
| return np.random.uniform(size=(dataset_size, tsp_size, 2)).tolist() |
|
|
|
|
| def generate_vrp_data(dataset_size, vrp_size): |
| CAPACITIES = { |
| 10: 20., |
| 20: 30., |
| 50: 40., |
| 75: 45., |
| 100: 50. |
| } |
| theta = 2*np.pi * np.random.uniform(size = (dataset_size, vrp_size)) |
| data_point = 0.5*np.ones((dataset_size, vrp_size, 2)) + np.stack([ 0.5* np.cos(theta), 0.5* np.sin(theta)], axis = 2) |
| demand_point = CAPACITIES[vrp_size]/vrp_size* np.ones((dataset_size, vrp_size)) |
|
|
| return list(zip( |
| (0.5*np.ones((dataset_size, 2))).tolist(), |
| data_point.tolist(), |
| demand_point.tolist(), |
| np.full(dataset_size, CAPACITIES[vrp_size]).tolist() |
| )) |
|
|
|
|
| def generate_op_data(dataset_size, op_size, prize_type='const'): |
| depot = np.random.uniform(size=(dataset_size, 2)) |
| loc = np.random.uniform(size=(dataset_size, op_size, 2)) |
|
|
| |
| if prize_type == 'const': |
| prize = np.ones((dataset_size, op_size)) |
| elif prize_type == 'unif': |
| prize = (1 + np.random.randint(0, 100, size=(dataset_size, op_size))) / 100. |
| else: |
| assert prize_type == 'dist' |
| prize_ = np.linalg.norm(depot[:, None, :] - loc, axis=-1) |
| prize = (1 + (prize_ / prize_.max(axis=-1, keepdims=True) * 99).astype(int)) / 100. |
|
|
| |
| |
| MAX_LENGTHS = { |
| 20: 2., |
| 50: 3., |
| 100: 4. |
| } |
|
|
| return list(zip( |
| depot.tolist(), |
| loc.tolist(), |
| prize.tolist(), |
| np.full(dataset_size, MAX_LENGTHS[op_size]).tolist() |
| )) |
|
|
|
|
| def generate_pctsp_data(dataset_size, pctsp_size, penalty_factor=3): |
| depot = np.random.uniform(size=(dataset_size, 2)) |
| loc = np.random.uniform(size=(dataset_size, pctsp_size, 2)) |
|
|
| |
| |
| |
| |
| |
| |
| |
| MAX_LENGTHS = { |
| 20: 2., |
| 50: 3., |
| 100: 4. |
| } |
| penalty_max = MAX_LENGTHS[pctsp_size] * (penalty_factor) / float(pctsp_size) |
| penalty = np.random.uniform(size=(dataset_size, pctsp_size)) * penalty_max |
|
|
| |
| |
| |
| |
| deterministic_prize = np.random.uniform(size=(dataset_size, pctsp_size)) * 4 / float(pctsp_size) |
|
|
| |
| |
| |
| |
| stochastic_prize = np.random.uniform(size=(dataset_size, pctsp_size)) * deterministic_prize * 2 |
|
|
| return list(zip( |
| depot.tolist(), |
| loc.tolist(), |
| penalty.tolist(), |
| deterministic_prize.tolist(), |
| stochastic_prize.tolist() |
| )) |
|
|
|
|
| if __name__ == "__main__": |
| parser = argparse.ArgumentParser() |
| parser.add_argument("--filename", help="Filename of the dataset to create (ignores datadir)") |
| parser.add_argument("--data_dir", default='data', help="Create datasets in data_dir/problem (default 'data')") |
| parser.add_argument("--name", type=str, required=True, help="Name to identify dataset") |
| parser.add_argument("--problem", type=str, default='all', |
| help="Problem, 'tsp', 'vrp', 'pctsp' or 'op_const', 'op_unif' or 'op_dist'" |
| " or 'all' to generate all") |
| parser.add_argument('--data_distribution', type=str, default='all', |
| help="Distributions to generate for problem, default 'all'.") |
|
|
| parser.add_argument("--dataset_size", type=int, default=10000, help="Size of the dataset") |
| parser.add_argument('--graph_sizes', type=int, nargs='+', default=[10, 20, 50,75, 100], |
| help="Sizes of problem instances (default 20, 50, 100)") |
| parser.add_argument("-f", action='store_true', help="Set true to overwrite") |
| parser.add_argument('--seed', type=int, default=1234, help="Random seed") |
|
|
| opts = parser.parse_args() |
|
|
| assert opts.filename is None or (len(opts.problems) == 1 and len(opts.graph_sizes) == 1), \ |
| "Can only specify filename when generating a single dataset" |
|
|
| distributions_per_problem = { |
| 'tsp': [None], |
| 'vrp': [None], |
| 'pctsp': [None], |
| 'op': ['const', 'unif', 'dist'] |
| } |
| if opts.problem == 'all': |
| problems = distributions_per_problem |
| else: |
| problems = { |
| opts.problem: |
| distributions_per_problem[opts.problem] |
| if opts.data_distribution == 'all' |
| else [opts.data_distribution] |
| } |
|
|
| for problem, distributions in problems.items(): |
| for distribution in distributions or [None]: |
| for graph_size in opts.graph_sizes: |
|
|
| datadir = os.path.join(opts.data_dir, problem) |
| os.makedirs(datadir, exist_ok=True) |
|
|
| if opts.filename is None: |
| filename = os.path.join(datadir, "{}{}{}_{}_seed{}.pkl".format( |
| problem, |
| "_{}".format(distribution) if distribution is not None else "", |
| graph_size, opts.name, opts.seed)) |
| else: |
| filename = check_extension(opts.filename) |
|
|
| assert opts.f or not os.path.isfile(check_extension(filename)), \ |
| "File already exists! Try running with -f option to overwrite." |
|
|
| np.random.seed(opts.seed) |
| if problem == 'tsp': |
| dataset = generate_tsp_data(opts.dataset_size, graph_size) |
| elif problem == 'vrp': |
| dataset = generate_vrp_data( |
| opts.dataset_size, graph_size) |
| elif problem == 'pctsp': |
| dataset = generate_pctsp_data(opts.dataset_size, graph_size) |
| elif problem == "op": |
| dataset = generate_op_data(opts.dataset_size, graph_size, prize_type=distribution) |
| else: |
| assert False, "Unknown problem: {}".format(problem) |
|
|
| print(dataset[0]) |
|
|
| save_dataset(dataset, filename) |
|
|