Commit 230bc3fe authored by Kento HASEGAWA's avatar Kento HASEGAWA
Browse files

Merge branch 'master' into adc2019-system

parents 346a70f7 ae0027ee
Loading
Loading
Loading
Loading
+8 −3
Changes for README.md: 8 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -17,9 +17,14 @@ make
# ToDo

* ブロックを詰める作業の精度向上(現状,右下にスペースが生まれるような結果になりやすい)
* 端点を含まないブロックへの対応
* 組み込みシステム(PYNQ)上での実行
* ソルバのハードウェア化
* ~~端点を含まないブロックへの対応~~
* ~~組み込みシステム(PYNQ)上での実行→Python3からsolverを呼び出すコードを開発~~
* Ubuntu上でソルバを動作させたときの実行時間計測(NotePC, PYNQ-Z1)
* ~~ソルバのハードウェア化~~
* ハードウェアを呼び出すためのwrapperコードを開発(現状jupyter上での実行)
* **ソルバの高速化**
* 求解途中であっても解を出力できるようにする
* **自作問題の作成**

# Update log
* 2019/08/09

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)
+84 −0
Changes for solver_python/README.md: 84 added lines, 0 removed lines.
Original line number Diff line number Diff line
# Environment
* PYNQ-Z1 (v2.4) (Release 2019_02_21)
* PYNQ Linux, based on Ubuntu 18.04
* Python 3.6.5

To confirm, 
```
cat REVISION
cat /etc/lsb-release
python3 --version
```

# Python solver based on C++ programs

C/C++ wrapper for python

[Reference]
* https://docs.python.org/ja/3/c-api/index.html
* https://cpp-learning.com/python_c_api_step1/ (勉強になる)
* https://cpp-learning.com/python_c_api_step2/ (勉強になる)
* http://codeit.blog.fc2.com/blog-entry-9.html (numpy)

## Setup

Check include file in `py_wrapper.hpp` & `solver.hpp` (python version)

```
#include "/usr/include/python3.6m/Python.h"
#include "/usr/include/python3.6m/numpy/arrayobject.h"
#include "/usr/include/python3.6m/numpy/arrayscalars.h"
```

If there exist no files in `/usr/include/python3.6m`, type commands as follows:

```
sudo apt-get install python3-dev
sudo apt-get install python3-numpy
```

Type command as follows:

```
sudo python3 setup.py install
```

To confirm, type `pip3 freeze`. `mySolverModule==1.0.0` will be listed.

[Uninstall]
```
sudo rm -rf build
sudo pip3 uninstall mySolverModule
```

## Run

```
python3 main.py -p input-Q-file(.txt) [-s seed-value] [-o output-A-file(.txt)]
```

# C++ solver

## Setup

```
make  # g++
```

or

```
make -f Makefile.arm  ## arm-linux-gnueabihf-g++
```

## Run

```
./sim -p input-Q-file(.txt) [-s seed-value] [-o output-A-file(.txt)]
```

# 実行時間比較

例題(sample_Q.txt),シード値デフォルト(214)

**TODO**
 No newline at end of file

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__ */
Loading