您的位置:首页 > 其它

装B失败小记一则

2016-03-07 15:22 211 查看
abstract:

这是一只码狗企图用代码在朋友圈掀起一场腥风血雨的惨痛失败的小记。。。。。。。。。

这是一个阳光明媚的下午,我吃着火锅唱着歌,徜徉在我平静的朋友圈,突然,几行小字闪电般刺痛了我的狗眼,大概是这样式的:





作为这种无脑游戏的狂热爱好者,我怎!么!能!忍!装B也要按照基本法啊!

于是我:

①截图

②python脚本获取元素RGB

③取余求平均RGB,识别颜色,颜色矩阵转数组

④分支限界搜索最优解

有一大坑:图用python缩略后,RGB出现很多严重偏离的像素点,不知为何。就因为这,识别步骤花了很长时间。

搞出颜色数组,树搜索一跑,卒。

计算量太大了,采用的剪枝策略太naive,又想不出更高明策略,装B失败,还困的不行。。。。

颜色识别代码:

# -*- coding: utf-8 -*-

import colorsys
import Image
import sys

def getDiff(colorRGB, r, g, b):
diff = 0;
diff = max(abs(colorRGB[0] - r), diff)
diff = max(abs(colorRGB[1] - g), diff)
diff = max(abs(colorRGB[2] - b), diff)
return diff

def getColorId(r, g, b):
dic = { "red":(275, 80, 80),
"orange":(241, 163, 13),
"green":(181, 207, 38),
"blue":(36, 168, 236),
"purple":(180, 80, 227)}
color_id = { "red":1, "orange":2, "green":3, "blue":4, "purple":5 }
min_diff = sys.maxint
result = -1
for color in dic:
diff = getDiff(dic[color], r, g, b)
if diff < min_diff:
#最小偏离值
result = color_id[color]
min_diff = diff
return result

def get_dominant_color(path):
board = [[0 for col in range(10)] for row in range(10)]
image = Image.open(path)
pix = image.load()

for i in range(0, 10):
n =16*2 + i*(345/10)*2
for j in range(0, 10):
m = 159*2 + j*(343/10)*2
count_r = 0
count_g = 0
count_b = 0
count =0
for aa in range(0,34*2):
for bb in range(0, 34*2):
r, g, b = pix[n+aa, m+bb]
if r+g+b<600:   #去除噪声
count += 1
count_r += r
count_g += g
count_b += b
color_id = getColorId(count_r/count, count_g/count, count_b/count)
board[j][i] = color_id
return board

if __name__=="__main__":

path = "C:\\Users\\go2sea\\Desktop\\test\\IMG_6131.PNG"
fp = open('file_color.txt','w')
board =  get_dominant_color(path)
print "{",
for ii in range(len(board)):
line = board[ii]
print "{ ",
for i in range(len(line)):
print line[i],
if i != len(line)-1:
print", ",
print "}",
if ii!=len(board)-1:
print","
print "};"
fp.close()


搜索代码:

#pragma once
#include <iostream>
#include <vector>
#include <cassert>
#include <algorithm>
#include <map>
#include <queue>
using namespace std;

//pq中优先级的比较
struct Compare {
//返回 block1优先级低于block2优先级
bool operator () (pair<vector<pair<int, int>>, pair<int, int>> pair1, pair<vector<pair<int, int>>, pair<int, int>> pair2) {
//return pair1.first.size() < pair2.first.size();
return pair1.first.size() > pair2.first.size();
}
};

void printBoard(vector<vector<int>>& board) {
for (int i = 0; i < board.size(); i++) {
for (int j = 0; j < board[0].size(); j++)
cout << board[i][j] << " ";
cout << endl;
}
cout << endl;
}

int maxPointsRest(vector<vector<int>>& board) {
map<int, int> m;
for (auto v : board)
for (auto c : v)
if (c > 0)
m[c]++;
int result = 0;
for (auto p : m)
if (p.second>1)
result += pow(p.second, 2);
return result;
}

//保证[i, j]位置不为0
vector<pair<int, int>> getBlock(vector<vector<int>> board, int i, int j) {
vector<pair<int, int>> block;//色块,初值只有一个格子[i,j]
block.push_back(pair<int, int>(i, j));
int color = board[i][j];//记录颜色
board[i][j] = 0;//现有block染黑
while (true) {
int size_before = block.size();
for (int m = 0; m < board.size(); m++){
for (int n = 0; n < board[0].size(); n++) {
if (board[m]
!= color)
continue;
for (auto p : block) {
int i = p.first, j = p.second;
if (abs(i - m) + abs(j - n) != 1)
continue;
block.push_back(pair<int, int>(m, n));
board[m]
= 0;	//染黑
break;
}
}
}
if (block.size() == size_before)
return block;
}

}

//将block中格子置0(染黑)
void setBlack(vector<vector<int>>& board, vector<pair<int, int>>& block) {
if (block.empty())
return;
int color = board[block[0].first][block[0].second];
for (auto p : block) {
assert(color == board[p.first][p.second]);
board[p.first][p.second] = 0;
}
}

//已染黑,落子(向左下角缩)
void shape(vector<vector<int>>& board) {
//每一列,从下往上,落到底,同时记录那一列为空
vector<bool> empty_column(board[0].size(), false);
for (int j = 0; j < board[0].size(); j++) {
int slow = board.size() - 1;
while (slow >= 0 && board[slow][j] != 0)	//寻找第一个空格子
slow--;
int fast = slow - 1;
while (fast >= 0) {
if (!board[fast][j]) {
fast--;
continue;
}
board[slow--][j] = board[fast][j];
board[fast--][j] = 0;
}
empty_column[j] = (slow == board.size() - 1);	//该列是否为空
}
//从左边第一个空列开始,他右面的落到相应位置,只需一次遍历即可
int slow = 0;
while (slow < board[0].size() && !empty_column[slow])	//寻找第一个空列
slow++;
int fast = slow + 1;
while (fast < board[0].size()) {
if (empty_column[fast]) {
fast++;
continue;
}
//fast列拷贝到slow列
for (int index = 0; index < board.size(); index++)
board[index][slow] = board[index][fast], board[index][fast] = 0;
slow++, fast++;
}
}

//设置flag,表示某位置已划入某一block,不再对其getBlock操作
void setFlag(vector<vector<int>>& board_flag, vector<pair<int, int>>& block) {
for (auto p : block) {
assert(board_flag[p.first][p.second] == 0);
board_flag[p.first][p.second] = 1;
}
}

//保证i,j可点,即getBlock(board, i, j)返回的block大小总>1(注意,now_path已经包含了生成该block所点击的[i, j]
void pointAt(vector<vector<int>> board, vector<pair<int, int>> block, int& max_score, int now_score, vector<pair<int, int>>& min_path, vector<pair<int, int>> now_path) {
setBlack(board, block);
shape(board);
now_score += pow(block.size(), 2);
//剪枝
if (maxPointsRest(board) + now_score <= max_score)
return;
bool end_status = true;
//找所有的block,放入pq中
priority_queue<pair<vector<pair<int, int>>, pair<int, int>>, vector < pair<vector<pair<int, int>>, pair<int, int>> >, Compare> pq;
vector<vector<int>> board_flag(board.size(), vector<int>(board[0].size(), 0));	//某位置为1表示已划分入某个block,不再对其getBlock
for (int i = 0; i < board.size(); i++) {
for (int j = 0; j < board[0].size(); j++) {
if (board_flag[i][j] == 1 || board[i][j] == 0)
continue;
block = getBlock(board, i, j);
if (block.size() == 1)	continue;
pq.push(pair<vector<pair<int, int>>, pair<int, int>>(block, pair<int, int>(i, j)));
setFlag(board_flag, block);
end_status = false;
}
}
while (!pq.empty()) {
block = pq.top().first;
pair<int, int> location = pq.top().second;
pq.pop();
now_path.push_back(location);
pointAt(board, block, max_score, now_score, min_path, now_path);
}
if (end_status && now_score > max_score)
max_score = now_score, min_path = now_path;
}

void search(vector<vector<int>> board) {
int max_score = 0;
vector<pair<int, int>> min_path;
vector<pair<int, int>> now_path;
vector<pair<int, int>> block;
pointAt(board, block, max_score, 0, min_path, now_path);

cout << "min_path:" << endl;
for (auto p : min_path)
cout << "[" << p.first << ", " << p.second << "]	" << endl;
cout << "max_score:	" << max_score << endl;
}

void main() {

//vector<vector<int>> board =
//{ { 4, 3, 3, 4, 4, 1, 2, 5, 2, 5 },
//{ 5, 3, 1, 2, 1, 4, 1, 1, 2, 5 },
//{ 3, 1, 1, 2, 2, 3, 1, 1, 4, 5 },
//{ 3, 1, 1, 3, 3, 4, 3, 3, 4, 5 },
//{ 3, 1, 3, 1, 4, 3, 1, 3, 4, 4 },
//{ 1, 4, 2, 4, 4, 3, 5, 4, 1, 4 },
//{ 1, 2, 4, 2, 4, 4, 3, 3, 1, 1 },
//{ 4, 2, 4, 4, 4, 4, 3, 2, 1, 2 },
//{ 4, 3, 3, 4, 4, 4, 3, 2, 1, 2 },
//{ 4, 3, 4, 4, 3, 4, 3, 2, 1, 2 } };

//vector<vector<int>> board = { { 1, 3, 4, 1, 2, 4, 3, 1, 1, 3 },
//{ 1, 3, 5, 1, 1, 4, 3, 1, 1, 4 },
//{ 2, 5, 1, 1, 1, 3, 3, 5, 1, 4 },
//{ 1, 3, 1, 4, 3, 4, 3, 1, 4, 2 },
//{ 3, 3, 1, 5, 3, 1, 3, 1, 4, 2 },
//{ 3, 4, 2, 5, 1, 2, 4, 4, 4, 3 },
//{ 3, 3, 2, 1, 1, 2, 2, 4, 3, 3 },
//{ 3, 1, 2, 1, 3, 3, 4, 3, 5, 4 },
//{ 4, 2, 3, 1, 4, 3, 1, 3, 2, 4 },
//{ 4, 4, 1, 5, 4, 3, 4, 1, 2, 4 } };

//vector<vector<int>> board = { { 1, 3, 4, 1, 2, 4 },
//{ 1, 3, 5, 1, 1, 4 },
//{ 2, 5, 1, 1, 1, 3 },
//{ 1, 3, 1, 4, 3, 4 },
//{ 3, 3, 1, 5, 3, 1},
//{ 3, 4, 2, 5, 1, 2} };

//vector<vector<int>> board = { { 1, 3, 4, 1},
//{ 1, 3, 5, 1},
//{ 2, 5, 1, 1},
//{ 1, 3, 1, 4} };

vector<vector<int>> board = { { 1, 3, 4, 1, 2 },
{ 1, 3, 5, 1, 1 },
{ 2, 5, 1, 1, 1 },
{ 1, 3, 1, 4, 3 },
{ 3, 3, 1, 5, 3 } };

search(board);
system("pause");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: