5
Well, as a college job, I have to create an algorithm that, given a certain file with x is able to verify which is the largest sequence of numbers which, on the basis of 6, comply with the following rules:
- The sequence must be increasing
- From one number to another of the sequence, only one digit can change
- All numbers in the sequence must have the same number of digits (15->10015 is not valid)
An example would be:
The file contains the numbers 782, 229, 446, 527, 874, 19, 829, 70, 830, 992, 430 and 649.
That is, based on 6: 3342, 1021, 2022, 2235, 4014, 31, 3501, 154, 3502, 4332, 1554 and 3001.
Therefore, the largest sequence respecting these rules would be: 649, 829 and 830, which corresponds to 3001, 3501 and 3502 on 6 basis.
Okay, the files aren’t that simple, there are files that have up to 100,000 numbers, so I created a graph. I tried both with matrix and with adjacency list. Add vertices and edges (i.e., which numbers respect the rules for a number x) it was not a problem, my problem is to walk in the graph, because searching in the internet I found only minimal walking, but what I need is: to find the biggest way.
I tried with DFS but the result is not what I want.
My code is this:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
public class DirectedGraphList
{
private class Vertice
{
private String item;
private boolean Visitado;
private ArrayList<Vertice> lst = new ArrayList<Vertice>();
public Vertice(String item) {
this.item = item;
}
public String getItem() {
return this.item;
}
public void setItem(String item) {
this.item = item;
}
public void addAdjacent(Vertice v) {
if (!lst.contains(v))
lst.add(v);
}
public ArrayList<Vertice> getAdjacents() {
return lst;
}
public Vertice getAdjacent(int i) {
Vertice res = null;
if ((i >= 0) && (i < lst.size()))
res = lst.get(i);
return res;
}
public int getDegree(){
return lst.size();
}
}
private ArrayList<Vertice> vert;
public DirectedGraphList() {
vert = new ArrayList<Vertice>();
}
private Vertice searchVerticeRef(String item)
{
Vertice res = null;
int i;
for (i = 0; ((i < vert.size()) && !vert.get(i).getItem().equals(item)); i++);
if (i < vert.size())
res = vert.get(i);
return res;
}
public void addVertice(String item)
{
if (searchVerticeRef(item) == null)
{
Vertice novo = new Vertice(item);
vert.add(novo);
}
}
public void addEdge(String strOrig, String strDest)
{
Vertice vAux1 = searchVerticeRef(strOrig);
Vertice vAux2 = searchVerticeRef(strDest);
if (vAux1 == null)
throw new IllegalArgumentException("Aresta origem invalida: " + strOrig);
else if (vAux2 == null)
throw new IllegalArgumentException("Aresta destino invalida: " + strDest);
else
{
vAux1.addAdjacent(vAux2);
}
}
public int getNumVertices() {
return vert.size();
}
public int getDegree(String vertice)
{
int i, j, c = 0;
Vertice v = searchVerticeRef(vertice);
if (v != null)
{
// grau de saida
c += v.getDegree();
// grau de entrada
for (i = 0; i < vert.size(); i++)
{
if (!vert.get(i).getItem().equals(vertice))
{
for (j = 0; j < vert.get(i).getDegree(); j++)
{
if (vert.get(i).getAdjacent(j).getItem().equals(vertice))
c++;
}
}
}
}
return c;
}
public ArrayList<String> getAllAdjacents(String vertice)
{
ArrayList<String> res = null;
Vertice v = searchVerticeRef(vertice);
if (v != null)
{
res = new ArrayList<String>();
for (int j = 0; j < v.getDegree(); j++)
res.add(v.getAdjacent(j).getItem());
}
return res;
}
public ArrayList<String> getSources()
{
ArrayList<String> res = new ArrayList<String>();
boolean checked;
String vertice;
for (int k=0; k<vert.size(); k++)
{
vertice = vert.get(k).getItem();
checked = false;
for (int i=0; i<vert.size(); i++)
{
for (int j=0; j<vert.get(i).getDegree(); j++)
{
if (vert.get(i).getAdjacent(j).getItem().equals(vertice))
{
checked = true;
break;
}
}
}
if (!checked)
res.add(vertice);
}
return res;
}
public ArrayList<String> getSinks()
{
ArrayList<String> res = new ArrayList<String>();
for (int i=0; i<vert.size(); i++)
{
if (vert.get(i).getAdjacents().isEmpty())
res.add(vert.get(i).getItem());
}
return res;
}
public void showInfo()
{
System.out.print("V = { ");
for (int i = 0; i < vert.size()-1; i++)
System.out.printf("%s, ", vert.get(i).getItem());
System.out.printf("%s }\n", vert.get(vert.size()-1).getItem());
ArrayList<String> arestas = new ArrayList<String>();
for (int i = 0; i < vert.size(); i++)
for (int j = 0; j < vert.get(i).lst.size(); j++)
arestas.add(String.format("(%s, %s)", vert.get(i).getItem(), vert.get(i).getAdjacent(j).getItem()));
System.out.print("E = {\n");
if (!arestas.isEmpty()) {
System.out.printf(" %s", arestas.get(0));
for (int i = 1; i < arestas.size(); i++)
System.out.printf(",\n %s", arestas.get(i));
}
System.out.println("\n }");
}
public static void criaArray(ArrayList<Integer> a,String nome) throws FileNotFoundException{
try{
FileReader ler= new FileReader(nome);
BufferedReader arq=new BufferedReader(ler);
int parsedStr;
String str=arq.readLine();
while(str!=null){
parsedStr=Integer.parseInt(str);
a.add(parsedStr);
str=arq.readLine();
}
}
catch(IOException e){
System.out.println("Erro na abertura do arquivo: "+
e.getMessage());
}
}
public static int diferente(String a,String b){
int diferentes=0;
if(a.length()==b.length()){
for(int i=0;i<a.length();i++){
if(a.charAt(i)!=b.charAt(i))
diferentes++;
}
}
else
diferentes=2;
return diferentes;
}
public static boolean possibilidades(DirectedGraphList graph,String a,ArrayList<Integer> array){
int diferentes=0;
for(int i=0;i<array.size();i++){
String numero=Integer.toString(array.get(i),6);
diferentes=diferente(numero,a);
if(diferentes==1){
graph.addEdge(a,numero);
}
}
return true;
}
public void DFS(Vertice a){
a.Visitado=true;
for(int i=0;i<a.lst.size();i++){
Vertice b=a.lst.get(i);
if(!b.Visitado){
DFS(b);
}
}
}
public static void main(String[] args) throws FileNotFoundException
{
ArrayList<Integer> numeros=new ArrayList<Integer>();
criaArray(numeros,"/home/geovane/Documentos/CC/ALPROII/teste5000b");
DirectedGraphList g = new DirectedGraphList();
HeapSort.heapsort(numeros);
for(int j=0;j<numeros.size();j++){
g.addVertice(Integer.toString(numeros.get(j),6));
}
for(int i=0;i<numeros.size();i++){
String numer=Integer.toString(numeros.get(i), 6);
possibilidades(g,numer,numeros);
}
}
}
Do you need to display the sequence itself, or is finding its size enough for you? I can jump, for example, from 15 to 10015 (under the theory that 00015 and 10015 differ in exactly one digit)?
– user25930
Okay, I forgot to mention that all numbers have to have the same number of digits, I’ll edit. That means you can’t jump from 15 to 10015. Also, I need to print the sequence.
– Geovane Wickert
Hello Geovane, the problem of the longest way is NP-Hard; the exception are directed acyclic graphs; in this case it is possible to invert the weights (e.g, -1 per edge) and use a minimum path algorithm.
– Anthony Accioly
To do that then I would have to change the way I make my edges, any suggestions?
– Geovane Wickert