Creating node with weight in java graph - java

I am creating a program to create a graph for bibliography dataset. The graph is directed, has Author node and Paper node, and has 2 types of edges (author to paper edge, paper to paper edge).
I want to get an input from you about whether or not what I am creating is making sense. Right now, it produces the right result when I want to get the outEdge and inEdge from and to a node. But im not sure if this implementation is correct in terms of the methods, designs, and algorithm.
Also, I have a problem with assigning weight to a node. I want to ask how can I do this as well. Right now, what I have tried is as follows:
for (String item : CandidateAuthorType1Unique) {
double weight = Collections.frequency(CandidateAuthorType1, item);
n.setWeight(item,weight);;
System.out.println(n.getName() + " : " + n.getWeight());
}
However, after using setWeight, the getName() method returns null. This means that the weight assigned is not assigned to a certain item. I wonder how to update the weight a certain item.
If I use
for (String item : CandidateAuthorType1Unique) {
double weight = Collections.frequency(CandidateAuthorType1, item);
n = new Node(item,weight);
System.out.println(n.getName() + " : " + n.getWeight());
}
Does it mean that each time a new node n is created, the old n node will not be stored? How can I checked every node ever created and its weight?
I would like to ask for your input to this program. Any input would be really helpful for me. Thank you.
Main class: Ranker.java
import java.util.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.sql.*;
public class Ranker {
static Graph g;
static Node n;
static Edge e;
static HashMap nodeMap; // maps Integer NodeIDs to Node object
String id;
double weight;
Ranker() {
g = new Graph();
nodeMap = new HashMap();
n = new Node(id,weight);
}
public static void main (String[] args) throws ClassNotFoundException, SQLException, IOException, IllegalArgumentException, IllegalAccessException{
Ranker Ranker = new Ranker();
Connection connect = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
HashMap nodeMap = new HashMap(); // maps Integer NodeIDs to Node objects
Class.forName("com.mysql.jdbc.Driver");
connect = DriverManager.getConnection("jdbc:mysql://localhost/arnetminer?"+"user=root&password=1234");
preparedStatement = connect.prepareStatement("Select fr,t,ty from subedge");
resultSet = preparedStatement.executeQuery();
int i=0;
while(resultSet.next()) {
g.addEdgeForIndexing(resultSet.getInt(1),resultSet.getInt(2),resultSet.getInt(3));
i++;
System.out.println( "edges added to G = "+i);
}
System.out.println("Loaded " + g.nodeCount() + " nodes.");
buildNodes();
System.out.println("Enter first author key:");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String authorkey1 = br.readLine();
int authorID1 = Integer.parseInt(authorkey1);
String AuthorID1 = "A"+authorID1;
ArrayList<String> p1 = g.getOutEdgesToP(AuthorID1);
System.out.println("P1 = " + p1);
ArrayList<String> p2 = new ArrayList<String>();
for (int j = 0; j<p1.size();j++){
ArrayList<String> temp = g.getOutEdgesToP(p1.get(j));
if (temp!=null)
p2.addAll(temp);
}
System.out.println("P2 = " +p2);
ArrayList<String> CandidateAuthorType1 = new ArrayList<String>();
for (int k = 0; k<p2.size(); k++){
ArrayList<String> temp = g.getInEdgesFromPtoA(p2.get(k));
if(temp!=null)
CandidateAuthorType1.addAll(temp);
}
System.out.println("Candidate Author Type 1= " + CandidateAuthorType1);
ArrayList<String> CandidateAuthorType1Unique = removeDuplicates(CandidateAuthorType1);
System.out.println("-----------------------------------------------");
System.out.println("Candidate author type 1 and author node weight:");
for (String item : CandidateAuthorType1Unique) {
double weight = Collections.frequency(CandidateAuthorType1, item);
n.setWeight(item,weight);;
System.out.println(n.getName() + " : " + n.getWeight());
}
ArrayList<String> CandidatePaperType1 = new ArrayList<String>();
for (int l = 0; l<CandidateAuthorType1.size(); l++){
ArrayList<String> temp = g.getOutEdgesToP(CandidateAuthorType1.get(l));
if(temp!=null)
CandidatePaperType1.addAll(temp);
}
System.out.println("Candidate Paper Type 1= " + CandidatePaperType1);
}
private static ArrayList<String> removeDuplicates(ArrayList<String> element){
ArrayList<String> result = new ArrayList<>();
HashSet<String> set = new HashSet<>();
for (String item : element) {
if (!set.contains(item)) {
result.add(item);
set.add(item);
}
}
return result;
}
private static void buildNodes()
{
String nodeID;
double weight = 0;
Node n;
Iterator it = g.nodeIteratorInitial();
while (it.hasNext()) {
nodeID = (String) it.next();
if (!nodeMap.containsKey(nodeID)){
n = new Node(nodeID,weight);
nodeMap.put(nodeID, 0);
}
}
}
}
Graph.java
import java.lang.reflect.Field;
import java.util.*;
public class Graph {
private HashSet<String> nodeIDs;
public HashMap<Integer, String> nodeIDsWithTN;
public HashMap<Integer, String> TNMap;
private HashMap<String, ArrayList<String>> edges;
private HashMap<String, ArrayList<String>> reverse;
private int numNodes;
private int numEdges;
private int numReverse;
public Graph() {
edges = new HashMap<String, ArrayList<String>>();
reverse = new HashMap<String, ArrayList<String>>();
nodeIDs = new HashSet<String>();
nodeIDsWithTN = new HashMap<Integer, String>();
TNMap = new HashMap<Integer, String>();
new HashSet();
}
public void addEdgeForIndexing(int from, int to, int T) throws IllegalArgumentException, IllegalAccessException {
String From = ""+from;
String To = ""+to;
int type = T;
if(T==1)
{
From="A"+from;
To="P"+to;
}
else if(T==2)
{
From="P"+from;
To="P"+to;
}
else
System.out.println("T ="+T+" value undefined");
Edge e = new Edge(From,To,type);
nodeIDs.add(e.From);
nodeIDs.add(e.To);
ArrayList<String> tmp = null;
if (edges.containsKey(e.From))
tmp = (ArrayList<String>) edges.get(e.From);
else {
tmp = new ArrayList<String>();
edges.put(e.From,tmp);
}
tmp.add(e.To);
ArrayList<String> tmp2 = null;
if (reverse.containsKey(e.To))
tmp2 = (ArrayList<String>) reverse.get(e.To);
else {
tmp2 = new ArrayList<String>();
reverse.put(e.To,tmp2);
}
tmp2.add(e.From);
}
public int nodeCount() {
if(nodeIDs.size() > 0)
return nodeIDs.size();
// else return numNodes;
return numEdges;
}
public int countInEdges(Integer key) {
if (!reverse.containsKey(key)) return 0;
return ((ArrayList<?>) reverse.get(key)).size();
}
public int countOutEdges(Integer key) {
if (!edges.containsKey(key)) return 0;
return ((ArrayList<?>) edges.get(key)).size();
}
public ArrayList<String> getInEdgesFromPtoA(String id) {
if (!reverse.containsKey(id)) return null;
ArrayList<String> a = reverse.get(id);
ArrayList<String> result = new ArrayList<String>();
for(int j=0;j<a.size();j++){
if(a.get(j).startsWith("A")){
result.add(a.get(j));
}
}
return result;
}
public ArrayList<String> getOutEdgesToP(String id) {
if (!edges.containsKey(id)) return null;
ArrayList<String> a = edges.get(id);
ArrayList<String> result = new ArrayList<String>();
for(int j=0;j<a.size();j++){
if(a.get(j).startsWith("P")){
result.add(a.get(j));
}
}
return result;
}
public Iterator<String> nodeIteratorInitial() {
return nodeIDs.iterator();
}
}
Edge.java
public class Edge {
String From;
String To;
int type;
private static int counter = 0;
public Edge(String From, String To, int type) {
this.From = new String(From);
this.To = new String(To);
this.type = type;
// System.out.println("edges added from " + From + " to " + To + " with type "+ type);
}
public String getFrom(){
return From;
}
public String getTo(){
return To;
}
public int getType(){
return type;
}
public void setFrom(String From){
this.From = From;
}
public void setTo(String To){
this.To = To;
}
public void setType(int type){
this.type = type;
}
}
Node.java
public class Node {
String id;
double weight;
private static int counter = 0;
public Node(String id,double weight) {
this.id = id;
this.weight = weight;;
}
public double getWeight(){
return weight;
}
public String getName() {
return id;
}
public void setWeight(String id, double weight){
if (this.id==id){
this.weight=weight;}
System.out.println("The node " + id + " has weight " + weight);
}
public void setName(String id){
this.id=id;
}
}

As you are initialising n in the Ranker() constructor, when the constructor is called, the String id has not been assigned and therefore always contains the value null. Therefore your Node n also gets the id as null. This is the reason why the weight isn't updated as in your setWeight(String id, double weight) function, the new id is compared to null which always returns false therefore the weight doesn't get updated.
You could make the following changes in your code
1) Remove the n = new Node(id,weight) initialisation in your Ranker() constructor.
2) Add the following lines instead of n.setWeight(item,weight) in your main method in Ranker class.
if (n == null)
n = new Node(item, weight);
n.setWeight(item, weight);

Related

Library book sorting

I am in a java programming class and I cannot figure how to fix this error.
This is the error I keep getting:
Library.java:120: error: class, interface, or enum expected
import java.util.ArrayList;
^
1 error
This is the task
Two sorted lists have been created, one implemented using a linked list (LinkedListLibrary linkedListLibrary) and the other implemented using the built-in ArrayList class (ArrayListLibrary arrayListLibrary). Each list contains 100 books (title, ISBN number, author), sorted in ascending order by ISBN number.
Complete main() by inserting a new book into each list using the respective LinkedListLibrary and ArrayListLibrary insertSorted() methods and outputting the number of operations the computer must perform to insert the new book. Each insertSorted() returns the number of operations the computer performs.
Ex: If the input is:
The Catcher in the Rye
9787543321724
J.D. Salinger
the output is:
Number of linked list operations: 1
Number of ArrayList operations: 1
This is my code:
import java.util.Scanner;
import java.io.FileInputStream;
import java.io.IOException;
public class Library {
public static void fillLibraries(LinkedListLibrary linkedListLibrary, ArrayListLibrary arrayListLibrary) throws IOException {
FileInputStream fileByteStream = null; // File input stream
Scanner inFS = null; // Scanner object
int linkedListOperations = 0;
int arrayListOperations = 0;
BookNode currNode;
Book tempBook;
String bookTitle;
String bookAuthor;
long bookISBN;
// Try to open file
fileByteStream = new FileInputStream("Books.txt");
inFS = new Scanner(fileByteStream);
while (inFS.hasNextLine()) {
bookTitle = inFS.nextLine();
bookISBN = inFS.nextLong();
inFS.nextLine();
bookAuthor = inFS.nextLine();
// Insert into linked list
currNode = new BookNode(bookTitle, bookAuthor, bookISBN);
linkedListOperations = linkedListLibrary.insertSorted(currNode, linkedListOperations);
linkedListLibrary.lastNode = currNode;
// Insert into ArrayList
tempBook = new Book(bookTitle, bookAuthor, bookISBN);
arrayListOperations = arrayListLibrary.insertSorted(tempBook, arrayListOperations);
}
fileByteStream.close(); // close() may throw IOException if fails
}
public static void main (String[] args) throws IOException {
Scanner scnr = new Scanner(System.in);
int linkedListOperations = 0;
int arrayListOperations = 0;
// Create libraries
LinkedListLibrary linkedListLibrary = new LinkedListLibrary();
ArrayListLibrary arrayListLibrary = new ArrayListLibrary();
// Fill libraries with 100 books
fillLibraries(linkedListLibrary, arrayListLibrary);
// Create new book to insert into libraries
BookNode currNode;
Book tempBook;
String bookTitle;
String bookAuthor;
long bookISBN;
bookTitle = scnr.nextLine();
bookISBN = scnr.nextLong();
scnr.nextLine();
bookAuthor = scnr.nextLine();
// Insert into linked list
currNode = new BookNode(bookTitle, bookAuthor, bookISBN);
// TODO
int i = linkedListLibrary.insertSorted(currNode,0);
linkedListLibrary.lastNode = currNode;
// Insert into ArrayList
tempBook = new Book(bookTitle, bookAuthor, bookISBN);
// TODO
int j = arrayListLibrary.insertSorted(tempBook,0);
// TODO: Print number of operations for linked list
System.out.println("Number of operations for linked list : "+i);
// TODO: Print number of operations for ArrayList
System.out.println("Number of operations for ArrayList : "+j);
}
}
// Book.java
public class Book{
private String bookTitle;
private String bookAuthor;
private long bookISBN;
public Book() {
bookTitle = "";
bookAuthor = "";
bookISBN = 0;
}
public Book(String userBookTitle, String userBookAuthor, long userBookISBN) {
bookTitle = userBookTitle;
bookAuthor = userBookAuthor;
bookISBN = userBookISBN;
}
public long getBookISBN() {
return bookISBN;
}
public void printInfo(){
System.out.println("Title: " + bookTitle);
System.out.println("Author: " + bookAuthor);
System.out.println("ISBN: " + bookISBN);
}
}
// ArrayListLibrary.java
import java.util.ArrayList;
public class ArrayListLibrary {
// ArraryList library
public ArrayList<Book> library;
public ArrayListLibrary() {
library = new ArrayList<Book>();
}
public int insertSorted(Book newBook, int counter) {
Book currBook;
// Add an empty element at end of list
library.add(null);
// Loop through elements starting at the end
for (int i = library.size() - 2; i >=0; --i) {
currBook = library.get(i);
// If the current book's ISBN is larger than newBook's ISBN, shift
// the current book down 1, count shift operation
if(currBook.getBookISBN() > newBook.getBookISBN()){
library.set(i+1, currBook);
++counter;
}
// Otherwise, place newBook at the next location (empty slot),
// count insert operation
else {
library.set(i+1, newBook);
++counter;
return counter;
}
}
// If we get to the top of the list, place newBook on top
library.set(0, newBook);
++counter;
return counter;
}
public void printLibrary() {
for (int i = 0; i < library.size(); ++i) {
library.get(i).printInfo();
System.out.println();
}
}
}
// BookNode.java
public class BookNode {
private String bookTitle;
private String bookAuthor;
private long bookISBN;
private BookNode nextNodePtr; // Reference to the next node
public BookNode() {
bookTitle = "";
bookAuthor = "";
bookISBN = 0;
nextNodePtr = null;
}
// Constructor
public BookNode(String bookTitleInit, String bookAuthorInit, long bookISBNInit) {
this.bookTitle = bookTitleInit;
this.bookAuthor = bookAuthorInit;
this.bookISBN = bookISBNInit;
this.nextNodePtr = null;
}
// Constructor
public BookNode(String bookTitleInit, String bookAuthorInit, long bookISBNInit, BookNode nextLoc) {
this.bookTitle = bookTitleInit;
this.bookAuthor = bookAuthorInit;
this.bookISBN = bookISBNInit;
this.nextNodePtr = nextLoc;
}
// insertAfter
public void insertAfter(BookNode nodeLoc) {
BookNode tmpNext;
tmpNext = this.nextNodePtr;
this.nextNodePtr = nodeLoc;
nodeLoc.nextNodePtr = tmpNext;
}
//setNext
public void setNext(BookNode nodeLoc) {
this.nextNodePtr = nodeLoc;
}
// Get location pointed by nextNodePtr
public BookNode getNext() {
return this.nextNodePtr;
}
public long getBookISBN() {
return this.bookISBN;
}
// TODO: Print book information
public void printBookInfo() {
System.out.println("Title: " + this.bookTitle);
System.out.println("Author: " + this.bookAuthor);
System.out.println("ISBN: " + this.bookISBN);
}
}
// LinkedListLibrary.java
public class LinkedListLibrary {
//Linked list nodes
BookNode headNode;
BookNode lastNode;
LinkedListLibrary() {
// Front of nodes list
headNode = new BookNode();
lastNode = headNode;
}
public int insertSorted(BookNode newNode, int counter) {
BookNode currNode, nextNode;
// Special case for head node
if (headNode == null || headNode.getBookISBN() >= newNode.getBookISBN()) {
newNode.insertAfter(headNode);
headNode = newNode;
}
else {
// Locate the node before insertion point
currNode = headNode;
while (currNode.getNext() != null && currNode.getNext().getBookISBN() < newNode.getBookISBN()) {
currNode = currNode.getNext();
}
newNode.setNext(currNode.getNext());
currNode.insertAfter(newNode);
}
++counter;
return counter;
}
public void printLibrary() {
BookNode currNode;
currNode = headNode.getNext();
while (currNode != null) {
currNode.printBookInfo();
System.out.println();
currNode = currNode.getNext();
}
}
}
Did the same lab. They make it seem intimidating with the amount of files and text thrown at you, but to pass the lab you just need to add the two lines to the end of Library.java:
System.out.println("Number of linked list operations: " + linkedListLibrary.insertSorted(currNode, linkedListOperations));
System.out.println("Number of ArrayList operations: " + arrayListLibrary.insertSorted(tempBook, arrayListOperations));
To explain:
The lab was to help you go through established code and read its set methods to learn how to do work in a class you haven't made. If you followed the development stubs (#TODO's) you would trace the path to finding what you need to do. This is what leads to the solution in this case!

Access a class's fields and methods to retrieve a field with some value

I'm trying to access a document class that has id, name, text and list of words. I try to compare a document id which I have with the ids and when found get the list of words attached to this id to find exact word and return its frequency.
Any help is highly appreciated.
public class Doc {
private int documentID;
private static Doc docInstance = null;
private String documentText;
private ArrayList<String> listOfTokens;
static int docCount = 0;
int tokFreq = 0;
public Doc() {
documentID = 0;
listOfTokens = new ArrayList<String>();
tokFreq = 0;
docCount++;
}
public static Doc getDocInstance() {
if (docInstance == null) {
docInstance = new Doc();
}
return docInstance;
}
public ArrayList<String> getListOfTokens() {
return listOfTokens;
}
public void setDocumentID(int x){
if (getDocumentID() != x)
this.documentID = x;
}
}
and I am trying this
public static void createDocumentVector(TreeMap<Integer,Integer>
documentVector, TreeMap<String, ArrayList<Integer>>qm, int N)
{
int eachDoc = 0;
Collection<String> allKeys = qm.keySet();
ArrayList<Integer> l1 = new ArrayList<Integer>();
boolean addedTerm = false;
/**
Obtain an Iterator for Collection
*/
Iterator<String> itr = allKeys.iterator();
String key;
int termFrequency = 0;
int documentFrequency = 0;
/**
Iterate through TreeMap values iterator
*/
while(itr.hasNext())
{
key = (String)itr.next();
Integer LL = 0;
l1 = qm.get(key); // Returns value of that key
for (int k = 0; k < l1.size(); k++)
{
LL = l1.get(k);
Doc doc = new Doc();
doc.getDocInstance().setDocumentID(LL);
int size = doc.getListOfTokens().size();
String[] docIdTokens = doc.getListOfTokens().toArray(new String[size]);
for (String s : docIdTokens){
if(s.equalsIgnoreCase(key)){
termFrequency++;
}
}
documentFrequency = l1.size();
eachDoc = getTFIDF(termFrequency, documentFrequency, N);
documentVector.put(eachDoc, LL);
}
}
}
It doesn't run completely and gives source not found, in debugging.
I am thinking to change class Doc into this:
public class Doc<ListOfTokens> {
private static int documentID;
private static Doc docInstance = null;
private String documentName;
private String documentText;
private HashMap<String, Integer> ListOfTokens = new HashMap<String, Integer>();
private TreeMap<Integer, ListOfTokens> documentMap = new TreeMap<Integer, ListOfTokens>();
int tokFreq = 0;
static int docCount = 0;
-----
}
but this would be a bit complicated I think. So any suggestions would be a great help.
You don't need to use the keyword static for the documentID property of class Doc. Since you are expecting that there will be multiple doc objects and each needs to have their own value for documentID, you need to use documentID as a non-static field.

java - Error casting Set.toArray() as Object[]

I am attempting to grab a random element from a Set of custom Objects (Space) and receiving an error in doing so.
Space[][][][] spaces = new Space[dim][dim][dim][dim];
Set<Space> spaceSet = new HashSet<Space>();
for(int i=0; i<dim; i++)
for(int j=0; j<dim; j++)
for(int k=0; k<dim; k++)
for(int l=0; l<dim; l++) {
spaces[i][j][k][l] = new Space(i,j,k,l);
spaceSet.add(spaces[i][j][k][l]);
}
...
Space s = null;
...
s = (Space[])spaceSet.toArray()[rand.nextInt(spaceSet.size())]; //This line throws the error
Error:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [LSpace;
at Maze.generatePath(Maze.java:45)
at Maze4D.main(Maze4D.java:15)
An array of Objects cannot be cast to an array of Foos. You will need to iterate over the array and cast each member individually. (Better yet, properly use generics / polymorphism and don't cast.)
Because as the docs point out, toArray() returns an Object[]
You need to use the other toArray(T[] a) if you want the type inferred:
s = spaceSet.toArray(new Space[0])[rand.nextInt(spaceSet.size())];
(The supplied array in this case is just being used for the type inference; toArray() is returning a new Space[] of the appropriate size)
When trying to work with Random size/space. Its always a better idea to use a map instead of arrays going down several levels. Here is an example of the something similar where you could set/get values with minimal boiler plate code.
import java.util.*;
public class SmartPropertyReader {
private SmartPropertyReader parent;
protected final String PRESERVE_MAP = "PRESERVE_MAP";
protected final String PRESERVE_LIST = "PRESERVE_LIST";
private String preserveType;
protected Map<String, SmartPropertyReader> map = new HashMap<String, SmartPropertyReader>();
protected Object value;
protected List<SmartPropertyReader> list = new ArrayList<SmartPropertyReader>();
public SmartPropertyReader(){
this.parent = null;
}
public SmartPropertyReader(SmartPropertyReader parent, String preserveType) {
this.parent = parent;
this.preserveType = preserveType;
}
public SmartPropertyReader get(String key) {
SmartPropertyReader subProp = map.get(key);
if(subProp == null){
subProp = new SmartPropertyReader(this, PRESERVE_MAP);
map.put(key, subProp) ;
}
return subProp;
}
public void setValue(Object passedValue) {
list.clear();
map.clear();
if(passedValue instanceof SmartPropertyReader){
this.map = ((SmartPropertyReader) passedValue).map;
this.list = ((SmartPropertyReader) passedValue).list;
}else{
this.value = passedValue;
}
SmartPropertyReader currPropertyReader = this;
while(currPropertyReader != null){
String preserveType = currPropertyReader.preserveType;
currPropertyReader = currPropertyReader.parent;
if(PRESERVE_MAP.equals(preserveType)){
currPropertyReader.clearList();
currPropertyReader.clearValue();
}else if(PRESERVE_LIST.equals(preserveType)){
currPropertyReader.clearValue();
currPropertyReader.clearMap();
}
}
}
protected void clearList(){
list.clear();
}
protected void clearMap(){
map.clear();
}
protected void clearValue(){
this.value = null;
}
public Object getValue() {
if(this.value == null){
SmartPropertyReader currPropertyReader = parent;
while(currPropertyReader != null){
String preserveType = currPropertyReader.preserveType;
if(PRESERVE_MAP.equals(preserveType)){
currPropertyReader.clearMap();
}else if(PRESERVE_LIST.equals(preserveType)){
currPropertyReader.clearList();
}
currPropertyReader = currPropertyReader.parent;
}
}
return this.value;
}
public SmartPropertyReader get(int index) {
while(list.size() <= index ){
list.add(null);
}
SmartPropertyReader subProp = list.get(index);
if(subProp == null){
subProp = new SmartPropertyReader(this, PRESERVE_LIST);
}
list.set(index, subProp);
return subProp;
}
public String toString(){
String retString = "";
if(value != null){
retString = value.toString();
if(value instanceof String){
retString = "\"" + retString + "\"";
}
}
if(list.size() > 0){
String listStr = listString();
if(!listStr.equals(""))
retString = "[" + listString() + "]";
}
if(map.size() > 0){
String mapStr = mapString();
if(!mapStr.equals(""))
retString = "{" +mapString() + "}";
}
return retString;
}
private String listString (){
String str = "";
boolean first = true;
for(SmartPropertyReader rblt: list){
if(rblt != null ){
String subStr = rblt.toString();
if(!subStr.equals("")){
if(!first)
str += ", ";
str += subStr;
first = false;
}
}
}
return str;
}
private String mapString(){
String str ="";
boolean first = true;
for(String key: map.keySet()){
SmartPropertyReader rblt = map.get(key);
if(rblt != null){
String subStr = rblt.toString();
if(!subStr.equals("")){
if(!first)
str += ", ";
str += "\""+key + "\": " + subStr;
first = false;
}
}
}
return str;
}
public static void main(String[] args) {
SmartPropertyReader propertyReader = new SmartPropertyReader();
propertyReader.get("Test").get("2nd key").get("A number value").setValue(10);
propertyReader.get("Test").get("a key").get(1).get(2).setValue(100);
propertyReader.get("Test").get("a key").get(1).get(3).setValue(100.345);
propertyReader.get("Test").get("a key").get(2).get("Nice").setValue("Nice value in the stack");
propertyReader.get("Test").get("a key").get(5).setValue("This would work too");
System.out.println(propertyReader.toString());
System.out.println(propertyReader.get("Test").get("2nd key").get("A number value").getValue());
System.out.println(propertyReader.get("Test").get("a key").get(1).get(2).getValue());
System.out.println(propertyReader.get("Test").get("a key").get(1).get(3).getValue());
System.out.println(propertyReader.get("Test").get("a key").get(2).get("Nice").getValue());
System.out.println(propertyReader.get("Test").get("a key").get(5).getValue());
}
}

What is wrong with my implementation of Kruskal's algorithm using union-find data structure.

I am trying to implement the Kruskal's algorithm, and find the sum of the weights in the MST.
I think my problem lays somewhere where I set the parent of each node, but I am not sure, because in small examples it works fine, however with big example it doesnt detect a cycle, and the final answer is wrong. so my find might be wrong, but I am not sure.
Here is my code:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Scanner;
public class Graph {
private static int parent[];
private static int numberOfNodes, numberOfEdges, weight;
private static Node startNode, endNode;
private static Graph g;
private static ArrayList<Integer> listOfWeights = new ArrayList<Integer>();
private static ArrayList<Edge> listOfEdges = new ArrayList<Edge>();
private static ArrayList<Node> listOfNodes = new ArrayList<Node>();
private static HashMap<Edge, Integer> distance = new HashMap<Edge, Integer>();
private static HashMap<Edge, Integer> sortedMap = new HashMap<Edge, Integer>();
//values = Integer
private Scanner sc;
public static void main(String[] args) throws FileNotFoundException {
// TODO Auto-generated method stub
g = new Graph();
}
public Graph() throws FileNotFoundException {
sc = new Scanner(new File("data"));
numberOfNodes = Integer.parseInt(sc.next());
numberOfEdges = Integer.parseInt(sc.next());
if(numberOfEdges > 0){
for(int i = 0; i < numberOfEdges; i++) {
//read the start point
startNode = new Node(Integer.parseInt(sc.next()));
//read the end point
endNode = new Node(Integer.parseInt(sc.next()));
//read the price per node
weight = Integer.parseInt(sc.next());
Edge e = new Edge(startNode,endNode);
//set the weight per node
e.setWeight(weight);
//put them in a hashmap
distance.put(e,e.getWeight());
if(!listOfNodes.contains(startNode)){
listOfNodes.add(startNode);
}
if(!listOfNodes.contains(endNode)){
listOfNodes.add(endNode);
}
//System.out.println(distance.get(e));
}
System.out.println("without sort distance: " + distance.toString());
for (Object key : distance.keySet()) {
listOfEdges.add((Edge) key);
}
for (Object value : distance.values()) {
listOfWeights.add((Integer) value);
}
sortedMap = sortHashMapByValuesD(distance);
//System.out.println("list of nodes: "+ listOfNodes);
parent = new int[listOfNodes.size()];
System.out.println("sorted by weights: "+sortedMap.toString());
System.out.println(kruskalAlgo(sortedMap));
}
else{
System.out.println(0);
}
}
public static void makeSet(int x){
parent[x-1] = x;
}
public static int find(int x){
//System.out.println("FIND ==> x: " + x + ".parent = " + parent[x-1] );
if(parent[x-1] == x){
return x;
}
return find(parent[x-1]);
}
public static void union(int x, int y){
//System.out.println("parent[0]: "+parent[0]);
parent[x-1] = y;
System.out.println("x: " + x + " UNION parent[x-1]: " + parent[x-1] + " y " + y );
}
public static int kruskalAlgo(HashMap<Edge, Integer> s){
parent[0] = 0;
for(int i = 0; i < parent.length; i++){
makeSet(listOfNodes.get(i).getId());
//System.out.println("parent is: "+parent[i] + " for node"+ listOfNodes.get(i));
}
// for each edge (u,v) ∈ G, taken in increasing order by weight
int min = 0;
int edgeNumber = 0;
for (Edge key : s.keySet()) {
if(edgeNumber == listOfNodes.size()-1){
//System.out.println("edgeNumber: "+ edgeNumber);
//System.out.println("listOfNodes.size()-1: "+ (listOfNodes.size()-1));
return min;
}
Node u = key.getFromNode();
//System.out.println(u);
Node v = key.getToNode();
//System.out.println(v);
if(find(u.getId()) != find (v.getId())){
min += key.getWeight();
union(u.getId(),v.getId());
System.out.println(key + " weight is: " + key.getWeight());
edgeNumber++;
}
}
return min;
}
public static ArrayList<Edge> findSet(Node v){
ArrayList<Edge> nodes = new ArrayList<Edge>();
return nodes;
}
//make an ordered listed by increasing weights
public LinkedHashMap<Edge, Integer> sortHashMapByValuesD(HashMap<Edge, Integer> newMap) {
//list of edges
List<Edge> mapKeys = new ArrayList<Edge>(newMap.keySet());
//list of nodes
List<Integer> mapValues = new ArrayList<Integer>(newMap.values());
//sort the nodes
Collections.sort(mapValues);
LinkedHashMap<Edge, Integer> sortedMap = new LinkedHashMap<Edge, Integer>();
Iterator<Integer> valueIt = mapValues.iterator();
while (valueIt.hasNext()) {
Object val = valueIt.next();
Iterator<Edge> keyIt = mapKeys.iterator();
while (keyIt.hasNext()) {
Object key = keyIt.next();
String comp1 = newMap.get(key).toString();
String comp2 = val.toString();
if (comp1.equals(comp2)){
newMap.remove(key);
mapKeys.remove(key);
sortedMap.put((Edge)key, (Integer)val);
break;
}
}
}
return sortedMap;
}
}
I think the problem may be in your implementation of union:
public static void union(int x, int y){
parent[x-1] = y;
}
the problem is if x already has been joined into a set, it will already have a parent which you override.
The solution is to join the root of the two candidates instead of the leaf nodes:
public static void union(int x, int y){
x=find(x);
y=find(y);
parent[x-1] = y;
}
By the way,a good description of this Disjoint-set algorithm, plus hints on making it more efficient via "union by rank" and "path compression" is on wikipedia at this page.

Writing on an output file

I am stuck on this part where it does not write to an output file
the first class is contact I had to modify this is not my class is the authors class
I just had to use it
//********************************************************************
// Contact.java Author: Lewis/Loftus
//
// Represents a phone contact.
//********************************************************************
public class Contact implements Comparable
{
private String firstName, lastName, phone;
//-----------------------------------------------------------------
// Constructor: Sets up this contact with the specified data.
//-----------------------------------------------------------------
public Contact (String first, String last, String telephone)
{
firstName = first;
lastName = last;
phone = telephone;
}
//-----------------------------------------------------------------
// Returns a description of this contact as a string.
//-----------------------------------------------------------------
public String toString ()
{
return lastName + ", " + firstName + "\t" + phone;
}
//-----------------------------------------------------------------
// Returns true if the first and last names of this contact match
// those of the parameter.
//-----------------------------------------------------------------
public boolean equals (Object other)
{
return (lastName.equals(((Contact)other).getLastName()) &&
firstName.equals(((Contact)other).getFirstName()));
}
//-----------------------------------------------------------------
// Uses both last and first names to determine ordering.
//-----------------------------------------------------------------
public int compareTo (Object other)
{
int result;
String otherFirst = ((Contact)other).getFirstName();
String otherLast = ((Contact)other).getLastName();
if (lastName.equals(otherLast))
result = firstName.compareTo(otherFirst);
else
result = lastName.compareTo(otherLast);
return result;
}
//-----------------------------------------------------------------
// First name accessor.
//-----------------------------------------------------------------
public String getFirstName ()
{
return firstName;
}
//-----------------------------------------------------------------
// Last name accessor.
//-----------------------------------------------------------------
public String getLastName ()
{
return lastName;
}
}
this class oes the sorting this is fine. it does the sorting no prblem
public class Sorting {
public static void bubbleSortRecursive(Comparable[] data, int n)
{
if (n < 2)
{
return;
}
else
{
int lastIndex = n - 1;
for (int i = 0; i < lastIndex; i++)
{
if (data[i].compareTo(data[i + 1]) > 0)
{ //swap check
Comparable tmp = data[i];
data[i] = data[i + 1];
data[i + 1] = tmp;
}
}
bubbleSortRecursive(data, lastIndex);
}
}
public static void selectionSortRecursive(Comparable[] data, int n)
{
if (n < 2)
{
return;
}
else
{
int lastIndex = n - 1;
int largestIndex = lastIndex;
for (int i = 0; i < lastIndex; i++)
{
if (data[i].compareTo(data[largestIndex]) > 0)
{
largestIndex = i;
}
}
if (largestIndex != lastIndex)
{ //swap check
Comparable tmp = data[lastIndex];
data[lastIndex] = data[largestIndex];
data[largestIndex] = tmp;
}
selectionSortRecursive(data, n - 1);
}
}
}
this is the part I need help with. It is not outputing to he p4output.txt, i dont know what the problem is.
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class TestProject4 {
public static void main(String[] args)
{
doBubbleSortRecursive();
System.out.println();
System.out.println();
doSelectionSortRecursive();
}
private static void doBubbleSortRecursive()
{
Contact[] contacts = createContacts();
System.out.println("Before bubbleSortRecursive(): ");
for (int i=0; i<contacts.length; i++)
System.out.println(contacts[i].toString());
Sorting.bubbleSortRecursive(contacts, contacts.length);
System.out.println("\nAfter bubbleSortRecursive(): ");
for (int i=0; i<contacts.length; i++)
System.out.println(contacts[i].toString());
}
private static void doSelectionSortRecursive()
{
Contact[] contacts = createContacts();
System.out.println("Before selectionSortRecursive(): ");
for (int i=0; i<contacts.length; i++)
System.out.println(contacts[i].toString());
Sorting.selectionSortRecursive(contacts, contacts.length);
System.out.println("\nAfter selectionSortRecursive(): ");
for (int i=0; i<contacts.length; i++)
System.out.println(contacts[i].toString());
}
private static void printContacts(Contact[] contacts)
{
try
{
// this part I need help with it is not outputing in the text file
File file = new File("p4output.txt");
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
for (Contact contact : contacts)
{
bw.write(contact.toString());
}
bw.close();
}
catch (IOException e)
{
e.printStackTrace();
}
System.out.println("\t" + contacts);
}
public static Contact[] createContacts()
{
return new Contact[]
{
new Contact("John" , "Smith" , "610-555-7384"),
new Contact("Sarah" , "Barnes" , "215-555-3827"),
new Contact("Mark" , "Riley", "333-333-3333"),
new Contact("Laura" , "Getz" ,"663-555-3984"),
new Contact("Larry" , "Smith" , "464-555-3489"),
new Contact("Frank" , "Phelps" , "322-555-2284"),
new Contact("Mario" , "Guzman" , "804-555-9066"),
new Contact("Marsha" , "Grant" , "243-555-2837"),
};
}
}
According to Eclipse, you never call/use printContacts(Contact[] contacts); method
Your printContacts(Contact[] contacts); contains the statements to write a file.
You don't appear to call the function printContacts() in your program. Try calling it after you do your contact creation and sorting.
It might look like this:
public static void main(String[] args)
{
doBubbleSortRecursive();
System.out.println();
System.out.println();
doSelectionSortRecursive();
printContacts(contactArray);//inserted code
}
Also, when you call your sorting methods, doSelectionSortRecursive(), you don't return the list of contacts. Make a return statement for it and then put the contact array into your printContacts function.
Here's an example:
public static void main(String[] args)
{
doBubbleSortRecursive();
System.out.println();
System.out.println();
Contact[] contacts = doSelectionSortRecursive();
printContacts(contacts);
}
public static Contact[] doSelectionSortRecursive(){
Contact[] contacts = createContacts();
//your sorting code
return contacts;
}
Using this method allows you to get the array of contacts from the method once it has been sorted.

Categories