Tuesday, September 3, 2013

Nest for-loop n-times, recursive calls, and beyond

It is easy to write the code to nest the for-loop n-times if you know the value of n. For example, if you know n=3, then the code is as follows:

   for(int i=0; i<length; i++){
       for(int j=0; j<length; j++){
          for(int k=0; k<length; k++){
          }
       }
   }
But what if the value of n is just a variable? How to write code for this? It can be solved using recursive function. The basic code is as follows:
 public void func(int count, int n){
    if( count == n){
       return;
    }
    for(int i=0; i<length; i++){
        func(count+1,n);
     }
 }
 
And you just need to call func(0,n); The basic idea here is to pass the count number as an argument to the next recursive call. And the next recursive call can determine if to finish or continue based on that value. Here we only pass the count number to the subsequent call. We can also pass other values in the arguments to the next recursive call and solve some quite complex problems! If we make some twists in the actual body of the function, this code can be even more powerful! We show several algorithms here.

N-Queen Problem


Problem: Position n queens on a chessboard so that no two are in the same row, column, or diagonal.
Inputs: positive integer n.
Outputs: All possible ways n queens can be placed on an n*n chessboard so that no two queens threaten each other.
Solution: We use col[i] to denote the column position of the queen in i-th row. We will pass col[] as an argument to the next recursive call so it can be used to check if the positions are valid.
 public void func(int count, int[] col){
    if ( count == col.length){
       printOutResult(col);
       return;
    }
    for(int i=0; i<col.length; i++){
       col[count] = i;
       if ( goodSoFar(col, count)){
          func(count+1, col);
       }
    }
 }
 
 private void printOutResult(int[] col){
    for(int i=0; i<col.length; i++){
      System.out.println(" " + col[i]);
    }
 }
 
 private boolean goodSoFar(int[] col, int count){
   for(int i=0; i<count; i++){
      if ( col[i] == col[count]){ // same column
       return false;
      }
      if ( Math.abs(col[i] - col[count]) == count - i){ // diagonal
        return false;
      }
   }
   return true;
 
 }
 
 public void solve(int n){
    int[] col = new int[n];
    func(0, col);
 }
 
Test Results:
Given n=4, it will give the answers: 2 4 1 3 and 3 1 4 2
Notes:
  1. We pass the intermediate value in col[] to the next call.
  2. col[] also holds the final results.
  3. Algorithm books call the functions like "goodSoFar" as backtracking.

Permutation Problem


Problem: Print out all the permutations of some letters.
Inputs: An array of characters inChars of length n, where n is a positive integer
Outputs: All possible permutations of these characters.
Solution 1:
 public void func(int count, boolean[] used, char[] chs, StringBuilder sb){
    if ( count == used.length){
       System.out.println(sb.toString());
    }
    for(int i=0; i<chs.length; i++){
       if( !used[i]){
         sb.append(chs[i]);
         used[i] = true;
         func(count+1, used, chs, sb);
         used[i] = false;
         sb.setLength(count);
       }
    }
 }
 
 public void solve(char[] inChars){
   boolean[] used = new boolean[inChars.length];
   StringBuilder sb = new StringBuilder();
   func(0, used, inChars, sb);
 }
 

Test Results:
For inChars = {'a','b','c'}, the output is
   abc
   acb
   bac
   bca
   cab
   cba

Notes:
  1. The above code for permutation is a little different from the n-Queens problem. In the n-Queens problem, each subsequent loop still goes throug all the positions, whereas here, the subsequent loops only go through partial values. They use the used[] array to check if a value has already been used.

Solution 2: Solution 1 is good but a little bit convoluted. We can actually use the exact same pattern as in the n-Queens problem to sovle the problem. The code is below:
 public void func(int count, int[] result, char[] chs) {
   if (count == result.length) {
    printResult(result, chs);
    return;
   }
   for (int i = 0; i < chs.length; i++) {
    result[count] = i;
    if (goodSoFar(count, result)) {
     func(count + 1, result, chs);
    }
   }
  }
  
  private boolean goodSoFar(int count, int[] used) {
   for (int i = 0; i < count; i++) {
    if (used[i] == used[count]) {
     return false;
    }
   }
   return true;
  }
  
  private void printResult(int[] result, char[] chs) {
   for (int i = 0; i < result.length; i++) {
    System.out.print(chs[result[i]]);
   }
   System.out.println();
  }
  
  public void solve(char[] inChars) {
   int[] result = new int[inChars.length];
   for (int i = 0; i < result.length; i++) {
    result[i] = -1;
   }
   func(0, result, inChars);
 }
 

Test Results:
For inChars = {'a','b','c'}, the output is
    abc
    acb
    bac
    bca
    cab
    cba

Notes:
  1. The code is very similar to the n-Queens problem. We store the intermediate results in the array "result" and pass it to the next recursive call. The "result" array stores the index of the char in the original input "inChars" array.
  2. Again, the "goodSoFar" method is our pruning method. It can be modified for other variations of permutation. For example, if no duplicate character is allowd, we can change the code.
  3. This algo is a little bit less efficient than solution 1 because the method "goodSoFar" needs to go through an array to check values. But the code is very clear and easy to understand.

Combination Problem


Inputs: An array of characters inChars of length n, where n is a positive integer
Outputs: All subsets except the empty subset. There should be 2^n - 1 subsets.
Solution:
  public void func(int count, boolean[] flags, char[] chs){
      if ( count == flags.length){
         printResult(flags, chs);
         return;
      }
      flags[count] = true;
      func(count + 1, flags, chs);
      flags[count] = false;
      func(count + 1, flags, chs);
  }
  
  private void printResult(boolean[] flags, char[] chs){
    for(int i=0; i<flags.length; i++){
      if ( flags[i]){
           System.out.print(chs[i]);
      }
    }
    System.out.println();
  }
  
  public void solve(char[] inChars){
     boolean[] flags = new boolean[inChars.length];
     func(0,flags, inChars); 
  }
  

Test Results:
For inChars = {'a','b','c'}, the output is

abc
ab
ac
a
bc
b
c

Notes:
  1. To form a subset, an element in the original set is either selected or not selected. We use "flags" in the code to denote whether each element is selected or not.
  2. The "func" method does not have a for-loop as in the previous examples. But essentially it is looping through the array {true, false}.

Knapsack Problem

Problem: Given a collection of items, each with its weight and value, find a subset of these items so that the total value of the items in this subset is a max value under the condition that their total weight does not exceed a given limit.
Inputs: int[] weights, int[] values, int weightLimit
Output: int maxValue and the items shosen
Solution: This is essentially a combination problem. The code is below.

 public class Knapsack(){

 private int currentMaxValue;
 private boolean[] chosen;
 private boolean[] selected;

 public void func(int count, final int weightLimit, final int[] weights,
   final int[] values, int weightSoFar, int valueSoFar,
   boolean[] selected) {
  if (count == selected.length) {
   if (valueSoFar > currentMaxValue) {
    updateResult(valueSoFar, selected);
   }
   return;
  }

  selected[count] = true;

  // if next item makes it overweight,stop
  if (weightSoFar + weights[count] > weightLimit) {
   if (valueSoFar > currentMaxValue) {
    updateResult(valueSoFar, selected);
   }
  } else {
   func(count + 1, weightLimit, weights, values, weightSoFar
     + weights[count], valueSoFar + values[count], selected);
  }

  selected[count] = false;
  func(count + 1, weightLimit, weights, values, weightSoFar, valueSoFar,
    selected);

 }

 private void updateResult(int valueSoFar, boolean[] flags) {
  this.currentMaxValue = valueSoFar;
  // can also use the following System.arraycopy instead of the for-loop
  // System.arraycopy(flags, 0, chosen, 0, flags.length);
  for (int i = 0; i < flags.length; i++) {
   chosen[i] = flags[i];
  }
 }

 public void solve(int[] weights, int[] values, int weightLimit) {
  Assert.isTrue(weights != null && values != null
    && weights.length == values.length);
  currentMaxValue = Integer.MIN_VALUE;
  chosen = new boolean[weights.length];
  selected = new boolean[weights.length];
  func(0, weightLimit, weights, values, 0, 0, selected);
  System.out.println("The max value is " + currentMaxValue + " chosen is "
    + Arrays.toString(chosen));
 }
}

Test Result:

 public void testKnapSack() {
  int limit = 20;
  int[] weights = { 2, 5, 23, 10, 6, 7, 1 };
  int[] values = { 2, 343, 234, 1, 21, 6, 8 };
  solve(weights, values, limit);
 }
Output:

Max values is 378 chosen is [false, true, false, false, true, true, true]
The above results mean that items at the positions 2,5,6,7 are chosen.

Notes on Character Encoding and Unicode

We often see terminologies such as ASCII, UTF-8, Unicode, etc. These can be confusing. Here are some notes on them.
  1. Basically an encoding is about how to represent language characters in computer using numbers.
  2. ASCII is basically for English. It uses 7 bits. Each value from 0 to 127 is mapped to a character. We know that this is not enough for other languages.
  3. ISO 8859 is another encoding. It uses 8 bits. It can be thought of as an expansion of ASCII. It uses the same values to represent the same ASCII characters. With the additional one bit, it can represent more characters and is sufficient for most other western languages.
  4. Unicode also maps characters to numbers (called code points). It uses 32 bits. But the range of the values is not all the 32 bit numbers. The range is from 0x0 to 0x10FFFF. For every character that has an ASCII value, the Unicode code point and the ASCII value of that character are the same.
  5. Unicode is a specification. It is not an implementation. Actually the same can be said of ASCII. UTF-8 and UTF-16 are two of the Unicode implementations.
  6. UTF-8 uses 8 bits to represent some characters. And uses up to 32 bits to represent other characters. It is a variable-length encoding. UTF-16 uses 16 bits to represent some characters. And uses 32 bits to represent other characters. It is also variable-length encoding. So the number 8 and 16 in these two encoding scheme can be thought of as the least number of digits used to encode a character.
  7. Java uses Unicode for String. And it uses UTF-16. In java, you can use escape character to represent a Unicode character. For example you can use \u0078 for 'x'. Now immediately you can see that this format has the largest possible value \uFFFF, which does not cover the all the values in a Unicode. The largest Unicode value is 0x10FFFF. For this java uses a surrogate pair which is a combination of two \u numbers.
  8. In java, you can also use another format to represent a char value. For example,
    char var = '\101'; 
    Here the variable var is equal to 'A'. The formal name for this representation is "octal escapes". The maximum value allowed in Java is '\377', which is equivalent to the decimal value 255 because 3*8^2 + 7*8 + 7 = 255. It is probably for purely historical reasons that Java supports octal escape sequences at all. These escape sequences originated in C.
  9. Note that the Unicode representation in java is preprocessed before compilation. So for example "\u0033\u0078\u1000\u0079" is a valid string that consists of 4 letters "3x?y".

Friday, June 28, 2013

Notes on Weblogic JNDI, Cluster, Datasource Deployment

  1. You can bind an RMI object or a non-RMI object into a JNDI tree.
  2. When a client connects to a cluster, it is actually connecting to one of the WebLogic Servers in the cluster. Because the JNDI tree for this WebLogic Server contains the RMI stubs for all services offered by the other WebLogic Servers in the cluster in addition to its own services, the cluster appears to the client as one WebLogic Server hosting all of the cluster-wide services.
  3. When an instance of a RMI object is deployed to a single WebLogic Server, the stub is replicated across the cluster.

    Notes
    (1) Note that only the stub of the RMI object is replicated. So if the hosting server of the RMI object is down, the service given by the RMI object is also down. The RMI stubs in the other sever's JNDI tree are updated to reflect the server failure.
    (2) When you deploy a data source to a cluster, WebLogic Server creates an instance of the data source on each server in the cluster. So in this case, each server has an actual instance instead of a stub. So even if one server goes down, the data source in other servers can still work.

  4. When a customer object ( a non-RMI object) is bound into a JNDI tree in a cluster, the object is replicated across all the servers in the cluster. However, if the host server goes down, the customer object is removed from teh cluster's JNDI tree.
    To create a binding that is not replicated across WebLogic Servers in a cluster, you must specify the REPLICATE_BINDING property to "false" when creating the context that binds the customer object.
  5. A client can use the ClusterAddress to get the service. This address may be either a DNS host name that maps to multiple IP addresses or a comma separated list of single address host names or IP addresses. An alternative method of specifying the initial point of contact with the WebLogic Cluster is to supply a comma-delimited list of DNS Server names or IP addresses. Examples:
       Hashtable ht = new Hashtable();
       ht.put(Context.PROVIDER_URL, "t3://acme1,acme2,acme3:7001");
    or
    ht.put(Context.PROVIDER_URL, "t3://node1:7001,node2:7002,node3:7003");

References

  1. Programming WebLogic JNDI(http://docs.oracle.com/cd/E15051_01/wls/docs103/jndi/jndi.html)
  2. Deploying Data Sources on Servers and Clusters (http://docs.oracle.com/cd/E23943_01/web.1111/e13737/ds_deploy.htm)

Wednesday, May 1, 2013

Notes on how to configure key files for SSH connection

Login onto Linux. When you first SSH to another server with the following command:
ssh someuser@remoteServer
You will get the prompt like the following:
The authenticity of host 'remoteServer (XX.XX.XX.XX)' can't be established.
RSA key fingerprint is d9:5e:8d:9d:59:12:39:e9:ff:59:57:07:92:ef:52:b2.
Are you sure you want to continue connecting (yes/no)? 
Type yes. Now you will be prompted to enter the password for the user "someuser" to login to remoteServer.
Just type the password. And now you should be successfully connected to remoteServer.

When you ssh to a remote server, your ssh client records the hostname, IP address and public key of the remote server in a flat file called "known_hosts". As such, the .ssh directory on your local server will now have the known_hosts file that contains an entry for remoteServer. The entry looks like the following:

remoteServer,XX.XX.XX.XX ssh-rsa AAAAB3NzaC1yc.....
In the above entry, the string after ssh-rsa is the public key of remoteServer. Where is this public key located on remoteServer? There can be different user accounts on remoteServer. And each account can create its own keys. But when you ssh to remoteServer, you will get the same public key. This key is actually at the location /etc/ssh/ssh_host_rsa_key.pub.

Now on your local server, execute the following command to generate the public/private keys:

ssh-kygen -t rsa
It will prompt you to enter the file in which to save the generated key and also prompt you to enter passphrase.
Just take the default and return to use the empty passphrase. This will create the private key id_rsa and the public key id_rsa.pub in the .ssh directory.

Logon to remoteServer. In the home directory for the user someuser on remoteServer, there is the .ssh folder. If this folder has a file authorized_keys, then append the content of the public key file id_rsa.pub that you generated on your local server to the end of authorized_keys. If authorized_keys file does not exist, then create it and copy the content of id_rsa.pub to this file.

Now if you do the following on your local server:

ssh someuser@remoteServer
You should be able to logon to remoteServer directly without the need to type password.

Friday, February 1, 2013

Fractals

I made a program using java Swing that can easily draw fractals that are generated as the attractors of the math IFS ( Iterated Function Systems). The following is a sample picture. It is a tile of a self-affine tiling of the plane R^2. The IFS consists of 3 functions {f1(x),f2(x), f3(x)}. The 3 functions are defined as follows:
f1(x) = (B^2)^(-1)(x)
f2(x) = (B*w*B)^(-1)(x + B*h)
f3(x) = B^(-1)(x + d)
where B is the matrix {{1, -1},{1,1}}, w is the matrix {{0,-1},{1,0}}, h = {0,1}, and d={1,0}.

Note that the picture consists of 3 pieces that are similar to each other. The 3 pieces do not overlap. They only touch others at the borders. Though the boundary of the whole picture is very complex, we can use similar copies of this shape of different sizes to tile the whole plane without overlapping! And we only need finitely many different sizes of this shape for the tiling.

Friday, January 25, 2013

JAXWS proxy

JDK 6 has the wsimport tool that can be used to generate java classes based on the given wsdl file. Then the webservice client can use those classes to call the web service. The following is the example code:
public void testMyService(){
  MyService service = new MyService();
  port = service.getMyPort();
  port.doSomething();
}
In the above, the class MyService is generated by wsimport. It has many annotations related to web service. It is a subclass of javax.xml.ws.Service. MyService is actually a proxy. The following is from the javadoc of the class Service:

Service objects provide the client view of a Web service.

Service acts as a factory of the following:

  • Proxies for a target service endpoint.
  • Instances of {@link javax.xml.ws.Dispatch} for dynamic message-oriented invocation of a remote operation.
Now the questions are these. How is the proxy actually created in the runtime? How are those annotations used? The following is the stack of the method calls at the point when the proxy is created:
 Thread [Main Thread] (Suspended (breakpoint at line 574 in Proxy)) 
  Proxy.newProxyInstance(ClassLoader, Class<?>[], InvocationHandler) line: 574 
  AnnotationParser.annotationForMap(Class, Map) line: 239 
  AnnotationParser.parseAnnotation(ByteBuffer, ConstantPool, Class, boolean) line: 229 
  AnnotationParser.parseAnnotations2(byte[], ConstantPool, Class) line: 69 
  AnnotationParser.parseAnnotations(byte[], ConstantPool, Class) line: 52 
  Class<T>.initAnnotationsIfNecessary() line: 3070 
  Class<T>.getAnnotation(Class<A>) line: 3029 
  AnnotationType.<init>(Class<?>) line: 113 
  AnnotationType.getInstance(Class) line: 66 
  AnnotationParser.parseAnnotation(ByteBuffer, ConstantPool, Class, boolean) line: 202 
  AnnotationParser.parseAnnotations2(byte[], ConstantPool, Class) line: 69 
  AnnotationParser.parseAnnotations(byte[], ConstantPool, Class) line: 52 
  Class<T>.initAnnotationsIfNecessary() line: 3070 
  Class<T>.getAnnotation(Class<A>) line: 3029 
  RuntimeInlineAnnotationReader.getClassAnnotation(Class<A>, Class, Locatable) line: 106 
  RuntimeInlineAnnotationReader.getClassAnnotation(Class, Object, Locatable) line: 57 
  RuntimeModelBuilder(ModelBuilder<T,C,F,M>).getTypeInfo(Ref<T,C>) line: 330 
  JAXBContextImpl.getTypeInfoSet() line: 460 
  JAXBContextImpl.<init>(JAXBContextImpl$JAXBContextBuilder) line: 298 
  JAXBContextImpl.<init>(JAXBContextImpl$JAXBContextBuilder, JAXBContextImpl$1) line: 141 
  JAXBContextImpl$JAXBContextBuilder.build() line: 1163 
  ContextFactory.createContext(Class[], Map) line: 145 
  NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method] 
  NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39 
  DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25 
  Method.invoke(Object, Object...) line: 597 
  ContextFinder.newInstance(Class[], Map, String) line: 202 
  ContextFinder.find(Class[], Map) line: 363 
  JAXBContext.newInstance(Class[], Map) line: 574 
  JAXBContext.newInstance(Class...) line: 522 
  ProviderImpl$2.run() line: 209 
  ProviderImpl$2.run() line: 206 
  ProviderImpl.getEPRJaxbContext() line: 206 [local variables unavailable] 
  ProviderImpl.() line: 77 [local variables unavailable] 
  NativeConstructorAccessorImpl.newInstance0(Constructor, Object[]) line: not available [native method] 
  NativeConstructorAccessorImpl.newInstance(Object[]) line: 39 
  DelegatingConstructorAccessorImpl.newInstance(Object[]) line: 27 
  Constructor<T>.newInstance(Object...) line: 513 
  Class<T>.newInstance0() line: 355 [local variables unavailable] 
  Class<T>.newInstance() line: 308 [local variables unavailable] 
  FactoryFinder.newInstance(String, ClassLoader) line: 31 
  FactoryFinder.find(String, String) line: 128 
  Provider.provider() line: 83 [local variables unavailable] 
  MyService(Service).<init>(URL, QName) line: 56 
  MyService.<init>() line: 46 
  SimpleClient.testMyService() line: 86 
  SimpleClient.main(String[]) line: 108 
This stack gives some clue about how the proxy is created.
  1. MyService is the class generated by wsimport.
  2. The following call to the constructor
         service = new MyService()
    
    calls the constructor of the super class Service. And the following code is executed:
       protected Service(java.net.URL wsdlDocumentLocation, QName serviceName) {
            delegate = Provider.provider().createServiceDelegate(wsdlDocumentLocation,
                    serviceName,
                    this.getClass());
        }
        
    This corresponds to
            MyService(Service).<init>(URL, QName) line: 56 
         
    in the stack.
  3. Now you can see that the Provider picks up the duty and will do all the heavy work. It uses the input parameters wsdlDocumentLocation, serviceName and Class to create the delegate object. The Provider is javax.xml.ws.spi.Provider. My guess is that the Class object this.getClass() contains all the annotation information of the class MyService. The stack shows the process uses the following classes:
    (1)RuntimeInlineAnnotationReader (package: com.sun.xml.bind.v2.model.annotation)
    (2)AnnotationParser (package: sun.reflect.annotation)

  4. These classes process the annotations.

Monday, January 21, 2013

How to set handlers on the JAX-WS client side

In webservice, handlers can be used for logging messages, implmenting security,etc. For a JAX-WS client, there are several ways to set handlers.

Use xml binding

The handlers can be set by binding a handler XML file.
import javax.xml.ws.Service;

@WebServiceClient(name = "MyService", targetNamespace = "...", wsdlLocation = "...")
@HandlerChain(file = "MyService_handler.xml")
public class MyService extends Service{
...
}
MyService_handler.xml:
<?xml version="1.0" encoding="UTF-8"?>
<javaee:handler-chains xmlns:javaee="http://java.sun.com/xml/ns/javaee">
  <javaee:handler-chain>
    <javaee:handler>
      <javaee:handler-class>com.my.SOAPHandler1</javaee:handler-class>
    </javaee:handler>
    <javaee:handler>
      <javaee:handler-class>com.my.SOAPHandler2</javaee:handler-class>
    </javaee:handler>
  
  </javaee:handler-chain>
</javaee:handler-chains>

Set handlers programmatically

The handlers can also be set programmatically. You can use BindingProvider to set the handlers.
import javax.xml.ws.BindingProvider;

 MyService service = new MyService(wsdlLoc, qName);
 port = service.getXXX();
 BindingProvider bp = (BindingProvider) port;
 Binding binding = bp.getBinding();
 List<Handler> handlerList = binding.getHandlerChain();
 MySOAPHandler myHandler = new MySOAPHandler();
 handlerList.add(myHandler );
 bp.getBinding().setHandlerChain(handlerList);

 port.callXYZ(...);
        
You can also use HandlerResolver to set handlers.

    import javax.xml.ws.handler.Handler;
    import javax.xml.ws.handler.HandlerResolver;
    import javax.xml.ws.handler.PortInfo;

        MyService service = new MyService(wsdlLoc, qName);
       
        service.setHandlerResolver(new HandlerResolver() {
        @Override public List getHandlerChain(PortInfo portInfo) { 
         List<Handler> handlerChain = new ArrayList<Handler>(); 
         handlerChain.add(new MySOAPHandler()); 
         return handlerChain; 
       } 
     });
     
      port = service.getXXX();
      port.callXYZ(...);
But be careful that the code "port = service.getXXX()" must be put after service.setHandlerResolver(...). If it is put before the call setHandlerResolver(...), the code won't work.

References

  1. http://www.javaworld.com/javaworld/jw-02-2007/jw-02-handler.html
  2. http://jax-ws.java.net/nonav/2.2.7/docs/index.html