zoukankan      html  css  js  c++  java
  • 普林斯顿算法课Part2第二周作业_SeamCarving

    作业地址:http://coursera.cs.princeton.edu/algs4/assignments/seamCarving.html

    作业难点:

    1、如何获取图形的RGB属性?

      需要研习下Picture、Color类等,使用getRGB()、getRed()、getGreen()、getBlue()等函数;

    2、如何计算从顶端到底部的最低energy曲线(即最短路径)?

      使用课上讲的Dijkstra算法求解即可;

    3、是否将findHorizontalSeam和findVerticalSeam的方法合并?

      如果要合并,关键的问题在于将energy矩阵转置;

    容易扣分点:

    1、怎么确保对象内存使用在要求的内存范围内?

      不同于第一份的作业,第二部分的作业的数据结构没有显示给出。本次作业中,为了降低对象的内存使用情况,要尽量避免使用全局性的私有变量,因此部分函数的参数会变得很长;

    2、removeHorizontalSeam和removeVerticalSeam函数执行后对象未及时更新。

      要确保在两个函数的最后进行图像更新;

    部分代码:

    1、数据结构:

        private int[][] colorRGB;
        private int width;
        private int height;         
        private Picture picture;
        private static final double MAX_ENERGY = 1000.0;

    2、求解最短路径:

       private void DijkstraSP(boolean isVertical, double[][] energy, double[] distTo, int[] edgeTo) {
           int V = width * height;  
           for (int v = 0; v < V; v++) {
               distTo[v] = Double.POSITIVE_INFINITY;
               edgeTo[v] = 0;
           }
           int initLen = width;
           if (!isVertical) initLen = height;
           IndexMinPQ<Double> pq = new IndexMinPQ<Double>(V);       
           for (int v = 0; v < initLen; v++) {
               distTo[v] = MAX_ENERGY;
               pq.insert(v, distTo[v]);
           }
           boolean notFinStat = true;
           while (!pq.isEmpty() && notFinStat) { 
               relax(pq.delMin(), isVertical, energy, distTo, edgeTo, pq);           
               for (int i = V - 1; i > V - initLen; i--) 
                   if (distTo[i] != Double.POSITIVE_INFINITY) {
                       notFinStat = false;
                       break;
                   }
           }
       }   
       private void relax(int v, boolean isVertical, double[][] energy, double[] distTo, int[] edgeTo, IndexMinPQ<Double> pq) {
           int x, y, w;
           double weight;
           int seamWidth = width, seamHeight = height;  
           if (!isVertical) {
               seamWidth = height; 
               seamHeight = width;
           }
           x = v % seamWidth; 
           y = v / seamWidth;
           if (x == 0 || x == seamWidth -1 || y == seamHeight - 1) 
               return;    
           for (int delta = -1; delta < 2; delta++) {     
               w = (y+1) * seamWidth + (x + delta);
               weight = energy[x + delta][y + 1];      
               if (distTo[w] > distTo[v] + weight) {
                   distTo[w] = distTo[v] + weight;
                   edgeTo[w] = v;
                   if(y + 1 == seamHeight - 1) return;
                   if (pq.contains(w)) pq.changeKey(w, distTo[w]);
                   else pq.insert(w, distTo[w]);
               }
           }    
       }
    View Code

    3、求解顶端到底部的路径:

       private int[] findSeam(boolean isVertical, double[] distTo, int[] edgeTo) {
           int minIndex = 0;       
           double minDist = Double.POSITIVE_INFINITY;
           int seamWidth = width, seamHeight = height;
           if (!isVertical) {     
               seamWidth = height;
               seamHeight = width;
           }
           int[] seamPath = new int [seamHeight];
           for (int i = 0; i < seamWidth; i++)      
               if (distTo[(seamHeight - 1) * seamWidth + i] < minDist) {
               minIndex = (seamHeight - 1) * seamWidth + i;
               minDist = distTo[(seamHeight -1) * seamWidth + i];
           }    
           for (int i = seamHeight - 1; i > 0 ; i--) {
               seamPath[i] = minIndex % seamWidth;
               minIndex = edgeTo[minIndex];
           }
           if (seamPath.length > 1) seamPath[0] = seamPath[1];
           return seamPath;
       }   
    View Code

    4、energy转置:

       private double[][] energyTranspose(int W, int H, boolean isTranspose) {
           double[][] result = new double[W][H];
           for (int y = 0; y < H; y++)
               for (int x = 0; x < W; x++) {
               if (isTranspose) result[x][y] = energy(y, x);
               else result[x][y] = energy(x, y);
           }   
           return result;        
       }   
    View Code

    5、removeVerticalSeam():

       public void removeVerticalSeam(int[] seam) {
           if (seam.length != height || width <= 1) 
               throw new java.lang.IllegalArgumentException();
           checkSeam(seam, width);
           int[][] copy = new int[width-1][height];
           for (int y = 0; y < height; y++) {
               for (int x = 0; x < width; x++) {
                   if (x < seam[y]) copy[x][y] = colorRGB[x][y];
                   else if (x > seam[y]) copy[x-1][y] = colorRGB[x][y];
               }
           }
           width--;
           colorRGB = copy;  
           picture();
       } 
    View Code

      

  • 相关阅读:
    面向接口程序设计思想实践
    Block Chain Learning Notes
    ECMAScript 6.0
    Etcd Learning Notes
    Travis CI Build Continuous Integration
    Markdown Learning Notes
    SPRING MICROSERVICES IN ACTION
    Java Interview Questions Summary
    Node.js Learning Notes
    Apache Thrift Learning Notes
  • 原文地址:https://www.cnblogs.com/notTao/p/6357337.html
Copyright © 2011-2022 走看看