Connected Component Labeling - Implementation - algorithm
I have asked a similar question some days ago, but I have yet to find an efficient way of solving my problem.
I'm developing a simple console game, and I have a 2D array like this:
1,0,0,0,1
1,1,0,1,1
0,1,0,0,1
1,1,1,1,0
0,0,0,1,0
I am trying to find all the areas that consist of neighboring 1's (4-way connectivity). So, in this example the 2 areas are as following:
1
1,1
1
1,1,1,1
1
and :
1
1,1
1
The algorithm, that I've been working on, finds all the neighbors of the neighbors of a cell and works perfectly fine on this kind of matrices. However, when I use bigger arrays (like 90*90) the program is very slow and sometimes the huge arrays that are used cause stack overflows.
One guy on my other question told me about connected-component labelling as an efficient solution to my problem.
Can somebody show me any C++ code which uses this algorithm, because I'm kinda confused about how it actually works along with this disjoint-set data structure thing...
Thanks a lot for your help and time.
I'll first give you the code and then explain it a bit:
// direction vectors
const int dx[] = {+1, 0, -1, 0};
const int dy[] = {0, +1, 0, -1};
// matrix dimensions
int row_count;
int col_count;
// the input matrix
int m[MAX][MAX];
// the labels, 0 means unlabeled
int label[MAX][MAX];
void dfs(int x, int y, int current_label) {
if (x < 0 || x == row_count) return; // out of bounds
if (y < 0 || y == col_count) return; // out of bounds
if (label[x][y] || !m[x][y]) return; // already labeled or not marked with 1 in m
// mark the current cell
label[x][y] = current_label;
// recursively mark the neighbors
for (int direction = 0; direction < 4; ++direction)
dfs(x + dx[direction], y + dy[direction], current_label);
}
void find_components() {
int component = 0;
for (int i = 0; i < row_count; ++i)
for (int j = 0; j < col_count; ++j)
if (!label[i][j] && m[i][j]) dfs(i, j, ++component);
}
This is a common way of solving this problem.
The direction vectors are just a nice way to find the neighboring cells (in each of the four directions).
The dfs function performs a depth-first-search of the grid. That simply means it will visit all the cells reachable from the starting cell. Each cell will be marked with current_label
The find_components function goes through all the cells of the grid and starts a component labeling if it finds an unlabeled cell (marked with 1).
This can also be done iteratively using a stack.
If you replace the stack with a queue, you obtain the bfs or breadth-first-search.
This can be solved with union find (although DFS, as shown in the other answer, is probably a bit simpler).
The basic idea behind this data structure is to repeatedly merge elements in the same component. This is done by representing each component as a tree (with nodes keeping track of their own parent, instead of the other way around), you can check whether 2 elements are in the same component by traversing to the root node and you can merge nodes by simply making the one root the parent of the other root.
A short code sample demonstrating this:
const int w = 5, h = 5;
int input[w][h] = {{1,0,0,0,1},
{1,1,0,1,1},
{0,1,0,0,1},
{1,1,1,1,0},
{0,0,0,1,0}};
int component[w*h];
void doUnion(int a, int b)
{
// get the root component of a and b, and set the one's parent to the other
while (component[a] != a)
a = component[a];
while (component[b] != b)
b = component[b];
component[b] = a;
}
void unionCoords(int x, int y, int x2, int y2)
{
if (y2 < h && x2 < w && input[x][y] && input[x2][y2])
doUnion(x*h + y, x2*h + y2);
}
int main()
{
for (int i = 0; i < w*h; i++)
component[i] = i;
for (int x = 0; x < w; x++)
for (int y = 0; y < h; y++)
{
unionCoords(x, y, x+1, y);
unionCoords(x, y, x, y+1);
}
// print the array
for (int x = 0; x < w; x++)
{
for (int y = 0; y < h; y++)
{
if (input[x][y] == 0)
{
cout << ' ';
continue;
}
int c = x*h + y;
while (component[c] != c) c = component[c];
cout << (char)('a'+c);
}
cout << "\n";
}
}
Live demo.
The above will show each group of ones using a different letter of the alphabet.
p i
pp ii
p i
pppp
p
It should be easy to modify this to get the components separately or get a list of elements corresponding to each component. One idea is to replace cout << (char)('a'+c); above with componentMap[c].add(Point(x,y)) with componentMap being a map<int, list<Point>> - each entry in this map will then correspond to a component and give a list of points.
There are various optimisations to improve the efficiency of union find, the above is just a basic implementation.
You could also try this transitive closure approach, however the triple loop for the transitive closure slows things up when there are many separated objects in the image, suggested code changes welcome
Cheers
Dave
void CC(unsigned char* pBinImage, unsigned char* pOutImage, int width, int height, int CON8)
{
int i, j, x, y, k, maxIndX, maxIndY, sum, ct, newLabel=1, count, maxVal=0, sumVal=0, maxEQ=10000;
int *eq=NULL, list[4];
int bAdd;
memcpy(pOutImage, pBinImage, width*height*sizeof(unsigned char));
unsigned char* equivalences=(unsigned char*) calloc(sizeof(unsigned char), maxEQ*maxEQ);
// modify labels this should be done with iterators to modify elements
// current column
for(j=0; j<height; j++)
{
// current row
for(i=0; i<width; i++)
{
if(pOutImage[i+j*width]>0)
{
count=0;
// go through blocks
list[0]=0;
list[1]=0;
list[2]=0;
list[3]=0;
if(j>0)
{
if((i>0))
{
if((pOutImage[(i-1)+(j-1)*width]>0) && (CON8 > 0))
list[count++]=pOutImage[(i-1)+(j-1)*width];
}
if(pOutImage[i+(j-1)*width]>0)
{
for(x=0, bAdd=true; x<count; x++)
{
if(pOutImage[i+(j-1)*width]==list[x])
bAdd=false;
}
if(bAdd)
list[count++]=pOutImage[i+(j-1)*width];
}
if(i<width-1)
{
if((pOutImage[(i+1)+(j-1)*width]>0) && (CON8 > 0))
{
for(x=0, bAdd=true; x<count; x++)
{
if(pOutImage[(i+1)+(j-1)*width]==list[x])
bAdd=false;
}
if(bAdd)
list[count++]=pOutImage[(i+1)+(j-1)*width];
}
}
}
if(i>0)
{
if(pOutImage[(i-1)+j*width]>0)
{
for(x=0, bAdd=true; x<count; x++)
{
if(pOutImage[(i-1)+j*width]==list[x])
bAdd=false;
}
if(bAdd)
list[count++]=pOutImage[(i-1)+j*width];
}
}
// has a neighbour label
if(count==0)
pOutImage[i+j*width]=newLabel++;
else
{
pOutImage[i+j*width]=list[0];
if(count>1)
{
// store equivalences in table
for(x=0; x<count; x++)
for(y=0; y<count; y++)
equivalences[list[x]+list[y]*maxEQ]=1;
}
}
}
}
}
// floyd-Warshall algorithm - transitive closure - slow though :-(
for(i=0; i<newLabel; i++)
for(j=0; j<newLabel; j++)
{
if(equivalences[i+j*maxEQ]>0)
{
for(k=0; k<newLabel; k++)
{
equivalences[k+j*maxEQ]= equivalences[k+j*maxEQ] || equivalences[k+i*maxEQ];
}
}
}
eq=(int*) calloc(sizeof(int), newLabel);
for(i=0; i<newLabel; i++)
for(j=0; j<newLabel; j++)
{
if(equivalences[i+j*maxEQ]>0)
{
eq[i]=j;
break;
}
}
free(equivalences);
// label image with equivalents
for(i=0; i<width*height; i++)
{
if(pOutImage[i]>0&&eq[pOutImage[i]]>0)
pOutImage[i]=eq[pOutImage[i]];
}
free(eq);
}
very useful Document => https://docs.google.com/file/d/0B8gQ5d6E54ZDM204VFVxMkNtYjg/edit
java application - open source - extract objects from image - connected componen labeling => https://drive.google.com/file/d/0B8gQ5d6E54ZDTVdsWE1ic2lpaHM/edit?usp=sharing
import java.util.ArrayList;
public class cclabeling
{
int neighbourindex;ArrayList<Integer> Temp;
ArrayList<ArrayList<Integer>> cc=new ArrayList<>();
public int[][][] cclabel(boolean[] Main,int w){
/* this method return array of arrays "xycc" each array contains
the x,y coordinates of pixels of one connected component
– Main => binary array of image
– w => width of image */
long start=System.nanoTime();
int len=Main.length;int id=0;
int[] dir={-w-1,-w,-w+1,-1,+1,+w-1,+w,+w+1};
for(int i=0;i<len;i+=1){
if(Main[i]){
Temp=new ArrayList<>();
Temp.add(i);
for(int x=0;x<Temp.size();x+=1){
id=Temp.get(x);
for(int u=0;u<8;u+=1){
neighbourindex=id+dir[u];
if(Main[neighbourindex]){
Temp.add(neighbourindex);
Main[neighbourindex]=false;
}
}
Main[id]=false;
}
cc.add(Temp);
}
}
int[][][] xycc=new int[cc.size()][][];
int x;int y;
for(int i=0;i<cc.size();i+=1){
xycc[i]=new int[cc.get(i).size()][2];
for(int v=0;v<cc.get(i).size();v+=1){
y=Math.round(cc.get(i).get(v)/w);
x=cc.get(i).get(v)-y*w;
xycc[i][v][0]=x;
xycc[i][v][1]=y;
}
}
long end=System.nanoTime();
long time=end-start;
System.out.println("Connected Component Labeling Time =>"+time/1000000+" milliseconds");
System.out.println("Number Of Shapes => "+xycc.length);
return xycc;
}
}
Please find below the sample code for connected component labeling . The code is written in JAVA
package addressextraction;
public class ConnectedComponentLabelling {
int[] dx={+1, 0, -1, 0};
int[] dy={0, +1, 0, -1};
int row_count=0;
int col_count=0;
int[][] m;
int[][] label;
public ConnectedComponentLabelling(int row_count,int col_count) {
this.row_count=row_count;
this.col_count=col_count;
m=new int[row_count][col_count];
label=new int[row_count][col_count];
}
void dfs(int x, int y, int current_label) {
if (x < 0 || x == row_count) return; // out of bounds
if (y < 0 || y == col_count) return; // out of bounds
if (label[x][y]!=0 || m[x][y]!=1) return; // already labeled or not marked with 1 in m
// mark the current cell
label[x][y] = current_label;
// System.out.println("****************************");
// recursively mark the neighbors
int direction = 0;
for (direction = 0; direction < 4; ++direction)
dfs(x + dx[direction], y + dy[direction], current_label);
}
void find_components() {
int component = 0;
for (int i = 0; i < row_count; ++i)
for (int j = 0; j < col_count; ++j)
if (label[i][j]==0 && m[i][j]==1) dfs(i, j, ++component);
}
public static void main(String[] args) {
ConnectedComponentLabelling l=new ConnectedComponentLabelling(4,4);
l.m[0][0]=0;
l.m[0][1]=0;
l.m[0][2]=0;
l.m[0][3]=0;
l.m[1][0]=0;
l.m[1][1]=1;
l.m[1][2]=0;
l.m[1][3]=0;
l.m[2][0]=0;
l.m[2][1]=0;
l.m[2][2]=0;
l.m[2][3]=0;
l.m[3][0]=0;
l.m[3][1]=1;
l.m[3][2]=0;
l.m[3][3]=0;
l.find_components();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
System.out.print(l.label[i][j]);
}
System.out.println("");
}
}
}
Related
Develop an algorithm
I participated in a programming competition at my University. I solved all the questions except this one. Now I am practicing this question to improve my skills. But I can't figure out the algorithm. If there is any algorithm existing please update me. Or any similar algorithm is present then please tell me I will change it according to this question. This is what I want to do. The First line of input is the distance between two points. After that, each subsequent line contains a pair of numbers indicating the length of cable and quantity of that cable. These cables are used to join the two points. Input is terminated by 0 0 Output: The output should contain a single integer representing the minimum number of joints possible to build the requested length of cableway. If no solution possible than print "No solution". Sample Input 444 16 2 3 2 2 2 30 3 50 10 45 12 8 12 0 0 Sample Output 10
Thanks guys. I found a solution from "Perfect subset Sum" problem and then made a few changes in it. Here's the code. #include <bits/stdc++.h> using namespace std; bool dp[100][100]; int sizeOfJoints = -1; void display(const vector<int>& v) { if (sizeOfJoints == -1) { sizeOfJoints = v.size() - 1; } else if (v.size()< sizeOfJoints) { sizeOfJoints = v.size() - 1; } } // A recursive function to print all subsets with the // help of dp[][]. Vector p[] stores current subset. void printSubsetsRec(int arr[], int i, int sum, vector<int>& p) { // If sum becomes 0 if (sum == 0) { display(p); return; } if(i<=0 || sum<0) return; // If given sum can be achieved after ignoring // current element. if (dp[i-1][sum]) { // Create a new vector to store path //vector<int> b = p; printSubsetsRec(arr, i-1, sum, p); } // If given sum can be achieved after considering // current element. if (sum >= arr[i-1] && dp[i-1][sum-arr[i-1]]) { p.push_back(arr[i-1]); printSubsetsRec(arr, i-1, sum-arr[i-1], p); p.pop_back(); } } // all subsets of arr[0..n-1] with sum 0. void printAllSubsets(int arr[], int n, int sum) { if (n == 0 || sum < 0) return; // If sum is 0, then answer is true for (int i = 0; i <= n; i++) dp[i][0] = true; // If sum is not 0 and set is empty, then answer is false for (int i = 1; i <= sum; i++) dp[0][i] = false; // Fill the subset table in botton up manner for (int i = 1; i <= n; i++) { for (int j = 1; j <= sum; j++) { if(j<arr[i-1]) dp[i][j] = dp[i-1][j]; if (j >= arr[i-1]) dp[i][j] = dp[i-1][j] || dp[i - 1][j-arr[i-1]]; } } if (dp[n][sum] == false) { return; } // Now recursively traverse dp[][] to find all // paths from dp[n-1][sum] vector<int> p; printSubsetsRec(arr, n, sum, p); } // Driver code int main() { int input[2000]; int inputIndex = 0; int i = 0; int distance = 0; cout<< "Enter Input: " <<endl; cin>> distance; while(true) { int temp1 = 0; int temp2 = 0; cin>> temp1; cin>> temp2; if (temp1 == 0 && temp2 == 0) { break; } for (i = 0; i < temp2; i++) input[inputIndex++] = temp1; } cout<< "Processing output. Please wait: " <<endl; printAllSubsets(input, inputIndex, distance); if(sizeOfJoints != -1) cout<<sizeOfJoints; else cout<<"No Solution Possible"; return 0; }
How to find the number of blobs in a 2d matrix?
How can I find the number of blobs in a 2d matrix? SIZE MxN A blob is a block of continuous X pixels. where the matrix contains X and O XOOOXO OXOXOX XXOOXO I would like to use 8-neighbourship (see here). So I would expect 2 blobs to be found in above example.
The idea is simple: Mark each continuous blob and count how many blobs were marked. Here is some pseudo-code (you did not specify a programming language) to get you started: numBlobs = 0; foreach(item in matrix) { res = Visit(item); if(res > 0) { numBlobs = numBlobs + 1; } } return numBlobs; The Visit function/method looks like this: Visit(item) { marked = 0; if(item.IsX() && !IsItemMarked(neighbour)) { MarkItemAsVisited(item); marked = 1; foreach(neighbour in GetNeighbours(item)) { marked = marked + Visit(neighbour); } } return marked; } All you have to do is to implement the other fucntions/methods but they are pretty straightforward.
public static void main(String[] args) { int[][] matrix = new int[6][5]; System.out.println(matrix.length); for (int i=0; i < matrix.length; i++) { for (int j=0; j < matrix[i].length; j++) { matrix[i][j] = 0; } } matrix[0][3] = 1; matrix[1][1] = 1; matrix[1][3] = 1; matrix[2][1] = 1; matrix[2][2] = 1; matrix[2][3] = 1; matrix[4][0] = 1; matrix[4][4] = 1; matrix[5][2] = 1; matrix[5][3] = 1; matrix[5][4] = 1; System.out.println(findBlobCount(matrix, matrix.length, matrix[0].length)); } static int findBlobCount (int matrix[][], int rowCount, int colCount) { int visited[][] = new int[rowCount][colCount]; // all initialized to false int count=0; for (int i=0; i<rowCount; i++) { for (int j=0; j<colCount; j++) { if (matrix[i][j] == 1 && visited[i][j] == 0) // unvisited black cell { markVisited (i,j, matrix, visited, rowCount, colCount); count++; } } } return count; } static int markVisited (int i, int j, int [][]matrix, int [][]visited, int rowCount, int colCount) { if (i < 0 || j < 0) return 0; if (i >= rowCount || j >= colCount) return 0; if (visited[i][j] == 1) // already visited return 1; if (matrix[i][j] == 0) // not a black cell return 0; visited[i][j] = 1; // recursively mark all the 4 adjacent cells - right, left, up and down return markVisited (i+1, j, matrix, visited, rowCount, colCount) + markVisited (i-1, j, matrix, visited, rowCount, colCount) + markVisited (i, j+1, matrix, visited, rowCount, colCount) + markVisited (i, j-1, matrix, visited, rowCount, colCount); }
How is the FlowerGarden pr0blem on TopCoder a DP-one?
I'm reading this excellent tutorial by Dumitru on DP based problems here. And I'm trying to come up with a DP based approach for the FlowerGarden problem mentioned in the list of 1D DP problems. I can only think of a non-DP solution that would involve initially sorting the flowers in an order and then reordering them based on different condition checks mentioned in the problem. That doesn't classify as DP, does it? The editorial also doesn't mention anything about DP. Could anyone, by any chance, point me to a proper DP-based solution to this problem? Thanks! Edit: I didn't realize the link would require registration. This is the problem: Problem Statement You are planting a flower garden with bulbs to give you joyous flowers throughout the year. However, you wish to plant the flowers such that they do not block other flowers while they are visible. You will be given a int[] height, a int[] bloom, and a int[] wilt. Each type of flower is represented by the element at the same index of height, bloom, and wilt. height represents how high each type of flower grows, bloom represents the morning that each type of flower springs from the ground, and wilt represents the evening that each type of flower shrivels up and dies. Each element in bloom and wilt will be a number between 1 and 365 inclusive, and wilt[i] will always be greater than bloom[i]. You must plant all of the flowers of the same type in a single row for appearance, and you also want to have the tallest flowers as far forward as possible. However, if a flower type is taller than another type, and both types can be out of the ground at the same time, the shorter flower must be planted in front of the taller flower to prevent blocking. A flower blooms in the morning, and wilts in the evening, so even if one flower is blooming on the same day another flower is wilting, one can block the other. You should return a int[] which contains the elements of height in the order you should plant your flowers to acheive the above goals. The front of the garden is represented by the first element in your return value, and is where you view the garden from. The elements of height will all be unique, so there will always be a well-defined ordering. Edit two: Example 1: height={5,4,3,2,1} bloom={1,1,1,1,1} wilt={365,365,365,365,365} Returns: { 1, 2, 3, 4, 5 } These flowers all bloom on January 1st and wilt on December 31st. Since they all may block each other, you must order them from shortest to tallest. Example 2: h={5,4,3,2,1} b={1,5,10,15,20} w={4,9,14,19,24} Returns: { 5, 4, 3, 2, 1 } The same set of flowers now bloom all at separate times. Since they will never block each other, you can order them from tallest to shortest to get the tallest ones as far forward as possible. Example 3: height={5,4,3,2,1} bloom={1,5,10,15,20} wilt={5,10,14,20,25} Returns: { 3, 4, 5, 1, 2 } The difference here is that the third type of flower wilts one day earlier than the blooming of the fourth flower. Therefore, we can put the flowers of height 3 first, then the flowers of height 4, then height 5, and finally the flowers of height 1 and 2. Note that we could have also ordered them with height 1 first, but this does not result in the maximum possible height being first in the garden.
It's not a dynamic programming problem. It's a greedy algorithm problem. This confused me too, since topcoder's own dynamic programming tutorial links to it as a practice problem in the “Elementary” section. Sort the flowers by height, shortest to tallest. Start with an empty list of rows. For each flower (shortest to tallest), find the forward-most place where you can insert that flower such that it blocks no flowers behind it. In Python: def getOrdering(height, bloom, wilt): flowers = zip(height, bloom, wilt) flowers.sort() def flowersOverlap(f1, f2): # Overlap if each blooms before the other wilts. return f2[1] <= f1[2] and f1[1] <= f2[2] rows = [ ] for flower in flowers: rowIndex = len(rows) # Start at the back and march forward as long as # `flower` wouldn't block any flowers behind it. while rowIndex > 0 and not flowersOverlap(flower, rows[rowIndex - 1]): rowIndex -= 1 rows[rowIndex:rowIndex] = [flower] return [flower[0] for flower in rows]
public int[] getOrdering(int[] height, int[] bloom, int[] wilt) { int[] optimal = new int[height.length]; int[] optimalBloom = new int[bloom.length]; int[] optimalWilt = new int[wilt.length]; // init state optimal[0] = height[0]; optimalBloom[0] = bloom[0]; optimalWilt[0] = wilt[0]; // run dynamic programming for(int i = 1; i < height.length; i ++) { int currHeight = height[i]; int currBloom = bloom[i]; int currWilt = wilt[i]; int offset = 0; // by default, type i is to be put to 1st row for(int j = 0; j < i; j ++) { if(currWilt >= optimalBloom[j] && currWilt <= optimalWilt[j] || currBloom >= optimalBloom[j] && currBloom <= optimalWilt[j] || currWilt >= optimalWilt[j] && currBloom <= optimalBloom[j]) { // life period overlap if(currHeight < optimal[j]) { // life overlap, and type i is shorter than type j offset = j; break; } else { offset = j + 1; // type i overlap with type j, and i is taller than j. Put i after j } } else { // not overlap with current if(currHeight < optimal[j]) { offset = j + 1; // type i not overlap with j, i is shorter than j, put i after j } // else keep offset as is considering offset is smaller than j } } // shift the types after offset for(int k = i - 1; k >= offset; k -- ) { optimal[k+1] = optimal[k]; optimalBloom[k+1] = optimalBloom[k]; optimalWilt[k+1] = optimalWilt[k]; } // update optimal optimal[offset] = currHeight; optimalBloom[offset] = currBloom; optimalWilt[offset] = currWilt; } return optimal; } This is my tested working code.
I'have been struggling with this exact question for a whole day, and also, i couldn't find any DP solution to it. Here is my greedy approach in java, similar to others already posted, the key point is to proceed under a height ordering. The reason is to avoid dealing with intermediate heights (referring to the already computed), given that a intermediate height can change the relative order of the previously computed ones. int[] height = new int[]{5, 3, 4}; int[] start = new int[]{1, 3, 1}; int[] end = new int[]{2, 4, 4}; System.out.println(Arrays.toString(new FlowerGarden().getOrdering(height, start, end))); This is the only optimal substructure I could find. But given that there is no overlapping among subproblems, this algorithm should not be considered DP but greedy. private static boolean intersects(final int[] starts, final int[] ends, int i1, int i2) { return !(ends[i1] < starts[i2] || ends[i2] < starts[i1]); } public int[] getOrdering(final int[] height, final int[] starts, final int[] ends) { PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>(new Comparator<Integer>() { public int compare(Integer i, Integer j) { return Integer.compare(height[i], height[j]); } } ); for (int i = 0; i < height.length; i++) { minHeap.add(i); } LinkedList<Integer> list = new LinkedList<Integer>(); while (minHeap.size() > 0) { Integer index = minHeap.poll(); int p = 1; int pos = 0; for (Integer i : list) { if (intersects(starts, ends, i, index)) { pos = p; } p++; } list.add(pos, index); } int[] ret = new int[height.length]; int j = 0; for (Integer i : list) { ret[j++] = height[i]; } return ret; } BTW, the DP solutions I have seen posted here fail for this example. Cheers
I tried to solve this problem too. The main idea of my approach is to build a tree where each child is overlaped at least once by its parent. For example, if we have three flower types of heigths 4,2 and 1 growing and dying on the same days, then, the resulting tree should be: On the other hand, if 4 and 2 and 4 and 1 live at the same time but 2 and 1 do not coexist then, the resulting tree should be: That will generate a tree which is consistent with the problem contraints. Nonetheless the problem statement also includes a cost function making some solutions better than others. ...you also want to have the flowers in rows which are more towards the front be as tall as possible. The way to project this preference into our tree is to order all "brothers" (all nodes sharing the same parent) from higher to lower. So 2 comes first than 1. I built this tree using the following code: #define INT_MOD(a,b) ((a<0)?(b+(a%b)):(a%b)) #define DIST(a,b) ((a-b>=0)?(a-b):(b-a)) //Prev: ForAll(i), bloom[i] < wilt[i] inline bool isOverlap(vector<int> & bloom, vector<int> & wilt, vector<int> & height, unsigned int idxPrev, unsigned int idxFollowing) { int f1A = bloom[idxPrev]; int f1B = wilt[idxPrev]; int f2A = bloom[idxFollowing]; int f2B = wilt[idxFollowing]; bool notIntersecting = f2A > f1B /* --[--]-(--)-- */ || f1A > f2B /* --(--)-[--]-- */ ; return height[idxPrev] > height[idxFollowing] && !notIntersecting; } class CPreference { public: static vector<int> * pHeight; static bool preference(int a, int b) { return (*pHeight)[a] > (*pHeight)[b]; } }; vector<int> * CPreference::pHeight = NULL; vector<int> getOrdering(vector<int> height, vector<int> bloom, vector<int> wilt) { int l = height.size(); vector<int> state = vector<int>(l, -1); /* Tree where each leave points to its parent. Being that parent the first flower type that is forced to be after (backwards) its children */ //This loop is the dynamic programming core. for(int i = 0; i < l; i++) for(int j = INT_MOD((i-1),l); j != i; j = INT_MOD((j-1),l)) { if(isOverlap(bloom, wilt, height, i, j) && (state[j] < 0 || DIST(height[j],height[i]) < DIST(height[j], height[state[j]]))) { state[j] = i; } } vector<vector<int> > groups; //Groups of indexes overlapped by the element at the same index for(int i = 0; i < l+1; i++) groups.push_back(vector<int>()); // (l+1) for no overlapped indexes group. for(int i = 0; i < l; i++) { int k = state[i]; if(k < 0) k = l; groups[k].push_back(i); } CPreference::pHeight = &height; for(vector<vector<int> >::iterator it = groups.begin(); it != groups.end(); it++) sort(it->begin(),it->end(), CPreference::preference); At this point, Each row (i) of groups contains, ordered from higher to lower, all flower types indexes that should be placed before the flower type of index i. One last step is needed, to flatten groups into an output vector. That is, to build a vector where each element is followed by either: Its parent on the tree. It next brother when sorted by height. That can be done by a depth visit of each node of group. I think that is the weak point of my solution. I had not so much time so I just made a naive recursive implementation: //PRE: each vector, v, in 'groups' is sorted using CPreference void flattenTree(vector<vector<int> > & groups, vector<int> & out, int currentIdx /*parent*/, int l) { int pIdx = currentIdx; if(pIdx < 0) pIdx = l; vector<int> & elements = groups[pIdx]; vector<int> ret; for(vector<int>::iterator it = elements.begin(); it != elements.end(); it++) { flattenTree(groups, out ,*it, l); } if(currentIdx>=0) out.push_back(currentIdx); } Which is used to completed getOrdering function: vector<int> getOrdering(vector<int> height, vector<int> bloom, vector<int> wilt) { int l = height.size(); vector<int> state = vector<int>(l, -1); /* Tree where each leave points to its parent. Being that parent the first flower type that is forced to be after (backwards) its children */ for(int i = 0; i < l; i++) for(int j = INT_MOD((i-1),l); j != i; j = INT_MOD((j-1),l)) { if(isOverlap(bloom, wilt, height, i, j) && (state[j] < 0 || DIST(height[j],height[i]) < DIST(height[j], height[state[j]]))) { state[j] = i; } } vector<vector<int> > groups; //Groups of indexes overlapped by the element at the same index for(int i = 0; i < l+1; i++) groups.push_back(vector<int>()); // (l+1) for no overlapped indexes group. for(int i = 0; i < l; i++) { int k = state[i]; if(k < 0) k = l; groups[k].push_back(i); } CPreference::pHeight = &height; for(vector<vector<int> >::iterator it = groups.begin(); it != groups.end(); it++) sort(it->begin(),it->end(), CPreference::preference); vector<int> ret; flattenTree(groups, ret, -1, l); for(unsigned int i = 0; i < ret.size(); i++) ret[i] = height[ret[i]]; return ret; } Please, let my know if you found a better solution or if know any way to improve mine.
package topcoders; import java.util.ArrayList; import java.util.List; public class FlowerGarden { public int[] getOrdering(int[] height, int[] bloom, int[] wilt) { int[] order = new int[height.length]; List<Integer> heightList = new ArrayList<Integer>(); for (int i = 0; i < height.length; i++) { heightList.add(height[i]); } heightList = quickSort(heightList); for (int i = 0; i < height.length; i++) { height[i] = heightList.get(i); } order = height; for (int i = 0; i < order.length; i++) { int j = 0; while (j < order.length - 1 && isBlocking(j + 1, j, order, bloom, wilt)) { int placeHolder = order[j]; order[j] = order[j + 1]; order[j + 1] = placeHolder; j++; } } return order; } public boolean isBlocking(int isBlocked, int isBlocking, int[] order, int[] bloom, int[] wilt) { if (order[isBlocking] > order[isBlocked] && bloom[isBlocked] <= wilt[isBlocking] && wilt[isBlocked] >= bloom[isBlocking]) { return true; } else { return false; } } public List<Integer> quickSort(List<Integer> array) { if (array.size() <= 1) { return array; } int pivotIndex = array.size() / 2; int pivot = array.get(pivotIndex); List<Integer> less = new ArrayList<Integer>(); List<Integer> greater = new ArrayList<Integer>(); int l = 0; int g = 0; for (int i = 0; i < array.size(); i++) { if (i == pivotIndex) { continue; } else if (array.get(i) >= pivot) { less.add(array.get(i)); } else { greater.add(array.get(i)); } } List<Integer> lessResult = quickSort(less); List<Integer> greaterResult = quickSort(greater); List<Integer> result = new ArrayList<Integer>(); result.addAll(lessResult); result.add(pivot); result.addAll(greaterResult); return result; } public static void main(String[] args) { int[] height = { 5, 4, 3, 2, 1 }; int[] bloom = { 1, 5, 10, 15, 20 }; int[] wilt = { 5, 10, 14, 20, 25 }; FlowerGarden g = new FlowerGarden(); List<Integer> arrayList = new ArrayList<Integer>(); int[] array = g.getOrdering(height, bloom, wilt); for (int i = 0; i < array.length; i++) { System.out.println(array[i]); } } }
A toplogical sort approach: #include<stdio.h> #include<stdlib.h> #include <vector> #include <queue> using namespace std; #define MAX_FLOWERS 50 struct flower { int id; int height; int bloom; int wilt; bool visited; int ind; }; struct flower_comp { bool operator()(const struct flower* lhs, const struct flower* rhs) const { return rhs->height > lhs->height; } }; inline bool overlap(const struct flower& a, const struct flower& b) { return !((a.bloom < b.bloom && a.wilt < b.bloom) || (a.bloom > b.bloom && a.bloom > b.wilt)); } void getOrdering(int height[], int bloom[], int wilt[], int size) { struct flower flowers[MAX_FLOWERS]; for(int i = 0; i < size; i++) { flowers[i].id = i; flowers[i].height = height[i]; flowers[i].bloom = bloom[i]; flowers[i].wilt = wilt[i]; flowers[i].visited = false; flowers[i].ind = 0; } bool partial_order[MAX_FLOWERS][MAX_FLOWERS] = {false}; for(int i = 0; i < size; i++) { for(int j = i + 1; j < size; j++) { if(overlap(flowers[i], flowers[j])) { if(flowers[i].height < flowers[j].height) { partial_order[i][j] = true; flowers[j].ind++; } else { partial_order[j][i] = true; flowers[i].ind++; } } } } priority_queue<struct flower*, vector<struct flower*>, flower_comp> pq; for(int i = 0; i < size; i++) { if(flowers[i].ind == 0) { pq.push(&flowers[i]); } } printf("{"); bool first = true; while(!pq.empty()) { struct flower* tmp = pq.top(); pq.pop(); tmp->visited = true; if(!first) { printf(","); } first = false; printf("%d", tmp->height); for(int j = 0; j < size; j++) { if(!flowers[j].visited && partial_order[tmp->id][j]) { flowers[j].ind--; if(flowers[j].ind == 0) { pq.push(&flowers[j]); } } } } printf("}\n"); } int main(int argc, char** argv) { int height[] = {5,4,3,2,1}; int bloom[] = {1,1,1,1,1}; int wilt[] = {365,365,365,365,365}; getOrdering(height, bloom, wilt, sizeof(height)/sizeof(height[0])); int height0[] = {5,4,3,2,1}; int bloom0[] = {1,5,10,15,20}; int wilt0[] = {4,9,14,19,24}; getOrdering(height0, bloom0, wilt0, sizeof(height0)/sizeof(height0[0])); int height1[] = {5,4,3,2,1}; int bloom1[] = {1,5,10,15,20}; int wilt1[] = {5,10,15,20,25}; getOrdering(height1, bloom1, wilt1, sizeof(height1)/sizeof(height1[0])); int height2[] = {5,4,3,2,1}; int bloom2[] = {1,5,10,15,20}; int wilt2[] = {5,10,14,20,25}; getOrdering(height2, bloom2, wilt2, sizeof(height2)/sizeof(height2[0])); int height3[] = {1,2,3,4,5,6}; int bloom3[] = {1,3,1,3,1,3}; int wilt3[] = {2,4,2,4,2,4}; getOrdering(height3, bloom3, wilt3, sizeof(height3)/sizeof(height3[0])); int height4[] = {3,2,5,4}; int bloom4[] = {1,2,11,10}; int wilt4[] = {4,3,12,13}; getOrdering(height4, bloom4, wilt4, sizeof(height4)/sizeof(height4[0])); }
Same thing as Rob's but in Javascript (ES6): function getOrdering(height, bloom, wilt) { var n = height.length; var idx = []; for (var i = 0; i < n; ++i) idx[i] = i; idx.sort( (a, b) => height[a] - height[b] ); var intersect = (a, b) => !(bloom[a] > wilt[b] || bloom[b] > wilt[a]); for (var i = 1; i < n; ++i) { // assume they are ordered correctly till index (i-1), // start moving flower i to the left until it can't move because of intersection var j = i, flw = idx[i]; while (j > 0 && !intersect(idx[j-1], flw)) { idx[j] = idx[j-1]; idx[--j] = flw; } } return idx.map( x => height[x] ); }
Similar to Rob, again in Python and slightly convoluted overlapping bloom/wilt check. H = 0 B = 1 W = 2 def getOrdering(heights, blooms, wilts): def _f1_after_f2(f1, f2): fs1 = set(range(f1[B], f1[W]+1)) fs2 = set(range(f2[B], f2[W]+1)) return f1[H] > f2[H] if fs2.intersection(fs1) != set([]) else False fs = zip(heights, blooms, wilts) fs.sort() ffs = [] for f1 in fs: insert_at = len(ffs) for f2 in reversed(ffs): if _f1_after_f2(f1, f2): break insert_at -= 1 ffs.insert(insert_at, f1) return [f[H] for f in ffs]
A graph algorithm to solve the problem: Create a directed graph(V,E): V -> flower types E -> relations between 2 flower types For all pairs (v_i, v_j) If v_i is smaller than v_j and v_j 'blocks' v_i draw an edge starting from v_i to v_j For all nodes v_i Find the v_i with no incoming edges and the biggest height -> write it at the end of the result list -> remove v_i and all of its outgoing edges from graph For more description checkout this forum: Topcoder Forum - FlowerGarden
Mine is like insertion sort. For each new flower, it goes from back to front and checks to see if the one in front of it blocks it; if it does, it means it must be placed behind it. Likewise, it also searches from front to back and checks to see if the one behind it blocks it; if it does, it means it must be placed in front of it. If there are no blocks, it simply checks for the best spot height-wise. #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <stdbool.h> #define uint32 uint32_t static void Swap(int *AIdx, int *BIdx) { int Tmp = *AIdx; *AIdx = *BIdx; *BIdx = Tmp; } static void SwapTo(int Start, int End, int *Array) { while(Start != End) { Swap(&Array[Start], &Array[Start - 1]); --Start; } } static void PrintTo(int End, int *Array) { for(int Idx = 0; Idx < End; ++Idx) { printf("%d, ", Array[Idx]); } printf("\n"); } /* Does A block B? */ static bool Blocks(int AIdx, int BIdx, int *Heights, int *Blooms, int *Wilts) { bool Result = (Heights[AIdx] > Heights[BIdx] && Wilts[AIdx] >= Blooms[BIdx] && Blooms[AIdx] <= Wilts[BIdx]); return Result; } static void Order(int *Heights, int *Blooms, int *Wilts, int FlowerCount) { for(int FlowerIdx = 1; FlowerIdx < FlowerCount; ++FlowerIdx) { PrintTo(FlowerIdx, Heights); /* front to back */ int MinIdx = -1; for(int Idx = 0; Idx < FlowerIdx; ++Idx) { if(Blocks(Idx, FlowerIdx, Heights, Blooms, Wilts)) { MinIdx = Idx; break; } } /* back to front */ int MaxIdx = -1; for(int Idx = (FlowerIdx - 1); Idx >= 0; --Idx) { if(Blocks(FlowerIdx, Idx, Heights, Blooms, Wilts)) { MaxIdx = (Idx + 1); break; } } /* best height index */ int BestHeightIdx = -1; if(MinIdx == -1 && MaxIdx == -1) { for(int Idx = 0; Idx < FlowerIdx; ++Idx) { if(Heights[FlowerIdx] > Heights[Idx]) { BestHeightIdx = Idx; break; } } if(BestHeightIdx == -1) { BestHeightIdx = FlowerIdx; } } int SwapToIdx = -1; if((MaxIdx == -1 && MinIdx != -1) || (MinIdx == -1 && MaxIdx != -1) || (MaxIdx != -1 && MinIdx != -1 && MaxIdx == MinIdx)) { SwapToIdx = (MinIdx != -1) ? MinIdx : MaxIdx; } else if(BestHeightIdx != -1) { SwapToIdx = BestHeightIdx; } else { fprintf(stderr, "Spot-finding error:\n MinIdx: %d, MaxIdx: %d, BestHIdx: %d\n", MinIdx, MaxIdx, BestHeightIdx); exit(1); } SwapTo(FlowerIdx, SwapToIdx, Heights); SwapTo(FlowerIdx, SwapToIdx, Blooms); SwapTo(FlowerIdx, SwapToIdx, Wilts); } } int main(int argc, char *argv[]) { int Heights0[] = {5,4,3,2,1}; int Blooms0[] = {1,1,1,1,1}; int Wilts0[] = {365,365,365,365,365}; int Heights1[] = {5,4,3,2,1}; int Blooms1[] = {1,5,10,15,20}; int Wilts1[] = {4,9,14,19,24}; int Heights2[] = {5,4,3,2,1}; int Blooms2[] = {1,5,10,15,20}; int Wilts2[] = {5,10,15,20,25}; int Heights3[] = {5,4,3,2,1}; int Blooms3[] = {1,5,10,15,20}; int Wilts3[] = {5,10,14,20,25}; int Heights4[] = {1,2,3,4,5,6}; int Blooms4[] = {1,3,1,3,1,3}; int Wilts4[] = {2,4,2,4,2,4}; int Heights5[] = {3,2,5,4}; int Blooms5[] = {1,2,11,10}; int Wilts5[] = {4,3,12,13}; int *AllHeights[] = {Heights0, Heights1, Heights2, Heights3, Heights4, Heights5}; int *AllBlooms[] = {Blooms0, Blooms1, Blooms2, Blooms3, Blooms4, Blooms5}; int *AllWilts[] = {Wilts0, Wilts1, Wilts2, Wilts3, Wilts4, Wilts5}; int AllFlowerCounts[] = {5, 5, 5, 5, 6, 4}; printf("\n"); for(int Idx = 0; Idx < 6; ++Idx) { int *Heights = AllHeights[Idx]; int *Blooms = AllBlooms[Idx]; int *Wilts = AllWilts[Idx]; int FlowerCount = AllFlowerCounts[Idx]; printf("Test %d\n", Idx); Order(Heights, Blooms, Wilts, FlowerCount); printf("{ "); for(int Idx = 0; Idx < FlowerCount; ++Idx) { printf("%d", Heights[Idx]); if(Idx != (FlowerCount - 1)) { printf(", "); } } printf(" }\n\n"); } } EDIT: This solution is god awful and I came up with a better one that's actually DP; it's as follows: for each flower, loop through all other flowers checking which ones it blocks; for those flowers it blocks, check for all the flowers it blocks, and so on until you get to a flower that doesn't block any other ones. Put that flower in a new array. Backtrack and put each flower before it in the next slot of that new array. If done for each flower, you will get an array full of flowers that don't block any others. You then put each flower as far forward as possible. The DP part of this solution is that sometimes you'll come across the same flower that has already been blocked by another flower previously and has already been put in the new array, so we skip that flower instead of chasing down the flowers it blocks.
I have got the implementation in c++. I have used a vector datatype to store the height, bloom and wilt respectively and then i sorted it w.r.t to height after which i took the flowers one by one and arranged them according to the values associated with them. here is the code :- #include<iostream> #include<vector> #include<utility> #include<algorithm> using namespace std; bool comp(pair<int, pair<int,int> >& a,pair<int, pair<int,int> >& b ){ return (a.first > b.first); } bool justify(pair<int, pair<int,int> >& a,pair<int, pair<int,int> >& b, int k , int j, vector<pair<int,pair<int,int> > >& v){ if(((b.second.first <= a.second.first) && (b.second.second>= a.second.first)) || ((b.second.first <= a.second.second) && (b.second.second>= a.second.second)) || ((b.second.first > a.second.first) && (b.second.second < a.second.second) )){ pair<int, pair<int,int> > temp = v[j]; int i = j-1; while(i >= k){ v[i+1] = v[i]; i--; } v[k] = temp; return true; } return false; } int main() { vector<pair<int,pair<int,int> > > v; int n,a,b,c; cin>>n; for(int i = 0;i < n;i++){ cin>>a>>b>>c; v.push_back(make_pair(a,make_pair(b,c))); } sort(v.begin(), v.end(), comp); for(int j = 1;j < n;j++){ for(int k = 0;k < j;k++){ bool res = justify(v[k],v[j], k, j, v); if(res) break; } } cout<<"output"<<endl; for(int i = 0;i < n;i++){ cout<<v[i].first<<" "<<v[i].second.first<<" "<<v[i].second.second<<endl; } return 0; }
Image rotation algorithm for a square pixel grid
I'm currently working on my own little online pixel editor. Now I'm trying to add a rotation function. But I can't quite figure out how to realize it. Here is the basic query for my pixel grid: for (var y = 0;y < pixelAmount;y++) { for (var x = 0;x < pixelAmount;x++) { var name = y + "x" + x; newY = ?? ; newX = ?? ; if ($(newY + "x" + newX).style.backgroundColor != "rgb(255, 255, 255)") { $(name).style.backgroundColor = $(newY + "x" + newX).style.backgroundColor; } } } How do I calculate newY and newX?
How do you rotate a two dimensional array? from this^ post I got this method (in c#): int a[4][4]; int n=4; int tmp; for (int i=0; i<n/2; i++){ for (int j=i; j<n-i-1; j++){ tmp=a[i][j]; a[i][j]=a[j][n-i-1]; a[j][n-i-1]=a[n-i-1][n-j-1]; a[n-i-1][n-j-1]=a[n-j-1][i]; a[n-j-1][i]=tmp; } } or this one: int[,] array = new int[4,4] { { 1,2,3,4 }, { 5,6,7,8 }, { 9,0,1,2 }, { 3,4,5,6 } }; int[,] rotated = RotateMatrix(array, 4); static int[,] RotateMatrix(int[,] matrix, int n) { int[,] ret = new int[n, n]; for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { ret[i, j] = matrix[n - j - 1, i]; } } return ret; } the first method doesn't use a second array (/matrix) to save memory..
Take a look at this doc (Section 3: Rotating a bitmap with an angle of any value). It walks you through how to do the math and gives you some sample code (C++, but it should be good enough for what you need).
If very quick performance is not of huge importance (which is the case by default), you can consider rotating the picture clockwise by flipping it against the main diagonal and then horizontally. To rotate counterclockwise, flip horizontally, then against the main diagonal. The code is much simpler. For diagonal flip you exchange the values of image[x,y] with image[y,x] in a loop like this for( var x = 0; x < pixelAmount; ++x ) for( var y = x + 1; y < pixelAmount; ++y ) swap(image[x,y],image[y,x]); For horizontal flip you do something like for( var y = 0; y < pixelAmount; ++y ) { i = 0; j = pixelAmount - 1; while( i < j ) { swap( image[i,y], image[j,y] ); ++i; --j; } }
cvDilate/cvErode: How to avoid connection between separated objects?
I would like to separate objects in OpenCv like the following image it shows: But if I am using cvDilate or cvErode the objects grow together... how to do that with OpenCv?
It looks like you will need to write your own dilate function and then add xor functionality yourself. Per the opencv documentation, here is the rule that cvdilate uses: dst=dilate(src,element): dst(x,y)=max((x',y') in element))src(x+x',y+y') Here is pseudocode for a starting point (this does not include xor code): void my_dilate(img) { for(i = 0; i < img.height; i++) { for(j = 0; j < img.width; j++) { max_pixel = get_max_pixel_in_window(img, i, j); img.pixel(i,j) = max_pixel; } } } int get_max_pixel_in_window(img, center_row, center_col) { int window_size = 3; int cur_max = 0; for(i = -window_size; i <= window_size; i++) { for(j = -window_size; j <= window_size; j++) { int cur_col = center_col + i; int cur_row = center_row + j; if(out_of_bounds(img, cur_col, cur_row)) { continue; } int cur_pix = img.pixel(center_row + i, center_col + j); if(cur_pix > cur_max) { cur_max = cur_pix; } } } return cur_max; } // returns true if the x, y coordinate is outside of the image int out_of_bounds(img, x, y) { if(x >= img.width || x < 0 || y >= img.height || y <= 0) { return 1; } return 0; }
As far as I know OpenCV does not have "dilation with XOR" (although that would be very nice to have). To get similar results you might try eroding (as in 'd'), and using the eroded centers as seeds for a Voronoi segmentation which you could then AND with the original image.
after erosion and dilate try thresholding the image to eliminate weak elements. Only strong regions should remain and thus improve the object separation. By the way could you be a little more clear about your problem with cvDilate or cvErode.