Categories
不学无术

PAT所有题目的解答

PAT所有题目的解答参见:http://biaobiaoqi.me/tags/pat/

Categories
不学无术

[Java]计算组合

基本功不扎实,写了半天写出来。
输入:一个长度n数组,比如{0,1,3,5},以及m
输出:组合CNM
===============

/**
	 * 计算组合的
	 * @param input 输入的序号,如{0,1,2,3,5}
	 *
	 * @param m 抽取数量
	 * @return 输出为组合,比如{{0,1},{0,2},{1,2}}
	 */
	public static List ComputeCombines(int[] input, int m){
		List result = new ArrayList();
		for(int i=0; i prev_result = ComputeCombines(rest, m-1); //更细分的结果
			for(int[] results: prev_result){
				int[] temp = new int[results.length +1];
				System.arraycopy(results, 0, temp, 0, results.length);
				temp[temp.length-1] = currNumber;
				result.add(temp);
			}
		}
		return result;
	}
	/**
	 * 从输入序列中取出从index开始(不含)到末尾的元素
	 * @param input
	 * @param index
	 * @return 如果没得搞了返回null
	 */
	private static int[] getRest(int[] input, int index) {
		int result_size = input.length - index - 1;
		if(result_size <= 0)
			return null;
		int[] rest_array = new int[result_size];
		System.arraycopy(input, index +1, rest_array, 0, result_size);
		return rest_array;
	}
	public static void main(String[] args){
		///////////////
		//测试用
		int[] input = {0,1,2,3};
		List result = ComputeCombines(input, 2);
		for(int[] r : result){
			for(int entry : r){
				System.out.print(entry);
			}
			System.out.print("n");
		}
		///////////////
	}
Categories
不学无术

1006. Sign In and Sign Out (25)

At the beginning of every day, the first person who signs in the computer room will unlock the door, and the last one who signs out will lock the door. Given the records of signing in’s and out’s, you are supposed to find the ones who have unlocked and locked the door on that day.
Input Specification:
Each input file contains one test case. Each case contains the records for one day. The case starts with a positive integer M, which is the total number of records, followed by M lines, each in the format:

ID_number Sign_in_time Sign_out_time

where times are given in the format HH:MM:SS, and ID number is a string with no more than 15 characters.
Output Specification:
For each test case, output in one line the ID numbers of the persons who have unlocked and locked the door on that day. The two ID numbers must be separated by one space.
Note: It is guaranteed that the records are consistent. That is, the sign in time must be earlier than the sign out time for each person, and there are no two persons sign in or out at the same moment.
Sample Input:

3
CS301111 15:30:28 17:00:10
SC3021234 08:00:00 11:25:25
CS301133 21:45:00 21:58:40

Sample Output:

SC3021234 CS301133

========================
没什么技术含量,直接贴代码~!
========================

#include 
#include 
#include 
using namespace std;
int compare(int left[], int right[])
{
    //比较两个时间的大小,left比right: 早返回-1, 相等返回0, 晚返回1
    if(left[0] > right[0])
        return 1;
    else if(left[0] < right[0])
        return -1;
    else
    {
        if(left[1] > right[1])
            return 1;
        else if(left[1] < right[1])
            return -1;
        else
        {
            if(left[2] > right[2])
                return 1;
            else if(left[2] < right[2])
                return -1;
            return 0;
        }
    }
}
int main()
{
    int sign_in_time[3] = {23, 59, 59};  //hh,mm,ss
    int sign_out_time[3] = {0, 0, 0};
    char sign_in_user[15]; //最早登入的
    char sign_out_user[15]; //最迟登出的
    int M = 0;
    scanf("%d", &M);
    for(int i=0; i

		
Categories
不学无术

Aspect and Sentiment Unification Model for Online Review Analysis 论文报告

自己做的一些东西,明天的会上要分享。
其中有两篇论文是拿来参考的。
Aspect and Sentiment Unification Model for Online Review Analysis
Aspect and Sentiment Unification Model for Online Review Analysis
outline
论文讲了啥
文本情感分析

Categories
不学无术

Java中HashMap遍历的两种方式

原文地址: http://www.javaweb.cc/language/java/032291.shtml
第一种:
  

Map map = new HashMap();
  Iterator iter = map.entrySet().iterator();
  while (iter.hasNext()) {
  Map.Entry entry = (Map.Entry) iter.next();
  Object key = entry.getKey();
  Object val = entry.getValue();
  }

  效率高,以后一定要使用此种方式!
第二种:
  

Map map = new HashMap();
  Iterator iter = map.keySet().iterator();
  while (iter.hasNext()) {
  Object key = iter.next();
  Object val = map.get(key);
  }

  效率低,以后尽量少使用!
HashMap的遍历有两种常用的方法,那就是使用keyset及entryset来进行遍历,但两者的遍历速度是有差别的,下面请看实例:
  public class HashMapTest {
  public static void main(String[] args) …{
  HashMap hashmap = new HashMap();
  for (int i = 0; i < 1000; i ) …{
  hashmap.put(“” i, “thanks”);
  }
  long bs = Calendar.getInstance().getTimeInMillis();
  Iterator iterator = hashmap.keySet().iterator();
  while (iterator.hasNext()) …{
  System.out.print(hashmap.get(iterator.next()));
  }
  System.out.println();
  System.out.println(Calendar.getInstance().getTimeInMillis() – bs);
  listHashMap();
  }
  public static void listHashMap() …{
  java.util.HashMap hashmap = new java.util.HashMap();
  for (int i = 0; i < 1000; i ) …{
  hashmap.put(“” i, “thanks”);
  }
  long bs = Calendar.getInstance().getTimeInMillis();
  java.util.Iterator it = hashmap.entrySet().iterator();
  while (it.hasNext()) …{
  java.util.Map.Entry entry = (java.util.Map.Entry) it.next();
  // entry.getKey() 返回与此项对应的键
  // entry.getValue() 返回与此项对应的值
  System.out.print(entry.getValue());
  }
  System.out.println();
  System.out.println(Calendar.getInstance().getTimeInMillis() – bs);
  }
  }
  对于keySet其实是遍历了2次,一次是转为iterator,一次就从hashmap中取出key所对于的value。而entryset只是遍历了第一次,他把key和value都放到了entry中,所以就快了。
Java中HashMap遍历的两种方式(本教程仅供研究和学习,不代表JAVA中文网观点)
本篇文章链接地址:http://www.javaweb.cc/language/java/032291.shtml
如需转载请注明出自JAVA中文网:http://www.javaweb.cc/

Categories
不学无术

KM算法 详解+模板

本文转载自:http://blog.sina.com.cn/s/blog_691ce2b701016reh.html
 
先说KM算法求二分图的最佳匹配思想,再详讲KM的实现。
【KM算法求二分图的最佳匹配思想】

对于具有二部划分( V1, V2 )的加权完全二分图,其中 V1= { x1, x2, x3, … , xn }, V2= { y1, y2, y3, … , yn },边< xi, yj >具有权值 Wi,j 。该带权二分图中一个总权值最大的完美匹配,称之为最佳匹配。
 
记 L(x) 表示结点 x 的标记量,如果对于二部图中的任何边<x,y>,都有 L(x)+ L(y)>= Wx,y,我们称 L 为二部图的可行顶标。
设 G(V,E) 为二部图, G'(V,E’) 为二部图的子图。如果对于 G’ 中的任何边<x,y> 满足, L(x)+ L(y)== Wx,y,我们称 G'(V,E’) 为 G(V,E) 的等价子图。
 
定理一:设 L 是二部图 G 的可行顶标。若 L 等价子图 G有完美匹配 M,则 M 是 G 的最佳匹配。
证明:由于 GL 是 G 的等价子图,M 是 GL 的完美匹配,所以,M 也是 G  的完美匹配。以由于对于匹配 M 的每条边 e ,都有 e∈ E( GL ),而且 M 中每条边覆盖每个顶点正好一次,所以
W( M )= å W(e), e∈ M = å L(x), x∈ V
另一方面,对于 G 的任何完美匹配 M’ 有
W( M’ )= å W(e), e∈ M’ <= å L(x), x∈ V
于是 W( M )>= W( M’ ),即 M 是 G 的最优匹配。
 
由上述定理,我们可以通过来不断修改可行顶标,得到等价子图,从而求出最佳匹配。
就像匈牙利算法一样,我们依次为每一个顶点 i 寻找增广路径,如果寻找增广路径失败,我们就修改相应的可行顶标,来得到增广路径。
如图:
 1  2  3  |
 3  2  4  |
 2  3  5  |
若要对这个完全二分图求最佳匹配
 
初始化:
Lx(1)= max{ y| w(1,y), 1<= y<= 3 }= max{ 1, 2, 3 }= 3, Ly(1)= 0
Lx(2)= max{ 3, 2, 4 }= 4, Ly(2)= 0
Lx(3)= max{ 2, 3, 5 }= 5, Ly(3)= 0;
我们建立等价子图( 满足 Lx(x)+ Ly(y)== W(x,y) ) 如下:
km算法求二分图最佳匹配
对于该图,运用匈牙利算法对 X 部顶点 1 求增广路径,得到一个匹配,如图( 红色代表匹配边 ):km算法求二分图最佳匹配
 对 X 部顶点 2 求增广路径失败,寻找增广路径的过程为 X 2-> Y 3-> X 1。我们把寻找增广路径失败的 DFS 的交错树中,在 X 部顶点集称之为 S, 在 Y 部的顶点集称之为 T。则 S= { 1, 2 },T= { 3 }。现在我们就通过修改顶标值来扩大等价子图,如何修改。
 
1)   我们寻找一个 d 值,使得 d= min{ (x,y)| Lx(x)+ Ly(y)- W(x,y), x∈ S, y∉ T },因些,这时 d= min{
Lx(1)+Ly(1)-W(1,1),  Lx(1)+Ly(2)-W(1,2),  Lx(2)+Ly(1)-W(2,1),  Lx(2)+Ly(2)-W(2,2) }=
min{ 3+0- 1, 3+0-2,  4+0-3,  4+0-2 }= min{ 2, 1, 1, 2 }= 1。
寻找最小的 d 是为了保证修改后仍满足性质对于边 <x,y> 有 Lx(x)+ Ly(y)>= W(x,y)。
 
2)   然后对于顶点 x
1. 如果 x∈ S 则 Lx(x)= Lx(x)- d。
2. 如果 x∈ T 则 Ly(x)= Ly(x)+ d。
3. 其它情况保持不变。
如此修改后,我们发现对于边<x,y>,顶标 Lx(x)+ Ly(y) 的值为
1.  Lx(x)- d+ Ly(y)+ d,  x∈ S, y∈ T。
2.  Lx(x)+ Ly(y),  x∉ S,  y∉ T。
3.  Lx(x)- d+ Ly(y), x∈ S, y∉ T。
4.  Lx(x)+ Ly(y)+ d, x∉ S,  y∈ T。
易知,修改后对于任何边仍满足 Lx(x)+ Ly(y)>= W(x,y),并且第三种情况顶标值减少了 d,如此定会使等价子图扩大。
 
就上例而言: 修改后 Lx(1)= 2, Lx(2)= 3, Lx(3)= 5, Ly(1)= 0, Ly(1)= 0, Ly(2)= 0, Ly(3)= 1。
这时 Lx(2)+Ly(1)=3+0=3= W(2,1),在等价子图中增加了一条边,等价子图变为:
 km算法求二分图最佳匹配
如此按以上方法,得到等价子图的完美匹配。
 
另外计算 d 值的时候可以进行一些优化。
定义 slack(y)= min{ (x,y)| Lx(x)+ Ly(y)- W(x,y),x∈ S,  y∉ T }
这样能在寻找增广路径的时候就顺便将 slack 求出。

(以上为摘上网络)
【KM算法及其具体过程】
(1)可行点标:每个点有一个标号,记lx[i]为X方点i的标号,ly[j]为Y方点j的标号。如果对于图中的任意边(i, j, W)都有lx[i]+ly[j]>=W,则这一组点标是可行的。特别地,对于lx[i]+ly[j]=W的边(i, j, W),称为可行边
(2)KM 算法的核心思想就是通过修改某些点的标号(但要满足点标始终是可行的),不断增加图中的可行边总数,直到图中存在仅由可行边组成的完全匹配为止,此时这个 匹配一定是最佳的(因为由可行点标的的定义,图中的任意一个完全匹配,其边权总和均不大于所有点的标号之和,而仅由可行边组成的完全匹配的边权总和等于所 有点的标号之和,故这个匹配是最佳的)。一开始,求出每个点的初始标号:lx[i]=max{e.W|e.x=i}(即每个X方点的初始标号为与这个X方 点相关联的权值最大的边的权值),ly[j]=0(即每个Y方点的初始标号为0)。这个初始点标显然是可行的,并且,与任意一个X方点关联的边中至少有一条可行边
(3)然后,从每个X方点开始DFS增广。DFS增广的过程与最大匹配的Hungary算法基本相同,只是要注意两点:一是只找可行边,二是要把搜索过程中遍历到的X方点全部记下来(可以用vst搞一下),以进行后面的修改;
(4) 增广的结果有两种:若成功(找到了增广轨),则该点增广完成,进入下一个点的增广。若失败(没有找到增广轨),则需要改变一些点的标号,使得图中可行边的 数量增加。方法为:将所有在增广轨中(就是在增广过程中遍历到)的X方点的标号全部减去一个常数d,所有在增广轨中的Y方点的标号全部加上一个常数d,则 对于图中的任意一条边(i, j, W)(i为X方点,j为Y方点):
<1>i和j都在增广轨中:此时边(i, j)的(lx[i]+ly[j])值不变,也就是这条边的可行性不变(原来是可行边则现在仍是,原来不是则现在仍不是);
<2>i在增广轨中而j不在:此时边(i, j)的(lx[i]+ly[j])的值减少了d,也就是原来这条边不是可行边(否则j就会被遍历到了),而现在可能是;
<3>j在增广轨中而i不在:此时边(i, j)的(lx[i]+ly[j])的值增加了d,也就是原来这条边不是可行边(若这条边是可行边,则在遍历到j时会紧接着执行DFS(i),此时i就会被遍历到),现在仍不是;
<4>i和j都不在增广轨中:此时边(i, j)的(lx[i]+ly[j])值不变,也就是这条边的可行性不变。
这 样,在进行了这一步修改操作后,图中原来的可行边仍可行,而原来不可行的边现在则可能变为可行边。那么d的值应取多少?显然,整个点标不能失去可行性,也 就是对于上述的第<2>类边,其lx[i]+ly[j]>=W这一性质不能被改变,故取所有第<2>类边的 (lx[i]+ly[j]-W)的最小值作为d值即可。这样一方面可以保证点标的可行性,另一方面,经过这一步后,图中至少会增加一条可行边。
(5)修改后,继续对这个X方点DFS增广,若还失败则继续修改,直到成功为止;
(6)以上就是KM算法的基本思路。但是朴素的实现方法,时间复杂度为O(n4)——需要找O(n)次增广路,每次增广最多需要修改O(n)次顶标,每次修改顶 标时由于要枚举边来求d值,复杂度为O(n2)。实际上KM算法的复杂度是可以做到O(n3)的。我们给每个Y顶点一个“松弛量”函数slack,每次开 始找增广路时初始化为无穷大。在寻找增广路的过程中,检查边(i,j)时,如果它不在相等子图中,则让slack[j]变成原值与 A[i]+B[j]-w[i,j]的较小值。这样,在修改顶标时,取所有不在交错树中的Y顶点的slack值中的最小值作为d值即可。但还要注意一点:修 改顶标后,要把所有不在交错树中的Y顶点的slack值都减去d。
【求二分图的最小匹配】
只需把权值取反,变为负的,再用KM算出最大权匹配,取反则为其最小权匹配。

hdoj 2255
#include 
#include 
#define M 310
#define inf 0x3f3f3f3f
int n,nx,ny;
int link[M],lx[M],ly[M],slack[M];    //lx,ly为顶标,nx,ny分别为x点集y点集的个数
int visx[M],visy[M],w[M][M];
int DFS(int x)
{
    visx[x] = 1;
    for (int y = 1;y <= ny;y ++)
    {
        if (visy[y])
            continue;
        int t = lx[x] + ly[y] - w[x][y];
        if (t == 0)       //
        {
            visy[y] = 1;
            if (link[y] == -1||DFS(link[y]))
            {
                link[y] = x;
                return 1;
            }
        }
        else if (slack[y] > t)  //不在相等子图中slack 取最小的
            slack[y] = t;
    }
    return 0;
}
int KM()
{
    int i,j;
    memset (link,-1,sizeof(link));
    memset (ly,0,sizeof(ly));
    for (i = 1;i <= nx;i ++)            //lx初始化为与它关联边中最大的
        for (j = 1,lx[i] = -inf;j <= ny;j ++)
            if (w[i][j] > lx[i])
                lx[i] = w[i][j];
    for (int x = 1;x <= nx;x ++)
    {
        for (i = 1;i <= ny;i ++)
            slack[i] = inf;
        while (1)
        {
            memset (visx,0,sizeof(visx));
            memset (visy,0,sizeof(visy));
            if (DFS(x))     //若成功(找到了增广轨),则该点增广完成,进入下一个点的增广
                break;  //若失败(没有找到增广轨),则需要改变一些点的标号,使得图中可行边的数量增加。
                        //方法为:将所有在增广轨中(就是在增广过程中遍历到)的X方点的标号全部减去一个常数d,
                        //所有在增广轨中的Y方点的标号全部加上一个常数d
            int d = inf;
            for (i = 1;i <= ny;i ++)
                if (!visy[i]&&d > slack[i])
                    d = slack[i];
            for (i = 1;i <= nx;i ++)
                if (visx[i])
                    lx[i] -= d;
            for (i = 1;i <= ny;i ++)  //修改顶标后,要把所有不在交错树中的Y顶点的slack值都减去d
                if (visy[i])
                    ly[i] += d;
                else
                    slack[i] -= d;
        }
    }
    int res = 0;
    for (i = 1;i <= ny;i ++)
        if (link[i] > -1)
            res += w[link[i]][i];
    return res;
}
int main ()
{
    int i,j;
    while (scanf ("%d",&n)!=EOF)
    {
        nx = ny = n;
      //  memset (w,0,sizeof(w));
        for (i = 1;i <= n;i ++)
            for (j = 1;j <= n;j ++)
                scanf ("%d",&w[i][j]);
        int ans = KM();
        printf ("%dn",ans);
    }
    return 0;
}
Categories
不学无术 木有技术

协同过滤文章两篇

探索推荐引擎内部的秘密,第 2 部分_ 深入推荐引擎相关算法 – 协同过滤 协同过滤

Categories
不学无术

interval scale和ratio scale的区别

interval scale 等距尺度:又称区间尺度,衡量的数字可代表大小或优劣顺序,数字的差距直接表示其差异的程度。
ratio scale 比例尺度:物与物的相对比较,表明各种物体间的相对度量关系。
参考百度百科

Categories
不学无术

Eclipse JRI : Java 调用 R 报错: Cannot find JRI native library!

Q: I get the following error, what’s wrong?
java.lang.UnsatisfiedLinkError: no jri in java.library.path
A: Usually it means that you didn’t setup the necessary environment variables properly or the JRI library is not where it is expected to be. The recommended way to start JRI programs is to use the run script which is generated along with the library. It sets everything up and is tested to work. If you want to write your own script or launcher, you must observe at least the following points:

  • R_HOME must be set correctly
  • (Windows): The directory containing R.dll must be in your PATH
  • (Mac): Well, it’s a Mac, so it just works ;).
  • (unix): R must be compiled using --enable-R-shlib and the directory containing libR.so must be in LD_LIBRARY_PATH. Also libjvm.so and other dependent Java libraries must be on LD_LIBRARY_PATH.
  • JRI library must be in the current directory or any directory listed in java.library.path. Alternatively you can specify its path with 
    -Djava.library.path= when starting the JVM. When you use the latter, make sure you check java.library.path property first such that you won’t break your Java.
  • Depending on your system, the R verison and other features you want to use, you may have to set additional settings such as R_SHARE_DIRR_INCLUDE_DIR andR_DOC_DIR.

Again, I don’t think you want to worry about all of the above – just use the start script!

特别注意红字标注的这一行,
QQ截图20130728131711
在这边修改实现即可。
参考:http://www.rforge.net/JRI/

Categories
不学无术

JXL Excel使用

http://www.360doc.com/content/11/0422/14/6728052_111518047.shtml