Note that there are some explanatory texts on larger screens.

plurals
  1. POConstrained Single-Objective Optimization
    primarykey
    data
    text
    <h2>Introduction</h2> <p>I need to split an array filled with a certain type (let's take water buckets for example) with two values set (in this case weight and volume), while keeping the difference between the total of the weight to a minimum (preferred) and the difference between the total of the volumes less than 1000 (required). This doesn't need to be a full-fetched genetic algorithm or something similar, but it should be better than what I currently have...</p> <h2>Current Implementation</h2> <p>Due to not knowing how to do it better, I started by splitting the array in two same-length arrays (the array can be filled with an uneven number of items), replacing a possibly void spot with an item with both values being 0. The sides don't need to have the same amount of items, I just didn't knew how to handle it otherwise.</p> <p>After having these distributed, I'm trying to optimize them like this:</p> <pre><code>func (main *Main) Optimize() { for { difference := main.Difference(WEIGHT) for i := 0; i &lt; len(main.left); i++ { for j := 0; j &lt; len(main.right); j++ { if main.DifferenceAfter(i, j, WEIGHT) &lt; main.Difference(WEIGHT) { main.left[i], main.right[j] = main.right[j], main.left[i] } } } if difference == main.Difference(WEIGHT) { break } } for main.Difference(CAPACITY) &gt; 1000 { leftIndex := 0 rightIndex := 0 liters := 0 weight := 100 for i := 0; i &lt; len(main.left); i++ { for j := 0; j &lt; len(main.right); j++ { if main.DifferenceAfter(i, j, CAPACITY) &lt; main.Difference(CAPACITY) { newLiters := main.Difference(CAPACITY) - main.DifferenceAfter(i, j, CAPACITY) newWeight := main.Difference(WEIGHT) - main.DifferenceAfter(i, j, WEIGHT) if newLiters &gt; liters &amp;&amp; newWeight &lt;= weight || newLiters == liters &amp;&amp; newWeight &lt; weight { leftIndex = i rightIndex = j liters = newLiters weight = newWeight } } } } main.left[leftIndex], main.right[rightIndex] = main.right[rightIndex], main.left[leftIndex] } } </code></pre> <h3>Functions:</h3> <p><em>main.Difference(const)</em> calculates the absolute difference between the two sides, the constant taken as an argument decides the value to calculate the difference for</p> <p><em>main.DifferenceAfter(i, j, const)</em> simulates a swap between the two buckets, i being the left one and j being the right one, and calculates the resulting absolute difference then, the constant again determines the value to check</p> <h3>Explanation:</h3> <p>Basically this starts by optimizing the weight, which is what the first for-loop does. On every iteration, it tries every possible combination of buckets that can be switched and if the difference after that is less than the current difference (resulting in better distribution) it switches them. If the weight doesn't change anymore, it breaks out of the for-loop. While not perfect, this works quite well, and I consider this acceptable for what I'm trying to accomplish.</p> <p>Then it's supposed to optimize the distribution based on the volume, so the total difference is less than 1000. Here I tried to be more careful and search for the best combination in a run before switching it. Thus it searches for the bucket switch resulting in the biggest capacity change and is also supposed to search for a tradeoff between this, though I see the flaw that the first bucket combination tried will set the liters and weight variables, resulting in the next possible combinations being reduced by a big a amount.</p> <h2>Conclusion</h2> <p>I think I need to include some more math here, but I'm honestly stuck here and don't know how to continue here, so I'd like to get some help from you, basically that can help me here is welcome.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload