Indexes of elements in order from minimum to largest

I'm trying to create an initial solution to the group balancing problem, but I seem to be stuck with what sounds like it should be pretty simple.

Basically I have an array of weights (random integers) like

W() = [1, 4, 3, 2, 5, 3, 2, 1] 

And I want to create another array of the same length with numbers 1 to the size of the array instead of the smallest and largest numbers respectively, for example.

 S() = [1, 7, 5, 3, 8, 6, 4, 2] 

For duplicates, the first occurrence is taken as the smaller of the indices.

I originally used the BubbleSort algorithm, but, unfortunately, this does not allow me to output in the required format.

I understand that this is a rather specific problem, but any help would be greatly appreciated.

+5
source share
3 answers

Thank you so much for everyone who helped!

I accepted your suggestions and somehow managed to create my own solution, despite the fact that I spent the whole day working on something that has very little to do with my overall project.

Here is the following code I used:

 Sub InitialSol(S() As Integer, n As Integer, k As Integer, W() As Long) Dim i As Integer, c As Integer Dim min As Long, max As Long, temp As Long min = W(1) max = W(1) For i = 2 To n If W(i) <= min Then min = W(i) End If If W(i) >= max Then max = W(i) End If Next i c = 1 Do While c <= n temp = max For i = 1 To n If W(i) = min Then S(i) = c c = c + 1 End If Next i For i = 1 To n If W(i) > min And W(i) <= temp Then temp = W(i) End If Next i min = temp Loop End Sub 
0
source

Try it and let me know how this works for you:

 Option Base 0 Option Explicit Option Compare Text Sub tmpSO() Dim tmp As Double Dim strJoin As String Dim i As Long, j As Long Dim W As Variant, S() As Double, X() As Long 'Load W W = Array(1, 4, 3, 2, 5, 3, 2, 1) 'Set the dimensions for the other arrays ReDim S(LBound(W) To UBound(W)) ReDim X(LBound(W) To UBound(W)) 'Copy W into S For i = LBound(W) To UBound(W) S(i) = W(i) Next i 'Sort S For i = LBound(S) To UBound(S) - 1 For j = i + 1 To UBound(S) If S(i) > S(j) Then tmp = S(j) S(j) = S(i) S(i) = tmp End If Next j Next i 'Get the results into X For i = LBound(S) To UBound(S) X(i) = WorksheetFunction.Match(W(i), S, 0) S(WorksheetFunction.Match(W(i), S, 0) - 1) = vbEmpty Next i 'Print out W (original array) Debug.Print Join(W, ",") 'Print out x (result array) For i = LBound(X) To UBound(X) strJoin = strJoin & "," & X(i) Next i Debug.Print mid(strJoin, 2) End Sub 
+2
source

You should find a way to glue values ​​(contents) and indexes. As you noted with excel-vba , I would advise you to write the data to the sheet, the first column of value and the second column of indexes and sort them using range.sort . After that, the second column holds your order.

If using Excel is not an option, the best option I can think of is to create a Scripting.Dictionary (with an index as a key) and sort it (there is no build function to sort, but when you search on it you can find some examples.

Or you could do something ugly, how to create an array of doubles from your data with the decimal part holding you the index [1.001, 4.002, 3.003, 2.004, 5.005, 3.006, 2.007, 1.008] , sort it, get decimal numbers and multiply them by integers.

+1
source

Source: https://habr.com/ru/post/1266642/


All Articles