Commit 4d3f25c4 authored by kazushi.kawamura's avatar kazushi.kawamura
Browse files

upload python code

parent c19af3eb
Loading
Loading
Loading
Loading

solver_python/Makefile

0 → 100644
+14 −0
Changes for solver_python/Makefile: 14 added lines, 0 removed lines.
Original line number Diff line number Diff line
TARGET = sim
OBJS = $(CPPS:.cpp=.o)
CPPS = main.cpp io.cpp solver.cpp tools.cpp
CXX = g++
CXXFLAGS = -std=c++11 -O3

all: $(TARGET)

$(TARGET): $(OBJS)
	$(CXX) -o $@ $(OBJS)

clean:
	rm *.o
	rm $(TARGET)

solver_python/io.cpp

0 → 100644
+287 −0
Changes for solver_python/io.cpp: 287 added lines, 0 removed lines.
Original line number Diff line number Diff line
#include "io.hpp"

void read_problem(const char *f_name, short int *W, short int *H, short int *blocks, short int *line_num, short int block_info[][5][3], short int line_info[][2][5]) {

	ifstream inputfile(f_name);
	if(!inputfile) {
		cout << f_name << ": Cannot open" << endl;
		exit(1);
	}
	
	for(int i = 0; i < MAX_BLOCKS+1; i++) {
		for(int j = 0; j < 5; j++) {
			for(int k = 0; k < 3; k++) {
				block_info[i][j][k] = -1;
			}
		}
	}
	for(int i = 0; i < MAX_LINES+1; i++) {
		for(int j = 0; j < 2; j++) {
			for(int k = 0; k < 5; k++) {
				line_info[i][j][k] = -1;
			}
		}
	}
	*line_num = 0;
	
	int now_block = 0, count;
	short int size_x = -1, size_y = -1, now_x, now_y, num;
	while(1) {
		string line, tmp;
		string::size_type pos;
		
		if(!getline(inputfile, line)) break;
		if(line.find("\n") != string::npos || line.find("\r") != string::npos) {
			line.replace(line.length()-1, 1, ""); // Remove '\n' or '\r'
		}
		
		int len = line.length();
		if(len == 0) continue;
		
		if(line.find("SIZE") != string::npos) {
			replace(line.begin(), line.end(), 'X', ' ');
			istringstream iss(line);
			iss >> tmp >> *W >> *H;
			continue;
		}
		else if(line.find("BLOCK_NUM") != string::npos) {
			istringstream iss(line);
			iss >> tmp >> *blocks;
			continue;
		}
		else if(line.find("BLOCK") != string::npos) {
			now_block++;
			replace(line.begin(), line.end(), 'X', ' ');
			istringstream iss(line);
			iss >> tmp >> size_x >> size_y;
			now_y = 0;
			count = 1;
			block_info[now_block][0][0] = size_x;
			block_info[now_block][0][1] = size_y;
			continue;
		}
		
		// Replace ' ' -> ""
		pos = 0;
		while((pos = line.find(' ', pos)) != string::npos) {
			line.replace(pos, 1, "");
		}
		// Replace '+' -> "-1"
		pos = 0;
		while((pos = line.find('+', pos)) != string::npos) {
			line.replace(pos, 1, "-1");
		}
		// Replace ',' -> " "
		pos = 0;
		while((pos = line.find(',', pos)) != string::npos) {
			line.replace(pos, 1, " ");
		}
		
		istringstream iss(line);
		for(now_x = 0; now_x < size_x; now_x++) {
			iss >> num;
			if(num > 0) {
				block_info[now_block][count][0] = now_x;
				block_info[now_block][count][1] = now_y;
				block_info[now_block][count][2] = num;
				if(line_info[num][0][0] == -1) { line_info[num][0][0] = now_block; }
				else if(line_info[num][1][0] == -1) { line_info[num][1][0] = now_block; }
				else { cout << "Error(RE0): Line#" << num << endl; exit(1); }
				if(num > *line_num) { *line_num = num; }
				count++;
			}
			else if(num < 0) {
				block_info[now_block][count][0] = now_x;
				block_info[now_block][count][1] = now_y;
				block_info[now_block][count][2] = 0;
				count++;
			}
		}
		now_y++;
	}
	cout << "W: " << *W << ", H: " << *H << endl;
	
	/// Print block information ///
	cout << "== Block information ==" << endl;
	cout << "#Blocks = " << *blocks << endl;
	for(int i = 1; i <= *blocks; i++) {
		short int sx = block_info[i][0][0];
		short int sy = block_info[i][0][1];
		cout << "Block#" << i << ": (" << sx << ", " << sy << ")" << endl;
		
		if(sx == 1 && sy == 1) { // monomino
			short int tx = block_info[i][1][0];
			short int ty = block_info[i][1][1];
			short int tn = block_info[i][1][2];
			cout << "- (" << tx << ", " << ty << ") " << tn << endl;
		}
		else {
			for(int it = 1; it < 5; it++) {
				short int tx = block_info[i][it][0];
				short int ty = block_info[i][it][1];
				short int tn = block_info[i][it][2];
				cout << "- (" << tx << ", " << ty << ") " << tn << endl;
			}
		}
	}
	/// Print block information ///
}

void extract_line_info(short int line_num, short int blocks, short int block_info[][5][3], short int line_info[][2][5]) {
	
	short int lines_x[4], lines_y[4]; // # of nums in a block for X- & Y- axes
	for(int i = 1; i <= blocks; i++) {
		short int sx = block_info[i][0][0];
		short int sy = block_info[i][0][1];
		
		if(sx == 1 && sy == 1) { // monomino
			//short int tx = block_info[i][1][0];
			//short int ty = block_info[i][1][1];
			short int tn = block_info[i][1][2];
			
			if(tn == 0) continue;
			
			short int n_idx = 0;
			while(line_info[tn][n_idx][1] != -1) {
				n_idx++;
				if(n_idx >= 2) { cout << "Error(EL0): Line#" << tn << endl; exit(1); }
			}
			line_info[tn][n_idx][LE] = 2;
			line_info[tn][n_idx][TO] = 2;
			line_info[tn][n_idx][RI] = 2;
			line_info[tn][n_idx][BO] = 2;
			
			continue;
		}
		
		for(short int p = 0; p < 4; p++) lines_x[p] = 0;
		for(short int q = 0; q < 4; q++) lines_y[q] = 0;
		
		for(int it = 1; it < 5; it++) {
			short int tx = block_info[i][it][0];
			short int ty = block_info[i][it][1];
			short int tn = block_info[i][it][2];
			if(tn > 0) {
				lines_x[tx] += 1;
				lines_y[ty] += 1;
			}
		}
		
		for(int it = 1; it < 5; it++) {
			short int tx = block_info[i][it][0];
			short int ty = block_info[i][it][1];
			short int tn = block_info[i][it][2];
			
			if(tn == 0) continue;
			
			short int n_idx = 0;
			while(line_info[tn][n_idx][1] != -1) {
				n_idx++;
				if(n_idx >= 2) { cout << "Error(EL1): Line#" << tn << endl; exit(1); }
			}
			
			short int compe_cost, wall_cost;
			// Map to left
			compe_cost = 2;
			compe_cost += lines_x[tx] - 1;
			for(short int p = tx - 1; p >= 0; p--) { compe_cost += lines_x[p] * 2; }
			wall_cost = 1;
			for(int it2 = 1; it2 < 5; it2++) {
				short int cx = block_info[i][it2][0];
				short int cy = block_info[i][it2][1];
				if(cx == tx && cy == ty) continue;
				if(cy == ty && cx < tx) {
					if(sx == 2 && sy == 3 && ty == 1) {
						wall_cost = 4;
					}
					else {
						wall_cost = 2;
					}
				}
			}
			line_info[tn][n_idx][LE] = compe_cost * wall_cost;
			
			// Map to top
			compe_cost = 2;
			compe_cost += lines_y[ty] - 1;
			for(short int q = ty - 1; q >= 0; q--) { compe_cost += lines_y[q] * 2; }
			wall_cost = 1;
			for(int it2 = 1; it2 < 5; it2++) {
				short int cx = block_info[i][it2][0];
				short int cy = block_info[i][it2][1];
				if(cx == tx && cy == ty) continue;
				if(cx == tx && cy < ty) {
					if(sx == 3 && sy == 2 && tx == 1) {
						wall_cost = 4;
					}
					else {
						wall_cost = 2;
					}
				}
			}
			line_info[tn][n_idx][TO] = compe_cost * wall_cost;
			
			// Map to right
			compe_cost = 2;
			compe_cost += lines_x[tx] - 1;
			for(short int p = tx + 1; p < sx; p++) { compe_cost += lines_x[p] * 2; }
			wall_cost = 1;
			for(int it2 = 1; it2 < 5; it2++) {
				short int cx = block_info[i][it2][0];
				short int cy = block_info[i][it2][1];
				if(cx == tx && cy == ty) continue;
				if(cy == ty && cx > tx) {
					if(sx == 2 && sy == 3 && ty == 1) {
						wall_cost = 4;
					}
					else {
						wall_cost = 2;
					}
				}
			}
			line_info[tn][n_idx][RI] = compe_cost * wall_cost;
			
			// Map to bottom
			compe_cost = 2;
			compe_cost += lines_y[ty] - 1;
			for(short int q = ty + 1; q < sy; q++) { compe_cost += lines_y[q] * 2; }
			wall_cost = 1;
			for(int it2 = 1; it2 < 5; it2++) {
				short int cx = block_info[i][it2][0];
				short int cy = block_info[i][it2][1];
				if(cx == tx && cy == ty) continue;
				if(cx == tx && cy > ty) {
					if(sx == 3 && sy == 2 && tx == 1) {
						wall_cost = 4;
					}
					else {
						wall_cost = 2;
					}
				}
			}
			line_info[tn][n_idx][BO] = compe_cost * wall_cost;
		}
	}
	
	/// Print line information ///
	cout << "== Line information ==" << endl;
	cout << "#Lines = " << line_num << endl;
	for(int l = 1; l <= line_num; l++) {
		short int block1 = line_info[l][0][0];
		short int block2 = line_info[l][1][0];
		cout << "Line#" << l << ": ";
		cout << "Block#" << block1 << "(";
		for(int i = 1; i < 5; i++) {
			cout << (float)line_info[l][0][i] / 2;
			if(i != 4) { cout << ", "; }
		}
		cout << "), ";
		cout << "Block#" << block2 << "(";
		for(int i = 1; i < 5; i++) {
			cout << (float)line_info[l][1][i] / 2;
			if(i != 4) { cout << ", "; }
		}
		cout << ")" << endl;
	}
	/// Print line information ///
}

solver_python/io.hpp

0 → 100644
+17 −0
Changes for solver_python/io.hpp: 17 added lines, 0 removed lines.
Original line number Diff line number Diff line
#ifndef __IO_HPP__
#define __IO_HPP__

#include <iostream>
#include <sstream>   // for istringstream
#include <fstream>
#include <algorithm> // for replace

#include "param.hpp"

using namespace std;

void read_problem(const char *f_name, short int *W, short int *H, short int *blocks, short int *line_num, short int block_info[][5][3], short int line_info[][2][5]);
void extract_line_info(short int line_num, short int blocks, short int block_info[][5][3], short int line_info[][2][5]);


#endif /* __IO_HPP__ */

solver_python/main.cpp

0 → 100644
+105 −0
Changes for solver_python/main.cpp: 105 added lines, 0 removed lines.
Original line number Diff line number Diff line
#include <iostream>
#include <getopt.h>

#include "param.hpp"
#include "io.hpp"
#include "solver.hpp"
#include "tools.hpp"

using namespace std;

void usage() {
	cout << "Usage: ./sim.exe [--problem input-file] [--output output-file] [--seed seed-value]" << endl;
	exit(-1);
}

int main(int argc, char *argv[]) {
	
	char *p_filename = NULL;
	char *out_filename = NULL;
	uint32_t seed_v = 214;
	
	// Get options
	struct option longopts[] = {
		{"problem", required_argument, NULL, 'p'},
		{"output", required_argument, NULL, 'o'},
		{"seed", required_argument, NULL, 's'},
		{0, 0, 0, 0}
	};
	int opt, optidx;
	while((opt = getopt_long(argc, argv, "p:o:s:", longopts, &optidx)) != -1) {
		switch(opt) {
		case 'p':
			p_filename = optarg;
			break;
		case 'o':
			out_filename = optarg;
			break;
		case 's':
			sscanf(optarg, "%u", &seed_v);
			break;
		default:
			usage();
		}
	}
	
	// Init seed value
	uint32_t seed[3];
	srand(seed_v);
	seed[0] = rand();
	seed[1] = rand();
	seed[2] = rand();
	
	// W: Max width of a board (specified in a problem file)
	// H: Max height of a board (specified in a problem file)
	// blocks: # of blocks (specified in a problem file)
	short int W, H, blocks, line_num;
	// W_ext: Width of a current solution
	// H_ext: Height of a current solution
	short int W_ext, H_ext;
	
	// block data
	short int block_info[MAX_BLOCKS+1][5][3];
	
	// line data
	short int line_info[MAX_LINES+1][2][5];
	
	// An opt. result will be stored in the array
	short int opt_result[MAX_CELLS];
	
	// Check problem
	read_problem(p_filename, &W, &H, &blocks, &line_num, block_info, line_info);
	extract_line_info(line_num, blocks, block_info, line_info);
	
	// Solver body
	int status = solver(seed, W, H, blocks, line_num, block_info, line_info, &W_ext, &H_ext, opt_result);
	
	// Check answer
	if(status == 0) {
		cout << "Fail re-routing" << endl;
	}
	else {
		cout << "== Answer ==" << endl;
		cout << "SIZE " << W_ext << "X" << H_ext << endl;
		pair<short int,short int> block_place_basis[MAX_BLOCKS+1];
		for(int i = 1; i <= blocks; i++) {
			block_place_basis[i] = make_pair(block_info[i][0][0], block_info[i][0][1]);
		}
		show_result(line_num, blocks, W_ext, H_ext, opt_result, block_place_basis);
	}
	if(W_ext > W || H_ext > H) {
		cout << "Fail satisfying constraint T_T" << endl;
	}
	else {
		cout << "Satisfy constraint ^_^" << endl;
		if(out_filename == NULL) return 0;
		cout << "Output to " << out_filename << endl;
		pair<short int,short int> block_place_basis[MAX_BLOCKS+1];
		for(int i = 1; i <= blocks; i++) {
			block_place_basis[i] = make_pair(block_info[i][0][0], block_info[i][0][1]);
		}
		output_to_file(out_filename, line_num, blocks, W_ext, H_ext, opt_result, block_place_basis);
	}
	
	return 0;
}

solver_python/main.py

0 → 100644
+33 −0
Changes for solver_python/main.py: 33 added lines, 0 removed lines.
Original line number Diff line number Diff line
import numpy as np
from argparse import ArgumentParser
import mySolverModule

def commandParsing():
	parser = ArgumentParser()
	parser.add_argument('-p', '--problem', help='Problem file name', required=True) # Required
	parser.add_argument('-s', '--seed', help='seed value') # Option
	parser.add_argument('-o', '--output', help='Output file name') # Option
	args = vars(parser.parse_args())
	return args

def main(args):
	seed_v = 214
	if args['seed'] is not None: seed_v = int(args['seed'])
	seed = mySolverModule.seed_generator(seed_v) # ndarray
	info = mySolverModule.check_problem(args['problem']) # extract info (block, line, ...)

	ret = mySolverModule.solver(seed, info['W'][0], info['H'][0], info['blocks'][0], info['line_num'][0], info['block_info'], info['line_info'])
	
	if ret['status'][0] == 0: print('Fail re-routing')
	else: mySolverModule.show_result(ret['W_ext'][0], ret['H_ext'][0], info['blocks'][0], info['line_num'][0], ret['block_info'], ret['opt_result'])

	if ret['W_ext'][0] > info['W'][0] or ret['H_ext'][0] > info['H'][0]:
		print('Fail satisfying constraint T_T')
	else:
		print('Satisfy constraint ^_^')
		if args['output'] is not None: mySolverModule.output_to_file(args['output'], ret['W_ext'][0], ret['H_ext'][0], info['blocks'][0], info['line_num'][0], ret['block_info'], ret['opt_result'])

if __name__ == '__main__':

	args = commandParsing()
	main(args)
Loading