package aim4.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
public class ConflictReducer {
protected boolean MultiSolutionsSupported;
public int conflictMatrix[][];
public int n;
public int conflictReduced[][];
public int conflictCounter[];
public int confirmed[];
public HashMap<ArrayList<Integer>, Integer> confirmedSeqSet;
public int nConfirmedMaxCurr;
public HashMap<Long, Integer> visited;
public ConflictReducer(int conflictMatrix[][], int n) {
this.MultiSolutionsSupported = true;
this.conflictMatrix = conflictMatrix;
this.n = n;
}
private void init() {
this.conflictReduced = new int[n][n];
this.conflictCounter = new int[n];
this.confirmed = new int[n];
this.confirmedSeqSet = new HashMap<ArrayList<Integer>, Integer>();
this.nConfirmedMaxCurr = 0;
this.visited = new HashMap<Long, Integer>();
for (int i = 0; i < n; i++) {
this.conflictCounter[i] = 0;
this.confirmed[i] = 1;
for (int j = 0; j < n; j++) {
this.conflictReduced[i][j] = 0;
if (this.conflictMatrix[i][j] > 0) {
this.conflictCounter[i] += 1;
}
}
}
}
private ArrayList<Integer> findRowsConflictMax() {
ArrayList<Integer> rows = new ArrayList<Integer>();
int conflictMax = 0;
for (int i = 0; i < n; i++) {
if (conflictCounter[i] > conflictMax) {
conflictMax = conflictCounter[i];
}
}
for (int i = 0; i < n; i++) {
if (conflictCounter[i] > 0 && conflictCounter[i] == conflictMax) {
rows.add(i);
}
}
return MultiSolutionsSupported? rows: (rows.size() > 0? new ArrayList<Integer>(rows.subList(0, 1)): rows);
}
private HashMap<ArrayList<Integer>, Integer> filterInvalidSeq() {
Iterator<ArrayList<Integer>> iter =
confirmedSeqSet.keySet().iterator();
int nConfirmedMax = 0;
while (iter.hasNext()) {
ArrayList<Integer> seq = iter.next();
int size = confirmedSeqSet.get(seq);
if (size > nConfirmedMax) {
nConfirmedMax = size;
}
}
HashMap<ArrayList<Integer>, Integer> filteredSeqSet =
new HashMap<ArrayList<Integer>, Integer>();
iter = confirmedSeqSet.keySet().iterator();
while (iter.hasNext()) {
ArrayList<Integer> seq = iter.next();
int size = confirmedSeqSet.get(seq);
if (size == nConfirmedMax) {
filteredSeqSet.put(seq, size);
}
}
return filteredSeqSet;
}
private ArrayList<Integer> findConfirmedSeq() {
ArrayList<Integer> confirmedSeq = new ArrayList<Integer>();
for (int i = 0; i < n; i++) {
if (confirmed[i] > 0) {
confirmedSeq.add(i);
}
}
return confirmedSeq;
}
private ArrayList<Integer> findRemainingSeq() {
ArrayList<Integer> remainingSeq = new ArrayList<Integer>();
for (int i = 0; i < n; i++) {
if (confirmed[i] > 0) {
remainingSeq.add(i);
}
}
return remainingSeq;
}
private boolean conflictReduceDone(ArrayList<Integer> rowsConflictMax) {
for (int i = 0; i < n; i++) {
if (conflictCounter[i] > 0) {
return false;
}
}
return rowsConflictMax.isEmpty();
}
private ArrayList<int[]> reduceRow(int row) {
ArrayList<int[]> reducedRowCells = new ArrayList<int[]>();
for (int j = 0; j < n; j++) {
int conflict = conflictMatrix[row][j];
int reduced = conflictReduced[row][j];
if (reduced <= 0) {
int tuple[] = new int[3];
tuple[0] = row;
tuple[1] = j;
tuple[2] = conflict;
reducedRowCells.add(tuple);
conflictReduced[row][j] = 1;
if (conflict > 0) {
conflictCounter[row] -= 1;
assert conflictCounter[row] >= 0;
}
}
}
return reducedRowCells;
}
private ArrayList<int[]> reduceCol(int col) {
ArrayList<int[]> reducedColCells = new ArrayList<int[]>();
for (int i = 0; i < n; i++) {
int conflict = conflictMatrix[i][col];
int reduced = conflictReduced[i][col];
if (reduced <= 0) {
int tuple[] = new int[3];
tuple[0] = i;
tuple[1] = col;
tuple[2] = conflict;
reducedColCells.add(tuple);
conflictReduced[i][col] = 1;
if (conflict > 0) {
conflictCounter[i] -= 1;
assert conflictCounter[i] >= 0;
}
}
}
return reducedColCells;
}
private void recovRow(ArrayList<int[]> reducedRowCells) {
int size = reducedRowCells.size();
for (int i = 0; i < size; i++) {
int[] tuple = reducedRowCells.get(i);
int row = tuple[0];
int col = tuple[1];
int conflict = tuple[2];
conflictReduced[row][col] = 0;
if (conflict > 0) {
conflictCounter[row] += 1;
assert conflictCounter[row] <= n;
}
}
}
private void recovCol(ArrayList<int[]> reducedColCells) {
int size = reducedColCells.size();
for (int i = 0; i < size; i++) {
int[] tuple = reducedColCells.get(i);
int row = tuple[0];
int col = tuple[1];
int conflict = tuple[2];
conflictReduced[row][col] = 0;
if (conflict > 0) {
conflictCounter[row] += 1;
assert conflictCounter[row] <= n;
}
}
}
private boolean reducedRow(int row) {
return confirmed[row] == 0;
}
private boolean conflictSaturated(int nRemainingRows) {
for (int i = 0; i < n; i++) {
if (reducedRow(i)) {
continue;
}
if (conflictCounter[i] != nRemainingRows - 1) {
return false;
}
}
return true;
}
private long getSearchingStat() {
long retval = 0L;
for (int i = 0; i < n; i++) {
retval = (retval<<1) + confirmed[i];
}
return retval;
}
public void conflictReduce() {
ArrayList<Integer> remainingRows = findRemainingSeq();
int nRemainingRows = remainingRows.size();
if (conflictSaturated(nRemainingRows)) {
for (int i = 0; i < nRemainingRows; i++) {
ArrayList<Integer> seq = new ArrayList<Integer>();
seq.add(remainingRows.get(i));
if (!confirmedSeqSet.containsKey(seq)) {
confirmedSeqSet.put(seq, 1);
}
}
return;
}
if (nRemainingRows < nConfirmedMaxCurr) {
return;
}
ArrayList<Integer> rowsConflictMax = findRowsConflictMax();
if (conflictReduceDone(rowsConflictMax)) {
ArrayList<Integer> confirmedSeq = findConfirmedSeq();
int size = confirmedSeq.size();
if (!confirmedSeqSet.containsKey(confirmedSeq)) {
confirmedSeqSet.put(confirmedSeq, size);
}
if (size > nConfirmedMaxCurr) {
nConfirmedMaxCurr = size;
}
return;
}
int nRowsConflictMax = rowsConflictMax.size();
for (int i = 0; i < nRowsConflictMax; i++) {
int row = rowsConflictMax.get(i);
int col = rowsConflictMax.get(i);
confirmed[row] = 0;
long stat = getSearchingStat();
if (visited.containsKey(stat)){
confirmed[row] = 1;
continue;
}
ArrayList<int[]> reducedRowCells = reduceRow(row);
ArrayList<int[]> reducedColCells = reduceCol(col);
visited.put(stat, 1);
conflictReduce();
confirmed[row] = 1;
recovRow(reducedRowCells);
recovCol(reducedColCells);
}
}
public ArrayList<Integer> work() {
ArrayList<Integer> seq = new ArrayList<Integer>();
if (n <= 0) {
return seq;
}
init();
conflictReduce();
HashMap<ArrayList<Integer>, Integer> filteredSeqSet =
filterInvalidSeq();
Iterator<ArrayList<Integer>> iter =
filteredSeqSet.keySet().iterator();
/*
while (iter.hasNext()) {
seq = iter.next();
for (int i = 0; i < seq.size() - 1; i++) {
System.out.print(seq.get(i)+" ");
}
System.out.println(seq.get(seq.size()-1));
}
*/
if (iter.hasNext()) {
seq = iter.next();
}
return seq;
}
public static void main(String args[]) {
int conflictMatrix[][] = {
{0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}
};
int n = 20;
ConflictReducer conflictReducer = new ConflictReducer(conflictMatrix, n);
conflictReducer.work();
}
}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
public class ConflictReducer {
protected boolean MultiSolutionsSupported;
public int conflictMatrix[][];
public int n;
public int conflictReduced[][];
public int conflictCounter[];
public int confirmed[];
public HashMap<ArrayList<Integer>, Integer> confirmedSeqSet;
public int nConfirmedMaxCurr;
public HashMap<Long, Integer> visited;
public ConflictReducer(int conflictMatrix[][], int n) {
this.MultiSolutionsSupported = true;
this.conflictMatrix = conflictMatrix;
this.n = n;
}
private void init() {
this.conflictReduced = new int[n][n];
this.conflictCounter = new int[n];
this.confirmed = new int[n];
this.confirmedSeqSet = new HashMap<ArrayList<Integer>, Integer>();
this.nConfirmedMaxCurr = 0;
this.visited = new HashMap<Long, Integer>();
for (int i = 0; i < n; i++) {
this.conflictCounter[i] = 0;
this.confirmed[i] = 1;
for (int j = 0; j < n; j++) {
this.conflictReduced[i][j] = 0;
if (this.conflictMatrix[i][j] > 0) {
this.conflictCounter[i] += 1;
}
}
}
}
private ArrayList<Integer> findRowsConflictMax() {
ArrayList<Integer> rows = new ArrayList<Integer>();
int conflictMax = 0;
for (int i = 0; i < n; i++) {
if (conflictCounter[i] > conflictMax) {
conflictMax = conflictCounter[i];
}
}
for (int i = 0; i < n; i++) {
if (conflictCounter[i] > 0 && conflictCounter[i] == conflictMax) {
rows.add(i);
}
}
return MultiSolutionsSupported? rows: (rows.size() > 0? new ArrayList<Integer>(rows.subList(0, 1)): rows);
}
private HashMap<ArrayList<Integer>, Integer> filterInvalidSeq() {
Iterator<ArrayList<Integer>> iter =
confirmedSeqSet.keySet().iterator();
int nConfirmedMax = 0;
while (iter.hasNext()) {
ArrayList<Integer> seq = iter.next();
int size = confirmedSeqSet.get(seq);
if (size > nConfirmedMax) {
nConfirmedMax = size;
}
}
HashMap<ArrayList<Integer>, Integer> filteredSeqSet =
new HashMap<ArrayList<Integer>, Integer>();
iter = confirmedSeqSet.keySet().iterator();
while (iter.hasNext()) {
ArrayList<Integer> seq = iter.next();
int size = confirmedSeqSet.get(seq);
if (size == nConfirmedMax) {
filteredSeqSet.put(seq, size);
}
}
return filteredSeqSet;
}
private ArrayList<Integer> findConfirmedSeq() {
ArrayList<Integer> confirmedSeq = new ArrayList<Integer>();
for (int i = 0; i < n; i++) {
if (confirmed[i] > 0) {
confirmedSeq.add(i);
}
}
return confirmedSeq;
}
private ArrayList<Integer> findRemainingSeq() {
ArrayList<Integer> remainingSeq = new ArrayList<Integer>();
for (int i = 0; i < n; i++) {
if (confirmed[i] > 0) {
remainingSeq.add(i);
}
}
return remainingSeq;
}
private boolean conflictReduceDone(ArrayList<Integer> rowsConflictMax) {
for (int i = 0; i < n; i++) {
if (conflictCounter[i] > 0) {
return false;
}
}
return rowsConflictMax.isEmpty();
}
private ArrayList<int[]> reduceRow(int row) {
ArrayList<int[]> reducedRowCells = new ArrayList<int[]>();
for (int j = 0; j < n; j++) {
int conflict = conflictMatrix[row][j];
int reduced = conflictReduced[row][j];
if (reduced <= 0) {
int tuple[] = new int[3];
tuple[0] = row;
tuple[1] = j;
tuple[2] = conflict;
reducedRowCells.add(tuple);
conflictReduced[row][j] = 1;
if (conflict > 0) {
conflictCounter[row] -= 1;
assert conflictCounter[row] >= 0;
}
}
}
return reducedRowCells;
}
private ArrayList<int[]> reduceCol(int col) {
ArrayList<int[]> reducedColCells = new ArrayList<int[]>();
for (int i = 0; i < n; i++) {
int conflict = conflictMatrix[i][col];
int reduced = conflictReduced[i][col];
if (reduced <= 0) {
int tuple[] = new int[3];
tuple[0] = i;
tuple[1] = col;
tuple[2] = conflict;
reducedColCells.add(tuple);
conflictReduced[i][col] = 1;
if (conflict > 0) {
conflictCounter[i] -= 1;
assert conflictCounter[i] >= 0;
}
}
}
return reducedColCells;
}
private void recovRow(ArrayList<int[]> reducedRowCells) {
int size = reducedRowCells.size();
for (int i = 0; i < size; i++) {
int[] tuple = reducedRowCells.get(i);
int row = tuple[0];
int col = tuple[1];
int conflict = tuple[2];
conflictReduced[row][col] = 0;
if (conflict > 0) {
conflictCounter[row] += 1;
assert conflictCounter[row] <= n;
}
}
}
private void recovCol(ArrayList<int[]> reducedColCells) {
int size = reducedColCells.size();
for (int i = 0; i < size; i++) {
int[] tuple = reducedColCells.get(i);
int row = tuple[0];
int col = tuple[1];
int conflict = tuple[2];
conflictReduced[row][col] = 0;
if (conflict > 0) {
conflictCounter[row] += 1;
assert conflictCounter[row] <= n;
}
}
}
private boolean reducedRow(int row) {
return confirmed[row] == 0;
}
private boolean conflictSaturated(int nRemainingRows) {
for (int i = 0; i < n; i++) {
if (reducedRow(i)) {
continue;
}
if (conflictCounter[i] != nRemainingRows - 1) {
return false;
}
}
return true;
}
private long getSearchingStat() {
long retval = 0L;
for (int i = 0; i < n; i++) {
retval = (retval<<1) + confirmed[i];
}
return retval;
}
public void conflictReduce() {
ArrayList<Integer> remainingRows = findRemainingSeq();
int nRemainingRows = remainingRows.size();
if (conflictSaturated(nRemainingRows)) {
for (int i = 0; i < nRemainingRows; i++) {
ArrayList<Integer> seq = new ArrayList<Integer>();
seq.add(remainingRows.get(i));
if (!confirmedSeqSet.containsKey(seq)) {
confirmedSeqSet.put(seq, 1);
}
}
return;
}
if (nRemainingRows < nConfirmedMaxCurr) {
return;
}
ArrayList<Integer> rowsConflictMax = findRowsConflictMax();
if (conflictReduceDone(rowsConflictMax)) {
ArrayList<Integer> confirmedSeq = findConfirmedSeq();
int size = confirmedSeq.size();
if (!confirmedSeqSet.containsKey(confirmedSeq)) {
confirmedSeqSet.put(confirmedSeq, size);
}
if (size > nConfirmedMaxCurr) {
nConfirmedMaxCurr = size;
}
return;
}
int nRowsConflictMax = rowsConflictMax.size();
for (int i = 0; i < nRowsConflictMax; i++) {
int row = rowsConflictMax.get(i);
int col = rowsConflictMax.get(i);
confirmed[row] = 0;
long stat = getSearchingStat();
if (visited.containsKey(stat)){
confirmed[row] = 1;
continue;
}
ArrayList<int[]> reducedRowCells = reduceRow(row);
ArrayList<int[]> reducedColCells = reduceCol(col);
visited.put(stat, 1);
conflictReduce();
confirmed[row] = 1;
recovRow(reducedRowCells);
recovCol(reducedColCells);
}
}
public ArrayList<Integer> work() {
ArrayList<Integer> seq = new ArrayList<Integer>();
if (n <= 0) {
return seq;
}
init();
conflictReduce();
HashMap<ArrayList<Integer>, Integer> filteredSeqSet =
filterInvalidSeq();
Iterator<ArrayList<Integer>> iter =
filteredSeqSet.keySet().iterator();
/*
while (iter.hasNext()) {
seq = iter.next();
for (int i = 0; i < seq.size() - 1; i++) {
System.out.print(seq.get(i)+" ");
}
System.out.println(seq.get(seq.size()-1));
}
*/
if (iter.hasNext()) {
seq = iter.next();
}
return seq;
}
public static void main(String args[]) {
int conflictMatrix[][] = {
{0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}
};
int n = 20;
ConflictReducer conflictReducer = new ConflictReducer(conflictMatrix, n);
conflictReducer.work();
}
}