/*
* JASA Java Auction Simulator API
* Copyright (C) 2013 Steve Phelps
*
* 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.
*/
package net.sourceforge.jabm.util;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Stack;
/**
* A class that iterates over all numerical partitions of n into k distinct
* parts including commutative duplications and parts containing zero.
*
* @author Steve Phelps
* @version $Revision: 16 $
*/
public class Partitioner implements Iterator<int[]>, Serializable {
protected Stack<PartitionerState> stack;
protected HashSet<PartitionerState> visitedStates;
public Partitioner(int n, int k) {
stack = new Stack<PartitionerState>();
visitedStates = new HashSet<PartitionerState>();
stack.push(new PartitionerState(new int[k], n));
}
public boolean hasNext() {
return !stack.isEmpty();
}
public int[] next() {
return partition();
}
public void remove() {
throw
new IllegalArgumentException("method remove() not implemented");
}
protected int[] partition() {
while (!stack.isEmpty()) {
PartitionerState state = stack.pop();
if (state.n == 0) {
return state.p;
}
int[] p = state.p;
for (int i = 0; i < p.length; i++) {
int[] p1 = (int[]) p.clone();
p1[i]++;
PartitionerState newState = new PartitionerState(p1, state.n - 1);
if (!visitedStates.contains(newState)) {
stack.push(newState);
visitedStates.add(newState);
}
}
}
return null;
}
public static void main(String[] args) {
Partitioner p = new Partitioner(20, 3);
while (p.hasNext()) {
int[] partition = (int[]) p.next();
for (int i = 0; i < partition.length; i++) {
System.out.print(partition[i] + " ");
}
System.out.println("");
}
}
}
class PartitionerState {
protected int n;
protected int[] p;
public PartitionerState(int[] p, int n) {
this.n = n;
this.p = p;
}
public boolean equals(Object other) {
PartitionerState s = (PartitionerState) other;
if (this.n != s.n) {
return false;
}
for (int i = 0; i < this.p.length; i++) {
if (this.p[i] != s.p[i]) {
return false;
}
}
return true;
}
public int hashCode() {
int hash = n;
int m = 1;
for (int i = 0; i < p.length; i++) {
hash += m * p[i];
m <<= 1;
}
return hash;
}
}