Loading military units into ships optimally, using backtrackingSolving Sudoku using backtrackingIs this a true backtracking algorithm?Sudoku solutions finder using brute force and backtrackingn-Queens backtracking codePartitions of a number (backtracking) - time efficiencyPuzzle game solver via BacktrackingBacktracking maze traversalSimple backtracking codeN Queens in Python using backtracking

Is there a way to unplug the Raspberry pi safely without shutting down

Is Texas Instrument wrong with their pin number on TO-92 package?

How does "Te vas a cansar" mean "You're going to get tired"?

Is it okay for a ticket seller to grab a tip in the USA?

Does a code snippet compile? Or does it get compiled?

what is measured in units of sat/kw?

Ex-contractor published company source code and secrets online

Write an interpreter for *

During the Space Shuttle Columbia Disaster of 2003, Why Did The Flight Director Say, "Lock the doors."?

Should I ask for permission to write an expository post about someone's else research?

(11 of 11: Meta) What is Pyramid Cult's All-Time Favorite?

Withdrew when Jimmy met up with Heath

Generate Brainfuck for the numbers 1–255

I accidentally overwrote a Linux binary file

What are the uses and limitations of Persuasion, Insight, and Deception against other PCs?

What does Apple mean by "This may decrease battery life"?

How many different ways are there to checkmate in the early game?

Why isn’t SHA-3 in wider use?

DeclareMathOperator and widearcarrow with kpfonts

Multirow in tabularx?

What game uses dice with sides powers of 2?

Loading military units into ships optimally, using backtracking

Help evaluating integral (anything simple that I am missing?)

What is the difference between 型 and 形?



Loading military units into ships optimally, using backtracking


Solving Sudoku using backtrackingIs this a true backtracking algorithm?Sudoku solutions finder using brute force and backtrackingn-Queens backtracking codePartitions of a number (backtracking) - time efficiencyPuzzle game solver via BacktrackingBacktracking maze traversalSimple backtracking codeN Queens in Python using backtracking






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








2












$begingroup$


I solved the following problem using backtracking:




We are given a list of military units, their weight and their
(numerical) strength. We have a number of ships with a limited
carrying capacity. Determine how to load ships with military units, so
that carrying capacity for each ship is not exceed and so that we have
the maximum possible military strength on our ships.




However, my code is not fast enough, as there are many unnecessary calculations being done, that does not lead to a solution. How would I optimize my code? My idea is to use memoization, but how would I implement it?



I tried to comment my code and refactor my code as best as I can.



public class HeroesOntTheBoat {

private int[] arrayWithGeneratedNumbers;
private int numberOfShips;
private int max;
private int[] bestArray;
private ArrayList<Integer> strengths;
private ArrayList<Integer> weights;
private ArrayList<Integer> carryingCapacities;

public HeroesOntTheBoat()
carryingCapacities = new ArrayList<Integer>(); // create arraylist for the carrying capacities of ships
strengths = new ArrayList<Integer>(); //create arraylists for strengths and weights of units
weights = new ArrayList<Integer>(); //create arraylists for weights
max = 0; // global variable max for finding the best strength


private void generate(int fromIndex) // I generate all combinations between 0 and numberOfShips
if (fromIndex == arrayWithGeneratedNumbers.length) // 0 is representing that unit is being left behind
processGeneratedNumbers(); // 1,2,3,4..n are representing the number of ship that the unit is loaded on
return; // index of a number in array is representing a specific unit


for (int i = 0; i <= numberOfShips; i++)
arrayWithGeneratedNumbers[fromIndex] = i;
generate(fromIndex + 1);



public void input(String input)
Scanner sc = null;
try
sc = new Scanner(new File(input)); // load my input from a textfile
numberOfShips = sc.nextInt(); // load the number of ships
for (int i = 0; i < numberOfShips; i++) //add carrying capacities to arraylist
carryingCapacities.add(sc.nextInt());

bestArray = new int[weights.size()]; // array where we will remember the best combination of units
while (sc.hasNext())
weights.add(sc.nextInt());
strengths.add(sc.nextInt());

arrayWithGeneratedNumbers = new int[weights.size()]; // array where we will generate numbers
generate(0); // run the generation
System.out.println(Arrays.toString(bestArray) + " this is the best layout of units"); // after the generation is over
System.out.println(max + " this is the max strength we can achieve"); // print the results
catch (FileNotFoundException e)
System.err.println("FileNotFound");
finally
if (sc != null)
sc.close();




public void processGeneratedNumbers()
int currentStrength = 0; // process every generated result
boolean carryingCapacityWasExceeded = false;
int[] currentWeight = new int[numberOfShips + 1];
for (int i = 0; i < arrayWithGeneratedNumbers.length; i++) // calculate weights for every ship and ground
currentWeight[arrayWithGeneratedNumbers[i]] += weights.get(i);

for (int i = 0; i < currentWeight.length; i++) // is capacity exceeded?
if (i != 0 && currentWeight[i] > carryingCapacities.get(i - 1)) // ignore 0, because 0 represents ground(units I left behind)
carryingCapacityWasExceeded = true;


if (carryingCapacityWasExceeded == false) // if capacity isn't exceeded
for (int i = 0; i < arrayWithGeneratedNumbers.length; i++) // calculate strength
if (arrayWithGeneratedNumbers[i] != 0) // ignore 0, because I left units with 0 behind on the ground
currentStrength += strengths.get(i);


if (currentStrength > max) // is my current strength better than global maximum?
max = currentStrength; // replace my global maximum
bestArray = arrayWithGeneratedNumbers.clone(); // remember the new best layout of units







public static void main(String[] args)
HeroesOnTheBoat g = new HeroesOnTheBoat();
g.input("inputFile");



Example input:



2 60 40
30 400
20 500
50 100
40 100
30 50
60 75
40 20


and its result:



[1, 1, 0, 2, 0, 0, 0] this is the best layout of units
1000 this is the max strength we can achieve









share|improve this question









New contributor



Jack is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$













  • $begingroup$
    Could you include the results of your example input?
    $endgroup$
    – dfhwze
    7 hours ago










  • $begingroup$
    @dfhwze The results are [1, 1, 0, 2, 0, 0, 0], which represents that units 0,1 and 4 will be on board. Units 0 and 1 on boat 0 and unit 4 on boat 1. The rest is left behind. 1000 this is the max strength we can achieve, because 400+500+100.
    $endgroup$
    – Jack
    7 hours ago


















2












$begingroup$


I solved the following problem using backtracking:




We are given a list of military units, their weight and their
(numerical) strength. We have a number of ships with a limited
carrying capacity. Determine how to load ships with military units, so
that carrying capacity for each ship is not exceed and so that we have
the maximum possible military strength on our ships.




However, my code is not fast enough, as there are many unnecessary calculations being done, that does not lead to a solution. How would I optimize my code? My idea is to use memoization, but how would I implement it?



I tried to comment my code and refactor my code as best as I can.



public class HeroesOntTheBoat {

private int[] arrayWithGeneratedNumbers;
private int numberOfShips;
private int max;
private int[] bestArray;
private ArrayList<Integer> strengths;
private ArrayList<Integer> weights;
private ArrayList<Integer> carryingCapacities;

public HeroesOntTheBoat()
carryingCapacities = new ArrayList<Integer>(); // create arraylist for the carrying capacities of ships
strengths = new ArrayList<Integer>(); //create arraylists for strengths and weights of units
weights = new ArrayList<Integer>(); //create arraylists for weights
max = 0; // global variable max for finding the best strength


private void generate(int fromIndex) // I generate all combinations between 0 and numberOfShips
if (fromIndex == arrayWithGeneratedNumbers.length) // 0 is representing that unit is being left behind
processGeneratedNumbers(); // 1,2,3,4..n are representing the number of ship that the unit is loaded on
return; // index of a number in array is representing a specific unit


for (int i = 0; i <= numberOfShips; i++)
arrayWithGeneratedNumbers[fromIndex] = i;
generate(fromIndex + 1);



public void input(String input)
Scanner sc = null;
try
sc = new Scanner(new File(input)); // load my input from a textfile
numberOfShips = sc.nextInt(); // load the number of ships
for (int i = 0; i < numberOfShips; i++) //add carrying capacities to arraylist
carryingCapacities.add(sc.nextInt());

bestArray = new int[weights.size()]; // array where we will remember the best combination of units
while (sc.hasNext())
weights.add(sc.nextInt());
strengths.add(sc.nextInt());

arrayWithGeneratedNumbers = new int[weights.size()]; // array where we will generate numbers
generate(0); // run the generation
System.out.println(Arrays.toString(bestArray) + " this is the best layout of units"); // after the generation is over
System.out.println(max + " this is the max strength we can achieve"); // print the results
catch (FileNotFoundException e)
System.err.println("FileNotFound");
finally
if (sc != null)
sc.close();




public void processGeneratedNumbers()
int currentStrength = 0; // process every generated result
boolean carryingCapacityWasExceeded = false;
int[] currentWeight = new int[numberOfShips + 1];
for (int i = 0; i < arrayWithGeneratedNumbers.length; i++) // calculate weights for every ship and ground
currentWeight[arrayWithGeneratedNumbers[i]] += weights.get(i);

for (int i = 0; i < currentWeight.length; i++) // is capacity exceeded?
if (i != 0 && currentWeight[i] > carryingCapacities.get(i - 1)) // ignore 0, because 0 represents ground(units I left behind)
carryingCapacityWasExceeded = true;


if (carryingCapacityWasExceeded == false) // if capacity isn't exceeded
for (int i = 0; i < arrayWithGeneratedNumbers.length; i++) // calculate strength
if (arrayWithGeneratedNumbers[i] != 0) // ignore 0, because I left units with 0 behind on the ground
currentStrength += strengths.get(i);


if (currentStrength > max) // is my current strength better than global maximum?
max = currentStrength; // replace my global maximum
bestArray = arrayWithGeneratedNumbers.clone(); // remember the new best layout of units







public static void main(String[] args)
HeroesOnTheBoat g = new HeroesOnTheBoat();
g.input("inputFile");



Example input:



2 60 40
30 400
20 500
50 100
40 100
30 50
60 75
40 20


and its result:



[1, 1, 0, 2, 0, 0, 0] this is the best layout of units
1000 this is the max strength we can achieve









share|improve this question









New contributor



Jack is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$













  • $begingroup$
    Could you include the results of your example input?
    $endgroup$
    – dfhwze
    7 hours ago










  • $begingroup$
    @dfhwze The results are [1, 1, 0, 2, 0, 0, 0], which represents that units 0,1 and 4 will be on board. Units 0 and 1 on boat 0 and unit 4 on boat 1. The rest is left behind. 1000 this is the max strength we can achieve, because 400+500+100.
    $endgroup$
    – Jack
    7 hours ago














2












2








2





$begingroup$


I solved the following problem using backtracking:




We are given a list of military units, their weight and their
(numerical) strength. We have a number of ships with a limited
carrying capacity. Determine how to load ships with military units, so
that carrying capacity for each ship is not exceed and so that we have
the maximum possible military strength on our ships.




However, my code is not fast enough, as there are many unnecessary calculations being done, that does not lead to a solution. How would I optimize my code? My idea is to use memoization, but how would I implement it?



I tried to comment my code and refactor my code as best as I can.



public class HeroesOntTheBoat {

private int[] arrayWithGeneratedNumbers;
private int numberOfShips;
private int max;
private int[] bestArray;
private ArrayList<Integer> strengths;
private ArrayList<Integer> weights;
private ArrayList<Integer> carryingCapacities;

public HeroesOntTheBoat()
carryingCapacities = new ArrayList<Integer>(); // create arraylist for the carrying capacities of ships
strengths = new ArrayList<Integer>(); //create arraylists for strengths and weights of units
weights = new ArrayList<Integer>(); //create arraylists for weights
max = 0; // global variable max for finding the best strength


private void generate(int fromIndex) // I generate all combinations between 0 and numberOfShips
if (fromIndex == arrayWithGeneratedNumbers.length) // 0 is representing that unit is being left behind
processGeneratedNumbers(); // 1,2,3,4..n are representing the number of ship that the unit is loaded on
return; // index of a number in array is representing a specific unit


for (int i = 0; i <= numberOfShips; i++)
arrayWithGeneratedNumbers[fromIndex] = i;
generate(fromIndex + 1);



public void input(String input)
Scanner sc = null;
try
sc = new Scanner(new File(input)); // load my input from a textfile
numberOfShips = sc.nextInt(); // load the number of ships
for (int i = 0; i < numberOfShips; i++) //add carrying capacities to arraylist
carryingCapacities.add(sc.nextInt());

bestArray = new int[weights.size()]; // array where we will remember the best combination of units
while (sc.hasNext())
weights.add(sc.nextInt());
strengths.add(sc.nextInt());

arrayWithGeneratedNumbers = new int[weights.size()]; // array where we will generate numbers
generate(0); // run the generation
System.out.println(Arrays.toString(bestArray) + " this is the best layout of units"); // after the generation is over
System.out.println(max + " this is the max strength we can achieve"); // print the results
catch (FileNotFoundException e)
System.err.println("FileNotFound");
finally
if (sc != null)
sc.close();




public void processGeneratedNumbers()
int currentStrength = 0; // process every generated result
boolean carryingCapacityWasExceeded = false;
int[] currentWeight = new int[numberOfShips + 1];
for (int i = 0; i < arrayWithGeneratedNumbers.length; i++) // calculate weights for every ship and ground
currentWeight[arrayWithGeneratedNumbers[i]] += weights.get(i);

for (int i = 0; i < currentWeight.length; i++) // is capacity exceeded?
if (i != 0 && currentWeight[i] > carryingCapacities.get(i - 1)) // ignore 0, because 0 represents ground(units I left behind)
carryingCapacityWasExceeded = true;


if (carryingCapacityWasExceeded == false) // if capacity isn't exceeded
for (int i = 0; i < arrayWithGeneratedNumbers.length; i++) // calculate strength
if (arrayWithGeneratedNumbers[i] != 0) // ignore 0, because I left units with 0 behind on the ground
currentStrength += strengths.get(i);


if (currentStrength > max) // is my current strength better than global maximum?
max = currentStrength; // replace my global maximum
bestArray = arrayWithGeneratedNumbers.clone(); // remember the new best layout of units







public static void main(String[] args)
HeroesOnTheBoat g = new HeroesOnTheBoat();
g.input("inputFile");



Example input:



2 60 40
30 400
20 500
50 100
40 100
30 50
60 75
40 20


and its result:



[1, 1, 0, 2, 0, 0, 0] this is the best layout of units
1000 this is the max strength we can achieve









share|improve this question









New contributor



Jack is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$




I solved the following problem using backtracking:




We are given a list of military units, their weight and their
(numerical) strength. We have a number of ships with a limited
carrying capacity. Determine how to load ships with military units, so
that carrying capacity for each ship is not exceed and so that we have
the maximum possible military strength on our ships.




However, my code is not fast enough, as there are many unnecessary calculations being done, that does not lead to a solution. How would I optimize my code? My idea is to use memoization, but how would I implement it?



I tried to comment my code and refactor my code as best as I can.



public class HeroesOntTheBoat {

private int[] arrayWithGeneratedNumbers;
private int numberOfShips;
private int max;
private int[] bestArray;
private ArrayList<Integer> strengths;
private ArrayList<Integer> weights;
private ArrayList<Integer> carryingCapacities;

public HeroesOntTheBoat()
carryingCapacities = new ArrayList<Integer>(); // create arraylist for the carrying capacities of ships
strengths = new ArrayList<Integer>(); //create arraylists for strengths and weights of units
weights = new ArrayList<Integer>(); //create arraylists for weights
max = 0; // global variable max for finding the best strength


private void generate(int fromIndex) // I generate all combinations between 0 and numberOfShips
if (fromIndex == arrayWithGeneratedNumbers.length) // 0 is representing that unit is being left behind
processGeneratedNumbers(); // 1,2,3,4..n are representing the number of ship that the unit is loaded on
return; // index of a number in array is representing a specific unit


for (int i = 0; i <= numberOfShips; i++)
arrayWithGeneratedNumbers[fromIndex] = i;
generate(fromIndex + 1);



public void input(String input)
Scanner sc = null;
try
sc = new Scanner(new File(input)); // load my input from a textfile
numberOfShips = sc.nextInt(); // load the number of ships
for (int i = 0; i < numberOfShips; i++) //add carrying capacities to arraylist
carryingCapacities.add(sc.nextInt());

bestArray = new int[weights.size()]; // array where we will remember the best combination of units
while (sc.hasNext())
weights.add(sc.nextInt());
strengths.add(sc.nextInt());

arrayWithGeneratedNumbers = new int[weights.size()]; // array where we will generate numbers
generate(0); // run the generation
System.out.println(Arrays.toString(bestArray) + " this is the best layout of units"); // after the generation is over
System.out.println(max + " this is the max strength we can achieve"); // print the results
catch (FileNotFoundException e)
System.err.println("FileNotFound");
finally
if (sc != null)
sc.close();




public void processGeneratedNumbers()
int currentStrength = 0; // process every generated result
boolean carryingCapacityWasExceeded = false;
int[] currentWeight = new int[numberOfShips + 1];
for (int i = 0; i < arrayWithGeneratedNumbers.length; i++) // calculate weights for every ship and ground
currentWeight[arrayWithGeneratedNumbers[i]] += weights.get(i);

for (int i = 0; i < currentWeight.length; i++) // is capacity exceeded?
if (i != 0 && currentWeight[i] > carryingCapacities.get(i - 1)) // ignore 0, because 0 represents ground(units I left behind)
carryingCapacityWasExceeded = true;


if (carryingCapacityWasExceeded == false) // if capacity isn't exceeded
for (int i = 0; i < arrayWithGeneratedNumbers.length; i++) // calculate strength
if (arrayWithGeneratedNumbers[i] != 0) // ignore 0, because I left units with 0 behind on the ground
currentStrength += strengths.get(i);


if (currentStrength > max) // is my current strength better than global maximum?
max = currentStrength; // replace my global maximum
bestArray = arrayWithGeneratedNumbers.clone(); // remember the new best layout of units







public static void main(String[] args)
HeroesOnTheBoat g = new HeroesOnTheBoat();
g.input("inputFile");



Example input:



2 60 40
30 400
20 500
50 100
40 100
30 50
60 75
40 20


and its result:



[1, 1, 0, 2, 0, 0, 0] this is the best layout of units
1000 this is the max strength we can achieve






java recursion time-limit-exceeded backtracking knapsack-problem






share|improve this question









New contributor



Jack is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.










share|improve this question









New contributor



Jack is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








share|improve this question




share|improve this question








edited 1 hour ago









200_success

135k21 gold badges173 silver badges443 bronze badges




135k21 gold badges173 silver badges443 bronze badges






New contributor



Jack is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








asked 8 hours ago









JackJack

133 bronze badges




133 bronze badges




New contributor



Jack is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




New contributor




Jack is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • $begingroup$
    Could you include the results of your example input?
    $endgroup$
    – dfhwze
    7 hours ago










  • $begingroup$
    @dfhwze The results are [1, 1, 0, 2, 0, 0, 0], which represents that units 0,1 and 4 will be on board. Units 0 and 1 on boat 0 and unit 4 on boat 1. The rest is left behind. 1000 this is the max strength we can achieve, because 400+500+100.
    $endgroup$
    – Jack
    7 hours ago

















  • $begingroup$
    Could you include the results of your example input?
    $endgroup$
    – dfhwze
    7 hours ago










  • $begingroup$
    @dfhwze The results are [1, 1, 0, 2, 0, 0, 0], which represents that units 0,1 and 4 will be on board. Units 0 and 1 on boat 0 and unit 4 on boat 1. The rest is left behind. 1000 this is the max strength we can achieve, because 400+500+100.
    $endgroup$
    – Jack
    7 hours ago
















$begingroup$
Could you include the results of your example input?
$endgroup$
– dfhwze
7 hours ago




$begingroup$
Could you include the results of your example input?
$endgroup$
– dfhwze
7 hours ago












$begingroup$
@dfhwze The results are [1, 1, 0, 2, 0, 0, 0], which represents that units 0,1 and 4 will be on board. Units 0 and 1 on boat 0 and unit 4 on boat 1. The rest is left behind. 1000 this is the max strength we can achieve, because 400+500+100.
$endgroup$
– Jack
7 hours ago





$begingroup$
@dfhwze The results are [1, 1, 0, 2, 0, 0, 0], which represents that units 0,1 and 4 will be on board. Units 0 and 1 on boat 0 and unit 4 on boat 1. The rest is left behind. 1000 this is the max strength we can achieve, because 400+500+100.
$endgroup$
– Jack
7 hours ago











1 Answer
1






active

oldest

votes


















3












$begingroup$

The algorithm



This algorithm creates every combination of ships and tests them one by one, including combinations that could be seen to be useless by the first choice made. For example, if the first choice is to assign a unit of weight 60 to a ship with capacity 50, then it no longer matters what the rest of the content of arrayWithGeneratedNumbers will be, there is no point recursively calling generate when there is already such a problem.



The solution to that is checking as much as possible as early as possible. So in generate, do not only check the solution when it is fully formed, check for capacity violations every time. That seems like more wasted work, but it's not a waste, it prevents a ton of recursion. If a capacity check fails early, thousands maybe millions of combinations will be skipped, by simply not generating them.



A similar related trick is computing the strength early, and returning back up the recursion tree once you see that the current branch cannot result in a better solution than some solution that you already have. So this only works if there is some non-trivial solution already, and it is useful to do a simple greedy pass first to initialize with, so more of the recursion is pruned right from the start.



With pruning, the order in which choices are made matters: pruning near the root of the tree is orders of magnitude better than pruning near the leafs. A general rule of thumb is to pick the most-constrained item first, and try the least-constraining choice for it first. So in this domain, pick the heaviest unit, and put it on the biggest ship. However, we can also make use of the strengths and go for units with a high strength-per-weight ratio first, relying on the idea of filling the ships with good units first and then trying to "fill the gaps" with worse units. There are different strategies here, probably almost anything is better than not using a strategy.



Naming



There are several extremely generic names in this code, bordering on meaninglessness. generate, generate what? processGeneratedNumbers, what is process? What are "generated numbers"? arrayWithGeneratedNumbers, variable names shouldn't repeat their type and again what are "generated numbers". This is not an abstract domain where we don't know what is being generated or what the numbers mean, the data here has a specific meaning, and the methods do specific things. So you could use names such as:




  • unitAssignment, in the sense of assigning units to ships. Or shipAssignment, in the same sense.


  • isAssignmentValid, checkCapacities, something like that. That's for the version that does not also update the best-solution-so-far, just pure checking for the purpose of pruning.

Also I wouldn't put the unrelated input between two related methods.



Boolean flag logic



Always a contentious point, but I would say, as a rough approximation, the fewer boolean flags the better. Return when the first checks fails, no messy business with flags.






share|improve this answer









$endgroup$

















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );






    Jack is a new contributor. Be nice, and check out our Code of Conduct.









    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f225939%2floading-military-units-into-ships-optimally-using-backtracking%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3












    $begingroup$

    The algorithm



    This algorithm creates every combination of ships and tests them one by one, including combinations that could be seen to be useless by the first choice made. For example, if the first choice is to assign a unit of weight 60 to a ship with capacity 50, then it no longer matters what the rest of the content of arrayWithGeneratedNumbers will be, there is no point recursively calling generate when there is already such a problem.



    The solution to that is checking as much as possible as early as possible. So in generate, do not only check the solution when it is fully formed, check for capacity violations every time. That seems like more wasted work, but it's not a waste, it prevents a ton of recursion. If a capacity check fails early, thousands maybe millions of combinations will be skipped, by simply not generating them.



    A similar related trick is computing the strength early, and returning back up the recursion tree once you see that the current branch cannot result in a better solution than some solution that you already have. So this only works if there is some non-trivial solution already, and it is useful to do a simple greedy pass first to initialize with, so more of the recursion is pruned right from the start.



    With pruning, the order in which choices are made matters: pruning near the root of the tree is orders of magnitude better than pruning near the leafs. A general rule of thumb is to pick the most-constrained item first, and try the least-constraining choice for it first. So in this domain, pick the heaviest unit, and put it on the biggest ship. However, we can also make use of the strengths and go for units with a high strength-per-weight ratio first, relying on the idea of filling the ships with good units first and then trying to "fill the gaps" with worse units. There are different strategies here, probably almost anything is better than not using a strategy.



    Naming



    There are several extremely generic names in this code, bordering on meaninglessness. generate, generate what? processGeneratedNumbers, what is process? What are "generated numbers"? arrayWithGeneratedNumbers, variable names shouldn't repeat their type and again what are "generated numbers". This is not an abstract domain where we don't know what is being generated or what the numbers mean, the data here has a specific meaning, and the methods do specific things. So you could use names such as:




    • unitAssignment, in the sense of assigning units to ships. Or shipAssignment, in the same sense.


    • isAssignmentValid, checkCapacities, something like that. That's for the version that does not also update the best-solution-so-far, just pure checking for the purpose of pruning.

    Also I wouldn't put the unrelated input between two related methods.



    Boolean flag logic



    Always a contentious point, but I would say, as a rough approximation, the fewer boolean flags the better. Return when the first checks fails, no messy business with flags.






    share|improve this answer









    $endgroup$



















      3












      $begingroup$

      The algorithm



      This algorithm creates every combination of ships and tests them one by one, including combinations that could be seen to be useless by the first choice made. For example, if the first choice is to assign a unit of weight 60 to a ship with capacity 50, then it no longer matters what the rest of the content of arrayWithGeneratedNumbers will be, there is no point recursively calling generate when there is already such a problem.



      The solution to that is checking as much as possible as early as possible. So in generate, do not only check the solution when it is fully formed, check for capacity violations every time. That seems like more wasted work, but it's not a waste, it prevents a ton of recursion. If a capacity check fails early, thousands maybe millions of combinations will be skipped, by simply not generating them.



      A similar related trick is computing the strength early, and returning back up the recursion tree once you see that the current branch cannot result in a better solution than some solution that you already have. So this only works if there is some non-trivial solution already, and it is useful to do a simple greedy pass first to initialize with, so more of the recursion is pruned right from the start.



      With pruning, the order in which choices are made matters: pruning near the root of the tree is orders of magnitude better than pruning near the leafs. A general rule of thumb is to pick the most-constrained item first, and try the least-constraining choice for it first. So in this domain, pick the heaviest unit, and put it on the biggest ship. However, we can also make use of the strengths and go for units with a high strength-per-weight ratio first, relying on the idea of filling the ships with good units first and then trying to "fill the gaps" with worse units. There are different strategies here, probably almost anything is better than not using a strategy.



      Naming



      There are several extremely generic names in this code, bordering on meaninglessness. generate, generate what? processGeneratedNumbers, what is process? What are "generated numbers"? arrayWithGeneratedNumbers, variable names shouldn't repeat their type and again what are "generated numbers". This is not an abstract domain where we don't know what is being generated or what the numbers mean, the data here has a specific meaning, and the methods do specific things. So you could use names such as:




      • unitAssignment, in the sense of assigning units to ships. Or shipAssignment, in the same sense.


      • isAssignmentValid, checkCapacities, something like that. That's for the version that does not also update the best-solution-so-far, just pure checking for the purpose of pruning.

      Also I wouldn't put the unrelated input between two related methods.



      Boolean flag logic



      Always a contentious point, but I would say, as a rough approximation, the fewer boolean flags the better. Return when the first checks fails, no messy business with flags.






      share|improve this answer









      $endgroup$

















        3












        3








        3





        $begingroup$

        The algorithm



        This algorithm creates every combination of ships and tests them one by one, including combinations that could be seen to be useless by the first choice made. For example, if the first choice is to assign a unit of weight 60 to a ship with capacity 50, then it no longer matters what the rest of the content of arrayWithGeneratedNumbers will be, there is no point recursively calling generate when there is already such a problem.



        The solution to that is checking as much as possible as early as possible. So in generate, do not only check the solution when it is fully formed, check for capacity violations every time. That seems like more wasted work, but it's not a waste, it prevents a ton of recursion. If a capacity check fails early, thousands maybe millions of combinations will be skipped, by simply not generating them.



        A similar related trick is computing the strength early, and returning back up the recursion tree once you see that the current branch cannot result in a better solution than some solution that you already have. So this only works if there is some non-trivial solution already, and it is useful to do a simple greedy pass first to initialize with, so more of the recursion is pruned right from the start.



        With pruning, the order in which choices are made matters: pruning near the root of the tree is orders of magnitude better than pruning near the leafs. A general rule of thumb is to pick the most-constrained item first, and try the least-constraining choice for it first. So in this domain, pick the heaviest unit, and put it on the biggest ship. However, we can also make use of the strengths and go for units with a high strength-per-weight ratio first, relying on the idea of filling the ships with good units first and then trying to "fill the gaps" with worse units. There are different strategies here, probably almost anything is better than not using a strategy.



        Naming



        There are several extremely generic names in this code, bordering on meaninglessness. generate, generate what? processGeneratedNumbers, what is process? What are "generated numbers"? arrayWithGeneratedNumbers, variable names shouldn't repeat their type and again what are "generated numbers". This is not an abstract domain where we don't know what is being generated or what the numbers mean, the data here has a specific meaning, and the methods do specific things. So you could use names such as:




        • unitAssignment, in the sense of assigning units to ships. Or shipAssignment, in the same sense.


        • isAssignmentValid, checkCapacities, something like that. That's for the version that does not also update the best-solution-so-far, just pure checking for the purpose of pruning.

        Also I wouldn't put the unrelated input between two related methods.



        Boolean flag logic



        Always a contentious point, but I would say, as a rough approximation, the fewer boolean flags the better. Return when the first checks fails, no messy business with flags.






        share|improve this answer









        $endgroup$



        The algorithm



        This algorithm creates every combination of ships and tests them one by one, including combinations that could be seen to be useless by the first choice made. For example, if the first choice is to assign a unit of weight 60 to a ship with capacity 50, then it no longer matters what the rest of the content of arrayWithGeneratedNumbers will be, there is no point recursively calling generate when there is already such a problem.



        The solution to that is checking as much as possible as early as possible. So in generate, do not only check the solution when it is fully formed, check for capacity violations every time. That seems like more wasted work, but it's not a waste, it prevents a ton of recursion. If a capacity check fails early, thousands maybe millions of combinations will be skipped, by simply not generating them.



        A similar related trick is computing the strength early, and returning back up the recursion tree once you see that the current branch cannot result in a better solution than some solution that you already have. So this only works if there is some non-trivial solution already, and it is useful to do a simple greedy pass first to initialize with, so more of the recursion is pruned right from the start.



        With pruning, the order in which choices are made matters: pruning near the root of the tree is orders of magnitude better than pruning near the leafs. A general rule of thumb is to pick the most-constrained item first, and try the least-constraining choice for it first. So in this domain, pick the heaviest unit, and put it on the biggest ship. However, we can also make use of the strengths and go for units with a high strength-per-weight ratio first, relying on the idea of filling the ships with good units first and then trying to "fill the gaps" with worse units. There are different strategies here, probably almost anything is better than not using a strategy.



        Naming



        There are several extremely generic names in this code, bordering on meaninglessness. generate, generate what? processGeneratedNumbers, what is process? What are "generated numbers"? arrayWithGeneratedNumbers, variable names shouldn't repeat their type and again what are "generated numbers". This is not an abstract domain where we don't know what is being generated or what the numbers mean, the data here has a specific meaning, and the methods do specific things. So you could use names such as:




        • unitAssignment, in the sense of assigning units to ships. Or shipAssignment, in the same sense.


        • isAssignmentValid, checkCapacities, something like that. That's for the version that does not also update the best-solution-so-far, just pure checking for the purpose of pruning.

        Also I wouldn't put the unrelated input between two related methods.



        Boolean flag logic



        Always a contentious point, but I would say, as a rough approximation, the fewer boolean flags the better. Return when the first checks fails, no messy business with flags.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 7 hours ago









        haroldharold

        1,9666 silver badges10 bronze badges




        1,9666 silver badges10 bronze badges























            Jack is a new contributor. Be nice, and check out our Code of Conduct.









            draft saved

            draft discarded


















            Jack is a new contributor. Be nice, and check out our Code of Conduct.












            Jack is a new contributor. Be nice, and check out our Code of Conduct.











            Jack is a new contributor. Be nice, and check out our Code of Conduct.














            Thanks for contributing an answer to Code Review Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f225939%2floading-military-units-into-ships-optimally-using-backtracking%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

            Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

            199年 目錄 大件事 到箇年出世嗰人 到箇年死嗰人 節慶、風俗習慣 導覽選單