装B失败小记一则
2016-03-07 15:22
211 查看
abstract:
这是一只码狗企图用代码在朋友圈掀起一场腥风血雨的惨痛失败的小记。。。。。。。。。
这是一个阳光明媚的下午,我吃着火锅唱着歌,徜徉在我平静的朋友圈,突然,几行小字闪电般刺痛了我的狗眼,大概是这样式的:
![](http://img.blog.csdn.net/20160307151905231?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20160307151959091?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
作为这种无脑游戏的狂热爱好者,我怎!么!能!忍!装B也要按照基本法啊!
于是我:
①截图
②python脚本获取元素RGB
③取余求平均RGB,识别颜色,颜色矩阵转数组
④分支限界搜索最优解
有一大坑:图用python缩略后,RGB出现很多严重偏离的像素点,不知为何。就因为这,识别步骤花了很长时间。
搞出颜色数组,树搜索一跑,卒。
计算量太大了,采用的剪枝策略太naive,又想不出更高明策略,装B失败,还困的不行。。。。
颜色识别代码:
搜索代码:
这是一只码狗企图用代码在朋友圈掀起一场腥风血雨的惨痛失败的小记。。。。。。。。。
这是一个阳光明媚的下午,我吃着火锅唱着歌,徜徉在我平静的朋友圈,突然,几行小字闪电般刺痛了我的狗眼,大概是这样式的:
作为这种无脑游戏的狂热爱好者,我怎!么!能!忍!装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"); }
相关文章推荐
- jQuery对下拉框Select操作总结
- C语言深度剖析-----函数
- React Native-18.React Native 常用API及实践 NetINfo
- iOS开发--应用程序上线
- 对原型的个人理解
- 常用的正则表达式
- 关于android应用程序的入口
- Ios设计模式
- 10032---Node.js实战--欢迎进入Node.js世界
- 使用命令给APK进行签名
- 简单工厂模式
- 加载SD卡图片到Gallery与ImageSwitch使用详解
- boost 各个模块的功能
- iOS开发-- 开发细节(支付宝,微信支付支持库)
- MySQLdb模块操作
- Mac OS 装gdb
- Windows下gvim配置
- C#成魔之路<7>水晶报表与打印(挂起)
- 内部类——实现单例
- Qt之线程(QThread)