print out the shortest path in BFS in c++ - breadth-first-search

I came across a problem in a game described below. You are given an n by n matrix with 0 and 1. The only operation that you can do is to "press" one value in the matrix and the rows and columns associated with the value will flip. (including itself)
So for example, if we are given a 5 by 5 matrix.
1 0 1 0 1
0 1 1 1 0
1 0 0 1 1
0 0 0 1 1
1 1 1 0 0
"Pressing" the (1,1) position will yield a matrix
1 1 1 0 1
1 0 0 0 1
1 1 0 1 1
0 1 0 1 1
1 0 1 0 0
The goal is to reach all 0 with the least steps.
I used bfs in this case and I was able to get the least steps. However, what I want to print out is the position in the matrix that I am changing along the way. Any help will be appreciated. My current code is as follows.
void flip(int i, int j, std::vector<std::vector<int>>& adj)
{
int m = adj.size(), n = adj[0].size();
adj[i][j] ^= 1;
for (int row = 0; row < n; row++)
{
adj[i][row] ^= 1;
}
for (int col = 0; col < m; col++)
{
adj[col][j] ^= 1;
}
}
int minFlips(std::vector<std::vector<int>>& mat)
{
if (all_zero(mat))
{
return 0;
}
std::map<std::vector<std::vector<int>>, int> mp;
std::queue<std::vector<std::vector<int>>> q;
std::set<std::vector<std::vector<int>>> visited;
q.push(mat);
mp[mat] = 0;
visited.insert(mat);
while (!q.empty())
{
auto cur = q.front();
q.pop();
auto adj = cur;
for (int i = 0; i < adj.size(); i++)
{
for (int j = 0; j < adj[0].size(); j++)
{
flip(i, j, adj);
if (all_zero(adj))
{
return 1 + mp[cur];
}
if (visited.find(adj) == visited.end())
{
visited.insert(adj);
mp[adj] = 1 + mp[cur];
q.push(adj);
}
flip(i, j, adj);
}
}
}
return -1;
}

Related

How data map type find the value by the key?

I want to know. How did the Map type work when finding the value of a key?
Is this create an index like SQL?
Why these times are same as when I tried this code?
I don't have studied a programming class. Can someone explain in a simple way for me to understand?
import 'dart:math';
void main() {
int limit = 1000000;
Random random = new Random();
Map<String, int> map = {};
List<String> list = [];
for (int i = 0; i < limit; i++) {
String key = i.toString() + random.nextInt(limit).toString();
map[key] = i;
if (i == 0 ||
i == limit - 1 ||
i == limit / 2 ||
i == limit / 4 ||
i == limit / 10) {
list.add(key);
print("$key : $i");
}
}
for (var e in list) {
print("\n$e");
int time = DateTime.now().microsecondsSinceEpoch;
print(
"$e : ${map[e]} -> time = ${DateTime.now().microsecondsSinceEpoch - time}");
}
}
The result is:
0225402 : 0
100000478677 : 100000
250000355840 : 250000
50000052625 : 500000
999999681585 : 999999
0225402
0225402 : 0 -> time = 0
100000478677
100000478677 : 100000 -> time = 0
250000355840
250000355840 : 250000 -> time = 0
50000052625
50000052625 : 500000 -> time = 0
999999681585
999999681585 : 999999 -> time = 0

How can I convert this function into an array function?

So I have this function here that runs through T2:T:
=IF($D$29<$N2,"", AVERAGE(INDIRECT("P"&IF($N2<11, 2,$N2-5)&":P"&$N2+5)))
Column P is a list of numbers starting at row 2. Column N is an index(goes up by 1 each row) which starts at row 2 and ends where P ends + 14, and D29 is just a number. In my current situation P ends at row 11 and N ends at row 25. And I'm trying to change it into an array formula so that when I add new rows it updates automatically. So after changing it I got this:
=ARRAYFORMULA(IF($D$29<$N2:N,"", AVERAGE(INDIRECT("P"&IF($N2:N<11, 2,$N2:N-5)&":P"&$N2:N+5))))
However, it is not functioning properly. It still occupies the same amount of rows, but each row is the same value. The value of the first row originally. How can I fix this problem? Thanks!
The problem here is that ARRAYFORMULA doesn't work with AVERAGE.
But you could always use javascript.
Open up the script editor and paste in this code.
function avg(nums, d) {
var r = [],
i, j, start, end, avg, count;
for(i = 0; i < nums.length; i++) {
if(d <= i) r.push([""]);
else {
if(i < 10) start = 0;
else start = i - 5;
end = i + 4;
avg = 0, count = 0;
for(j = start; j <= end; j++) {
if(nums[j]) {
avg += nums[j][0];
count++;
}
}
r.push([avg / count]);
}
}
return r;
}
Save it, go back to your spreadsheet and put this formula in any cell =avg(P2:P11, D29)

Horn-Schunck optical flow implementation issue

I am trying to implement Horn-Schunck optical flow algorithm by NumPy and OpenCV
I use Horn-Schunck method on wiki and original paper
But my implementation fails on following simple example
Frame1:
[[ 0 0 0 0 0 0 0 0 0 0]
[ 0 255 255 0 0 0 0 0 0 0]
[ 0 255 255 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0]]
Frame2:
[[ 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 255 255 0 0 0 0 0]
[ 0 0 0 255 255 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0]]
This is just small white rectangle that moves by 2 pixels on frame2
My implementation produce following flow
U part of flow (I apply np.round to every part of flow. Original values is pretty the same):
[[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]
V part of flow:
[[ 0. 1. 0. -1. -0. 0. 0. 0. 0. 0.]
[-0. -0. 0. 0. 0. 0. 0. 0. 0. 0.]
[-0. -1. -0. 1. 0. 0. 0. 0. 0. 0.]
[-0. -0. -0. 0. 0. 0. 0. 0. 0. 0.]
[-0. -0. -0. 0. 0. 0. 0. 0. 0. 0.]]
It look like this flow is incorrect (Because if i move every pixel of frame2 in direction of corresponding flow component i never get frame1)
Also my implementation fails on real images
But if i move rectangle by 1 pixel right (or left or top or down) my implementation produce:
U part of flow:
[[1 1 1 .....]
[1 1 1 .....]
......
[1 1 1 .....]]
V part of flow:
[[0 0 0 .....]
[0 0 0 .....]
......
[0 0 0 .....]]
I suppose that this flow is correct because i can reconstruct frame 1 by following procedure
def translateBrute(img, u, v):
res = np.zeros_like(img)
u = np.round(u).astype(np.int)
v = np.round(v).astype(np.int)
for i in xrange(img.shape[0]):
for j in xrange(img.shape[1]):
res[i, j] = takePixel(img, i + v[i, j], j + u[i, j])
return res
where takePixel is simple function that returns pixel intensity if input coordinates lays inside of image or intensity on image border otherwise
This is my implementation
import cv2
import sys
import numpy as np
def takePixel(img, i, j):
i = i if i >= 0 else 0
j = j if j >= 0 else 0
i = i if i < img.shape[0] else img.shape[0] - 1
j = j if j < img.shape[1] else img.shape[1] - 1
return img[i, j]
#Numerical derivatives from original paper: http://people.csail.mit.edu/bkph/papers/Optical_Flow_OPT.pdf
def xDer(img1, img2):
res = np.zeros_like(img1)
for i in xrange(res.shape[0]):
for j in xrange(res.shape[1]):
sm = 0
sm += takePixel(img1, i, j + 1) - takePixel(img1, i, j)
sm += takePixel(img1, i + 1, j + 1) - takePixel(img1, i + 1, j)
sm += takePixel(img2, i, j + 1) - takePixel(img2, i, j)
sm += takePixel(img2, i + 1, j + 1) - takePixel(img2, i + 1, j)
sm /= 4.0
res[i, j] = sm
return res
def yDer(img1, img2):
res = np.zeros_like(img1)
for i in xrange(res.shape[0]):
for j in xrange(res.shape[1]):
sm = 0
sm += takePixel(img1, i + 1, j ) - takePixel(img1, i, j )
sm += takePixel(img1, i + 1, j + 1) - takePixel(img1, i, j + 1)
sm += takePixel(img2, i + 1, j ) - takePixel(img2, i, j )
sm += takePixel(img2, i + 1, j + 1) - takePixel(img2, i, j + 1)
sm /= 4.0
res[i, j] = sm
return res
def tDer(img, img2):
res = np.zeros_like(img)
for i in xrange(res.shape[0]):
for j in xrange(res.shape[1]):
sm = 0
for ii in xrange(i, i + 2):
for jj in xrange(j, j + 2):
sm += takePixel(img2, ii, jj) - takePixel(img, ii, jj)
sm /= 4.0
res[i, j] = sm
return res
averageKernel = np.array([[ 0.08333333, 0.16666667, 0.08333333],
[ 0.16666667, 0. , 0.16666667],
[ 0.08333333, 0.16666667, 0.08333333]], dtype=np.float32)
#average intensity around flow in point i,j. I use filter2D to improve performance.
def average(img):
return cv2.filter2D(img.astype(np.float32), -1, averageKernel)
def translateBrute(img, u, v):
res = np.zeros_like(img)
u = np.round(u).astype(np.int)
v = np.round(v).astype(np.int)
for i in xrange(img.shape[0]):
for j in xrange(img.shape[1]):
res[i, j] = takePixel(img, i + v[i, j], j + u[i, j])
return res
#Core of algorithm. Iterative scheme from wiki: https://en.wikipedia.org/wiki/Horn%E2%80%93Schunck_method#Mathematical_details
def hornShunckFlow(img1, img2, alpha):
img1 = img1.astype(np.float32)
img2 = img2.astype(np.float32)
Idx = xDer(img1, img2)
Idy = yDer(img1, img2)
Idt = tDer(img1, img2)
u = np.zeros_like(img1)
v = np.zeros_like(img1)
#100 iterations enough for small example
for iteration in xrange(100):
u0 = np.copy(u)
v0 = np.copy(v)
uAvg = average(u0)
vAvg = average(v0)
# '*', '+', '/' operations in numpy works component-wise
u = uAvg - 1.0/(alpha**2 + Idx**2 + Idy**2) * Idx * (Idx * uAvg + Idy * vAvg + Idt)
v = vAvg - 1.0/(alpha**2 + Idx**2 + Idy**2) * Idy * (Idx * uAvg + Idy * vAvg + Idt)
if iteration % 10 == 0:
print 'iteration', iteration, np.linalg.norm(u - u0) + np.linalg.norm(v - v0)
return u, v
if __name__ == '__main__':
img1c = cv2.imread(sys.argv[1])
img2c = cv2.imread(sys.argv[2])
img1g = cv2.cvtColor(img1c, cv2.COLOR_BGR2GRAY)
img2g = cv2.cvtColor(img2c, cv2.COLOR_BGR2GRAY)
u, v = hornShunckFlow(img1g, img2g, 0.1)
imgRes = translateBrute(img2g, u, v)
cv2.imwrite('res.png', imgRes)
print img1g
print translateBrute(img2g, u, v)
Optimization scheme are taken from wikipedia and numerical derivatives are taken from original paper.
Anyone have idea why my implementation produce incorrect flow?
I can provide any additional info if it necessary
PS Sorry for my poor english
UPD:
I implement Horn-Schunck cost function
def grad(img):
Idx = cv2.filter2D(img, -1, np.array([
[-1, -2, -1],
[ 0, 0, 0],
[ 1, 2, 1]], dtype=np.float32))
Idy = cv2.filter2D(img, -1, np.array([
[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]], dtype=np.float32))
return Idx, Idy
def hornShunckCost(Idx, Idy, Idt, u, v, alpha):
#return sum(sum(It**2))
udx, udy = grad(u)
vdx, vdy = grad(v)
return (sum(sum((Idx*u + Idy*v + Idt)**2)) +
(alpha**2)*(sum(sum(udx**2)) +
sum(sum(udy**2)) +
sum(sum(vdx**2)) +
sum(sum(vdy**2))
))
and check value of this function inside iterations
if iteration % 10 == 0:
print 'iter', iteration, np.linalg.norm(u - u0) + np.linalg.norm(v - v0)
print hornShunckCost(Idx, Idy, Idt, u, v, alpha)
If i use simple example with rectangle that has been moved by one pixel everything is ok: value of cost function decrease at every step.
But on example with rectangle that has been moved by two pixels value of cost function increase at every step.
This behaviour of algorithm is really strange
Maybe i choose incorrect way to calculate cost function.
I lost a fact that classic Horn-Schunck scheme uses linearized data term (I1(x, y) - I2(x + u(x, y), y + v(x, y))). This linearization make optimization easy but disallows large displacements
To handle big displacements there are next approach Pyramidal Horn-Schunck

Which is the best algorithm to provide moves to solve 15 puzzle? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
i am working to find the solution steps for a randomly generated "15 puzzle". So tell me which is the best algorithm to use to solve it fast. Provide me approach to do so.
I am making a tree of nodes containing 4*4 array and traversing through all the node which are not yet processed and when i get the solution i stop the iteration.
In viewcontroller i have some code as
- (IBAction)getSolution:(id)sender {
while (!appDelegate.isResultFound) {
TreeNode *node=[self nodeWithLowestCostAndUnproceessedInRootNode];
[node expandNodeToChilds];
//break;
}
NSLog(#"Result Found");
if([appDelegate.result isEqualToString:#""])
NSLog(#"No move required");
else
NSLog(#"%#",appDelegate.result);
}
-(TreeNode*)nodeWithLowestCostAndUnproceessedInRootNode{
TreeNode *node1;
int lowestCost=200;
for (TreeNode *node in appDelegate.treeNodes) {
if([node myHeuristicsFunction]<lowestCost&&node.isProcessed==NO){
node1=node;
lowestCost=[node.cost intValue];
}
}
return node1;}
and in node class i am expanding the node as (except the move used by the parent)
-(void)expandNodeToChilds{
[self checkMovesForEmptyPlace];
if(top.x>=0){
[self addPuzzleBoxToTreeBySwapingPoint:top withMove:#"Bottom"];
}
if(right.y<=3){
[self addPuzzleBoxToTreeBySwapingPoint:right withMove:#"Left"];
}
if(bottom.x<=3){
[self addPuzzleBoxToTreeBySwapingPoint:bottom withMove:#"Top"];
}
if(left.y>=0){
[self addPuzzleBoxToTreeBySwapingPoint:left withMove:#"Right"];
}
self.isProcessed=true;}
Currently i am using manhattan distance with A*, but not getting the result in significant time, app memory increases to 1GB and app crashes.
I am assuming that you are looking for the shortest way to reach the goal for this puzzle. You can use A* algorithm with the manhattan distance between the current board and the goal board as the cost function.
The following code in Java implements the algorithm. The function Solver takes as input N, the size of the NxN board and then the corresponding N*N numbers ranging from [0,N^2] giving the locations of the numbers in the 2d grid. It outputs the minimum number of moves that are required and the actual moves. 0 indicates the empty position in the puzzle.
import java.io.InputStreamReader;
import java.util.*;
class Solver{
private int N ;
private int minMoves ;
public static int[] correctRow;
public static int[] correctCol;
private class Node implements Comparable<Node>{
private Board board ;
private int moves ;
private Node prevNode ;
public Node(Board board,int moves,Node prev){
this.board = board ;
this.moves = moves ;
this.prevNode = prev ;
}
public int compareTo(Node that){
int thisPriority = this.moves+this.board.manhattan() ;
int thatPriority = that.moves+that.board.manhattan() ;
if(thisPriority<thatPriority){
return -1 ;
}else if(thisPriority>thatPriority){
return 1 ;
}else{
return 0 ;
}
}
}
private Node lastNode ;
private boolean solvable ;
public Solver(Board initial){
N = initial.dimension() ;
PriorityQueue<Node> pq = new PriorityQueue<Node>() ;
PriorityQueue<Node> pq2 = new PriorityQueue<Node>() ;
pq.add(new Node(initial,0,null)) ;
pq2.add(new Node(initial.twin(),0,null)) ;
while(true){
Node removed = pq.poll();
Node removed2 = pq2.poll();
if(removed.board.isGoal()){
minMoves = removed.moves ;
lastNode = removed ;
solvable = true ;
break ;
}
if(removed2.board.isGoal()){
minMoves = -1 ;
solvable = false ;
break ;
}
Iterable<Board> neighbors = removed.board.neighbors() ;
Iterable<Board> neighbors2 = removed2.board.neighbors() ;
for(Board board : neighbors){
if(removed.prevNode != null && removed.prevNode.board.equals(board) ){
continue ;
}
pq.add(new Node(board,removed.moves+1,removed)) ;
}
for(Board board : neighbors2){
if(removed2.prevNode != null && removed2.prevNode.board.equals(board) ){
continue ;
}
pq2.add(new Node(board,removed2.moves+1,removed2)) ;
}
}
}
public boolean isSolvable(){
return solvable ;
}
public int moves(){
return minMoves ;
}
public Iterable<Board> solution(){
if(!isSolvable()){
return null ;
}
Stack<Board> stack = new Stack<Board>() ;
Node node = lastNode ;
while(true){
if(node == null) break ;
Board board = node.board ;
node = node.prevNode ;
stack.push(board) ;
}
return stack ;
}
static void initCorrectRowsCols(int N){
correctRow = new int[N*N] ;
int z = 0 ;
for(int i = 0 ; i < N ; i++ ){
for(int j = 0 ; j < N ; j++ ){
correctRow[z++] = i ;
}
}
z = 0 ;
correctCol = new int[N*N] ;
for(int i = 0 ; i < N ; i++ ){
for(int j = 0 ; j < N ; j++ ){
correctCol[z++] = j ;
}
}
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
// create initial board from file
Scanner in = new Scanner(new InputStreamReader(System.in));
int N = in.nextInt();
initCorrectRowsCols(N);
int[][] blocks = new int[N][N];
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
blocks[i][j] = in.nextInt();
Board initial = new Board(blocks);
// solve the puzzle
Solver solver = new Solver(initial);
long end = System.currentTimeMillis();
System.out.println("time taken " + (end-start) + " milli seconds");
// print solution to standard output
if (!solver.isSolvable())
System.out.println("No solution possible");
else {
System.out.println("Minimum number of moves = " + solver.moves());
Stack<Board> stack = new Stack<Board>();
for (Board board : solver.solution())
stack.push(board);
while(!stack.isEmpty()){
System.out.println(stack.pop());
}
}
}
}
class Board{
private int[][] array ;
private int N ;
int emptyRow;
int emptyCol;
boolean reached;
int manhattan = 0;
public Board(int[][] blocks){
N = blocks.length ;
array = new int[N][N] ;
reached = true;
for(int i = 0 ; i < N ; i++ ){
for(int j = 0 ; j < N ; j++ ) {
array[i][j] = blocks[i][j] ;
if(array[i][j] == 0){
emptyRow = i;
emptyCol = j;
}
if(array[i][j] != N*i + j+1){
if(!(i==N-1 && j==N-1)){
reached = false;
}
}
int num = array[i][j] ;
if(num==0){
continue ;
}
int indManhattan = Math.abs(Solver.correctRow[num-1] - i)
+ Math.abs(Solver.correctCol[num-1]-j) ;
manhattan += indManhattan ;
}
}
}
public int dimension(){
return N ;
}
public int hamming(){
int outOfPlace = 0 ;
for(int i = 0 ; i < N ; i++ ) {
for(int j = 0 ; j < N ; j++ ){
if(i==N-1 && j==N-1) {
break ;
}
if(array[i][j] != i*N+j+1){
outOfPlace++ ;
}
}
}
return outOfPlace ;
}
public int manhattan(){
return manhattan ;
}
public boolean isGoal(){
return reached ;
}
public Board twin(){
int[][] newArray = new int[N][N] ;
for(int i = 0 ; i < N ; i++ ){
for(int j = 0 ; j < N ; j++ ){
newArray[i][j] = array[i][j] ;
}
}
for(int i = 0 ; i < 2 ; i++ ) {
if(newArray[i][0]==0 || newArray[i][5]==0){
continue ;
}
int temp = newArray[i][0] ;
newArray[i][0] = newArray[i][6] ;
newArray[i][7] = temp ;
break ;
}
return new Board(newArray) ;
}
public boolean equals(Object y){
if(y==this){
return true ;
}
if(y == null){
return false ;
}
if(y.getClass() != this.getClass()){
return false ;
}
Board that = (Board)y ;
if(that.array.length != this.array.length){
return false ;
}
for(int i = 0 ; i < N ; i++ ) {
for(int j = 0 ; j < N ; j++ ) {
if(that.array[i][j] != this.array[i][j] ){
return false ;
}
}
}
return true ;
}
public Iterable<Board> neighbors(){
Queue<Board> q = new ArrayDeque<Board>() ;
int firstIndex0 = 0 ;
int secondIndex0 = 0 ;
for(int i = 0 ; i < N ; i++ ){
for(int j = 0 ; j < N ; j++ ) {
if(array[i][j] == 0){
firstIndex0 = i ;
secondIndex0 = j ;
break ;
}
}
}
if(secondIndex0-1>-1){
int[][] newArr = getCopy() ;
exch(newArr,firstIndex0,secondIndex0,firstIndex0,secondIndex0-1) ;
q.add(new Board(newArr)) ;
}
if(secondIndex0+1<N){
int[][] newArr = getCopy() ;
exch(newArr,firstIndex0,secondIndex0,firstIndex0,secondIndex0+1) ;
q.add(new Board(newArr)) ;
}
if(firstIndex0-1>-1){
int[][] newArr = getCopy() ;
exch(newArr,firstIndex0,secondIndex0,firstIndex0-1,secondIndex0) ;
q.add(new Board(newArr)) ;
}
if(firstIndex0+1<N){
int[][] newArr = getCopy() ;
exch(newArr,firstIndex0,secondIndex0,firstIndex0+1,secondIndex0) ;
q.add(new Board(newArr)) ;
}
return q ;
}
private int[][] getCopy(){
int[][] copy = new int[N][N] ;
for(int i = 0 ; i < N ; i++ ) {
for(int j = 0 ; j < N ; j++ ){
copy[i][j] = array[i][j] ;
}
}
return copy ;
}
private void exch(int[][] arr, int firstIndex,int secIndex,int firstIndex2,int secIndex2){
int temp = arr[firstIndex][secIndex] ;
arr[firstIndex][secIndex] = arr[firstIndex2][secIndex2] ;
arr[firstIndex2][secIndex2] = temp ;
}
public String toString(){
StringBuilder s = new StringBuilder() ;
s.append(N + "\n") ;
for(int i = 0 ; i < N ; i++ ){
for(int j = 0 ; j < N ; j++ ) {
s.append(String.format("%4d",array[i][j])) ;
}
s.append("\n") ;
}
return s.toString() ;
}
}
So for the input
3
7 8 5
4 0 2
3 6 1
The algorithm generates the output
Minimum number of moves = 28
3
7 8 5
4 0 2
3 6 1
3
7 0 5
4 8 2
3 6 1
3
7 5 0
4 8 2
3 6 1
3
7 5 2
4 8 0
3 6 1
3
7 5 2
4 0 8
3 6 1
3
7 5 2
4 6 8
3 0 1
3
7 5 2
4 6 8
3 1 0
3
7 5 2
4 6 0
3 1 8
3
7 5 2
4 0 6
3 1 8
3
7 5 2
0 4 6
3 1 8
3
0 5 2
7 4 6
3 1 8
3
5 0 2
7 4 6
3 1 8
3
5 4 2
7 0 6
3 1 8
3
5 4 2
7 1 6
3 0 8
3
5 4 2
7 1 6
0 3 8
3
5 4 2
0 1 6
7 3 8
3
5 4 2
1 0 6
7 3 8
3
5 0 2
1 4 6
7 3 8
3
0 5 2
1 4 6
7 3 8
3
1 5 2
0 4 6
7 3 8
3
1 5 2
4 0 6
7 3 8
3
1 5 2
4 3 6
7 0 8
3
1 5 2
4 3 6
7 8 0
3
1 5 2
4 3 0
7 8 6
3
1 5 2
4 0 3
7 8 6
3
1 0 2
4 5 3
7 8 6
3
1 2 0
4 5 3
7 8 6
3
1 2 3
4 5 0
7 8 6
3
1 2 3
4 5 6
7 8 0
I would also like to mention that
Finding a shortest solution to an N-by-N slider puzzle is NP-Hard, so it's unlikely that an efficient solution exists.
If you are not looking for a shortest path solution but any solution that runs fast in the input then this paper describes an algorithm that guarantees to perform at most N^3 moves.
Thus although the solution I have given runs fast on most of the inputs, it may fail on other difficult inputs.
Also note that not all puzzles are solvable. For the puzzles that cannot be solved, the algorithm prints that the puzzle cannot be solved.
PS. The algorithm implemented above follows the guidelines of this programming assignment.

Opencv: how to create new matrix from existing matrix with some changes?

in OpenCV, I have a matrix like this: [3 4 2; 5 2 1; 6 7 9], that is with 3x3 size. Now I want to change it into 3x1 size, and be like this:
[3 4 2 5 2 1 6 7 9]. But this is not exactly what I want, my actual goal is to put zero before and after each value, at the same time repeat each value three times. So my goal matrix should be like this: [ 0 3 3 3 0 0 4 4 4 0 0 2 2 2 0 0 5 5 5 0 0 2 2 2 0 0 1 1 1 0 0 6 6 6 0 0 7 7 7 0 0 9 9 9 0 ]. I wrote the following code for this:
for ( int i = 0; i < 3; i ++ )
{
for ( int j = 0; j < 3; j ++ )
{
for ( int m = k + 1; m < m + 3; m ++ )
{
dstMat.col (m) = srcMat.at <int> ( i, j );
}
k = k + 5 ;
}
}
Is there any better way for doing is? Especially without "for" loop, it is really time confusing. Many thanks in advance.
You can use Mat::reshape to convert your 3x3 matrix to 3x1. This way you'll need one for loop instead of two, and it's an O(1) operation.
you can omit the next for loop by using ROI:
srcMat.reshape(0,1);
for (int i =0; i < 9; i++)
dstMat(cv::Range::all(), cv::Range(i*5+1, i*5+4)).setTo(srcMat.at<int>(i));
and that would be all.
You could start by calling reshape on your matrix to flatten it to one row/column. That would save you one of the for loops and make it slightly clearer.

Resources