Package primarydatamanager

Source Code of primarydatamanager.DayProgramMapper

/*
* TV-Browser
* Copyright (C) 04-2003 Martin Oberhauser (darras@users.sourceforge.net)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*
* CVS information:
*  $RCSfile$
*   $Source$
*     $Date: 2007-08-19 20:59:54 +0200 (Sun, 19 Aug 2007) $
*   $Author: Bananeweizen $
* $Revision: 3618 $
*/
package primarydatamanager;

import java.util.ArrayList;

import tvbrowserdataservice.file.DayProgramFile;
import tvbrowserdataservice.file.ProgramField;
import tvbrowserdataservice.file.ProgramFrame;

/**
*
*
* @author Til Schneider, www.murfman.de
*/
public class DayProgramMapper {
 
 
 
  public DayProgramMapper() {
  }
 


  public void map(DayProgramFile rawFile, DayProgramFile lastCompleteFile)
    throws PreparationException
  {
    // NOTE: The mapping process works in two steps:
    //       1. At first all the exact matching programs are matched.
    //          In this step the most programs should be mapped.
    //       2. The remaining programs are matched to their best counterpart.
    //          This step is relatively slowly, which is the reason for step 1.
    //
    //       Warning: After this process there may still be programs that are
    //                not mapped! These programs must get a new ID.

    // First reset all IDs
    resetIDs(rawFile);
   
    // Create a list with all Programs that have not yet been assigned
    ArrayList<ProgramFrame> progList = new ArrayList<ProgramFrame>();
    for (int i = 0; i < lastCompleteFile.getProgramFrameCount(); i++) {
      progList.add(lastCompleteFile.getProgramFrameAt(i));
    }

    // Step 1:
    // Now check whether there is an exactly matching program in start time
    // and title
    mapExactMatches(rawFile, progList);
   
    // Put the unmapped programs in a list
    ArrayList<ProgramFrame> unmappedList = createUnmappedList(rawFile);
   
    if (unmappedList.isEmpty()) {
      // Nothing to do any more
      return;
    }
     
    // Step 2:
    // Match the most similar programs together
    mapSimilarMatches(progList, unmappedList);
  }
 
 
 
  private ArrayList<ProgramFrame> createUnmappedList(DayProgramFile file) {
    ArrayList<ProgramFrame> unmappedList = new ArrayList<ProgramFrame>();
    for (int i = 0; i < file.getProgramFrameCount(); i++) {
      ProgramFrame frame = file.getProgramFrameAt(i);
      if (frame.getId() == -1) {
        unmappedList.add(frame);
      }
    }
    return unmappedList;
  }



  private void resetIDs(DayProgramFile file) {
    for (int i = 0; i < file.getProgramFrameCount(); i++) {
      file.getProgramFrameAt(i).setId(-1);
    }
  }



  private void mapExactMatches(DayProgramFile rawFile, ArrayList<ProgramFrame> progList) throws PreparationException {
    for (int frameNr = 0; frameNr < rawFile.getProgramFrameCount(); frameNr++) {
      ProgramFrame rawFrame = rawFile.getProgramFrameAt(frameNr);
      int rawStarttime = PrimaryDataUtilities.getProgramStartTime(rawFrame);
      String rawTitle = PrimaryDataUtilities.getProgramTitle(rawFrame);
     
      for (int i = 0; i < progList.size(); i++) {
        ProgramFrame prepFrame = progList.get(i);
        int prepStarttime = PrimaryDataUtilities.getProgramStartTime(prepFrame);
        String prepTitle = PrimaryDataUtilities.getProgramTitle(prepFrame);
       
        if ((rawStarttime == prepStarttime) && rawTitle.equals(prepTitle)) {
          // This is a match -> map the program
          rawFrame.setId(prepFrame.getId());
          progList.remove(i);
          break;
        }
      }
    }
  }



  private void mapSimilarMatches(ArrayList<ProgramFrame> progList, ArrayList<ProgramFrame> unmappedList) {
    // NOTE: We work with a similarity matrix to find the best matches.
    //       This matrix works as follows: It contains for each raw program
    //       and each prepared program their similarity.
    // Example:
    //       Assumed we have four prepared programs and three raw programs
    //       the similarity matrix may look as follows:
    //          1 3 4 0
    //          2 9 1 3
    //          1 2 5 8
    //       Meaning that prepared program #2 and raw program #0 have a
    //       similarity of 4.
    //
    //       Now the best match is chosen. In this case [1,1] with a similarity
    //       of 9. These programs are mapped together. To avoid a second match
    //       the similarities of these programs is set to 0. After this the
    //       matrix looks like this:
    //            |
    //          1 0 4 0
    //        --0 0 0 0--
    //          1 0 5 8
    //            |
    //       This is made until the whole matrix is 0. In this case the
    //       following programs are mapped:
    //          [1,1] - similarity 9
    //          [3,2] - similarity 8  (The 5 is overwritten in this step)
    //          [2,0] - similarity 4.
    //       The raw program #0 does not get a match.
   
    // Compare each raw program with each prepared program and build a
    // similarity matrix
    double[][] similarity = new double[progList.size()][unmappedList.size()];
    for (int i = 0; i < progList.size(); i++) {
      ProgramFrame prepFrame = progList.get(i);
      for (int j = 0; j < unmappedList.size(); j++) {
        ProgramFrame rawFrame = unmappedList.get(j);
        similarity[i][j] = getSimilarity(prepFrame, rawFrame);
      }
    }
   
    // Use the similarity matrix to map all programs that are similar
    double maxSimilarity;
    do {
      // Find the programs that have the maximum similarity
      maxSimilarity = 0;
      int maxI = 0;
      int maxJ = 0;
     
      for (int i = 0; i < progList.size(); i++) {
        for (int j = 0; j < unmappedList.size(); j++) {
          if (similarity[i][j] > maxSimilarity) {
            // We have a new maximum
            maxSimilarity = similarity[i][j];
            maxI = i;
            maxJ = j;
          }
        }
      }
     
      // map the programs
      if (maxSimilarity > 0) {
        ProgramFrame prepFrame = progList.get(maxI);
        ProgramFrame rawFrame = unmappedList.get(maxJ);
        rawFrame.setId(prepFrame.getId());
       
        // Set the similarities of these programs to 0 to avoid a second match
        for (int i = 0; i < progList.size(); i++) {
          similarity[i][maxJ] = 0;
        }
        for (int j = 0; j < unmappedList.size(); j++) {
          similarity[maxI][j] = 0;
        }
      }
    } while (maxSimilarity != 0);
  }



  private double getSimilarity(ProgramFrame frame1, ProgramFrame frame2) {
    int comparedFieldCount = 0;
    int equalFieldCount = 0;
   
    for (int i = 0; i < frame1.getProgramFieldCount(); i++) {
      ProgramField field1 = frame1.getProgramFieldAt(i);
      // Get the corresponding field of frame2
      int field2Idx = frame2.getProgramFieldIndexForTypeId(field1.getTypeId());
      if (field2Idx != -1) {
        ProgramField field2 = frame2.getProgramFieldAt(field2Idx);
       
        // Compare the fields
        if (field1.equals(field2)) {
          equalFieldCount++;
        }
        comparedFieldCount++;
      }
    }
   
    if (comparedFieldCount == 0) {
      // Avoid division by zero
      return 0;
    } else {
      return (double) equalFieldCount / (double) comparedFieldCount;
    }
  }

}
TOP

Related Classes of primarydatamanager.DayProgramMapper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.