I need algorithm to charge a matrix of 2^k columns and 2^k rows with a sign value of -1 or +1. The first k+1 columns will charge it but the rest (all combinations of k values) not.
I need to multiply all possibilities of k exp :
I have k = 3
I need to multiply 1*2 and 1*3 and 2*3 and 1*2*3.
This is a simple example, but I need the general solution.
This method use for calculating 2^k factorial design.
I tried the following code with visual basic but it did not work 100% (only the first (k+1) columns of the matrix are correct)
Private Sub Command1_Click()
MSFlexGrid1.Cols = Text1.Text + 1
MSFlexGrid1.Rows = 3
MSFlexGrid1.Col = 0
MSFlexGrid1.Row = 1
MSFlexGrid1.Text = "Min"
MSFlexGrid1.Row = 2
MSFlexGrid1.Text = "Max"
For i = 1 To Text1.Text
MSFlexGrid1.Row = 0
MSFlexGrid1.Col = i
MSFlexGrid1.Text = "F" & Str(i)
Next i
End Sub
Function FactFunct(ByVal M As Integer) As Integer
Dim l As Integer
l = 0
For j = M - 1 To 1 Step -1
l = l + j
Next j
FactFunct = l
End Function
Private Sub Command2_Click()
Dim t As Integer
GR2.Visible = True
GR2.Cols = 2 ^ Val(Text1.Text) + 2
GR2.Rows = 2 ^ Val(Text1.Text) + 3
t = 1
GR2.Col = 1
'-------------------------- Incrementer les colonnes
For i = 1 To Val(Text1.Text) + 1
GR2.Row = 1
'-------------------------- declanchement de la routine
If i > 2 Then
t = t * 2
End If
c = -1
j = 1
l = 2 ^ Val(Text1.Text)
'-------------------------- Incrementer les lignes
Do While j <= l
'-------------------------- chargement de la colonne 1
If GR2.Col = 1 Then
GR2.Text = 1
GR2.Row = GR2.Row + 1
j = j + 1
Else
b = 1
'-------------------------- Incrementer les colonnes
Do While b <= t
GR2.Text = 1 * c
GR2.Row = GR2.Row + 1
b = b + 1
j = j + 1
Loop
c = c * -1
End If
Loop
GR2.Col = GR2.Col + 1
Next i
'-----------------------------produit des colonnes
GR2.Col = Val(Text1.Text) + 1
Dim n, Puissance, PositionText, Nbrboucle, NbrValPro, ValColFix, PosCol As Integer
GridRout.Cols = Val(Text1.Text) - 1
Dim JJ As Integer
JJ = 0
For p = Val(Text1.Text) To 2 Step -1
GridRout.Col = JJ
GridRout.Text = FactFunct(p)
JJ = JJ + 1
Next p
For nbrrow = 1 To 2 ^ Val(Text1.Text)
routine = 2
charg = Val(Text1.Text) + 2
For i = 1 To 2
For j = 2 To Val(Text1.Text) + 1
res = 1
k = j
Do While i < routine
GR2.Row = nbrrow
GR2.Col = k
res = Val(res) * Val(GR2.Text)
k = k + 1
i = i + 1
If k = Val(Text1.Text) + 1 Then
k = j + 1
End If
Loop
For M = j + 1 To Val(Text1.Text) + 1
GR2.Row = nbrrow
GR2.Col = M
res2 = Val(res) * Val(GR2.Text)
GR2.Col = charg
GR2.Text = Val(res2)
charg = charg + 1
Next M
Next j
routine = routine + 1
Next i
Next nbrrow
End Sub
Private Sub Form_Load()
'GR2.Visible = False
'GridRout.Visible = False
End Sub
Private Sub MSFlexGrid1_DblClick()
MSFlexGrid1.Text = InputBox("give a number")
End Sub
Private Sub MSFlexGrid2_Click()
End Sub
Related
For a computer science homework, with the example of money, I need to print all possible combination of numbers that add up to 15. I have 9 coins of 1GBP, 3 coins of 2GBP and 3 banknotes of 5GBP. The code below does all possible combinations but I only need to print ones where the numbers add up to 15.
Here is the code below.
Dim num(15) As Integer
Dim a%, b%, c%, d%, e%, f%, g%, h%, i%, j%, k%, l%, m%, n%, o%
num(1) = 1
num(2) = 1
num(3) = 1
num(4) = 1
num(5) = 1
num(6) = 1
num(7) = 1
num(8) = 1
num(9) = 1
num(10) = 2
num(11) = 2
num(12) = 2
num(13) = 5
num(14) = 5
num(15) = 5
Dim count As Integer
For a = 0 To 14
For b = 0 To 14
For c = 0 To 14
For d = 0 To 14
For e = 0 To 14
For f = 0 To 14
For g = 0 To 14
For h = 0 To 14
For i = 0 To 14
For j = 0 To 14
For k = 0 To 14
For l = 0 To 14
For m = 0 To 14
For n = 0 To 14
For o = 0 To 14
Console.WriteLine(num(a) & num(b) & num(c) & num(d) & num(e) & num(f) & num(g) & num(h) & num(i) & num(j) & num(k) & num(l) & num(m) & num(n) & num(o))
count += 1
Next o
Next n
Next m
Next l
Next k
Next j
Next i
Next h
Next g
Next f
Next e
Next d
Next c
Next b
Next a
There is a moment where the program has t = 1 but my if statement wont find it.
what gives?
Most of the question is code to fully experiment with the issue
What i am trying to do with my if statement is to find when t = whole number integers example 1,2,3,4,5 then do stuff to return other results but i cant find the moments when t= 1 so im stuck
Dim neq As Double
neq = 2
Dim e As Double
e = Exp(1)
Dim t_int As Integer
t_int = 5
'''''COUNTERS
Dim i As Integer
Dim j As Integer
Dim colOf As Integer
'''''EQUATION CONTROL
Dim h(3) As Double
Dim n As Double
'''''EQUATION CONTROL
Dim u() As Double
Dim uStar() As Double
Dim uOld() As Double
Dim uEx As Double
'''''EQUATION CONTROL
Dim f() As Double
Dim fOld() As Double
'''''EQUATION CONTROL
Dim t As Double
Dim tOld As Double
Dim tNew As Double
'''''SIZING ARRAY
ReDim u(neq)
ReDim uOld(neq)
ReDim uStar(neq)
ReDim f(neq)
ReDim fOld(neq)
'''''INITAL VAULES
h(1) = 0.1
h(2) = 0.05
h(3) = 0.025
u(1) = 2
u(2) = 0
colOf = 12
For j = 1 To 1
Cells(1, 1 + colOf) = "h(" & j & ") = " & h(j)
Cells(2, 1 + colOf) = "t"
Cells(2, 2 + colOf) = "u(1)"
Cells(2, 3 + colOf) = "u(2)"
Cells(2, 4 + colOf) = "uEx"
For n = 1 To (t_int / h(j))
tOld = t
t = tOld + h(j)
For i = 1 To neq
uOld(i) = u(i)
Next i
For i = 1 To neq
fOld(i) = fDeriv(uOld, tOld, i)
uStar(i) = uOld(i) + h(j) * fOld(i)
Next i
For i = 1 To neq
f(i) = fDeriv(uStar, t, i)
u(i) = uOld(i) + (h(j) * (fOld(i) + f(i))) / 2
Next i
i = i - 1
uEx = 2 * e ^ -t * (Cos((3 ^ 0.5) * t) + ((3 ^ 0.5) ^ -1) * Sin((3 ^ 0.5) * t))
Cells(n + 2, 1 + colOf) = t
Cells(n + 2, 2 + colOf) = u(1)
Cells(n + 2, 3 + colOf) = u(2)
Cells(n + 2, 4 + colOf) = uEx
**If t = 1 Then Debug.Print t**
Next n
colOf = colOf + 5
Next j
I am trying to construct and If statement that turns a tab Red if two of three cells are colored, or Turns green if only on is colored. I was hoping that there would be an easier way to right it than three if statements like this.
Dim dateRng As String, num As Integer, j As Integer, irng As Range, frng As Range
dateRng = Sheets("Input Raw Data").Range("B" & counter + 2).Value
num = Sheets("Tool Setup").Range("C18").Value
NumPts = num * 3
For s = 1 To Sheets.Count
With Sheets(s)
For j = 1 To num
If .Name = j Then
.Range("A1:C1").Merge
.Range("A1") = dateRng
.Name = Sheets("Point Names").Range("B" & (3 * j - 1))
End If
Next j
End With
Next s
For s = 1 to Sheets.Count
With Sheets(s)
For y = 1 To NumPts
If .Name = Sheets("Reporting").Range("B" & (12 * y - 5)) Then
For k = 6 To -1
Set irng = Sheets("Reporting").Range("A" & (12 * y - k))
Set irng = Sheets("Reporting").Range(irng, irng.End(xlToRight).End(xlToRight))
irng.Copy (.Range("A2"))
Next k
.Columns("A:A").ColumnWidth = 12
.Columns("B:B").EntireColumn.AutoFit
If .Range("B7").Interior.ColorIndex > 0 Then
a = 1
End If
If .Range("B8").Interior.ColorIndex > 0 Then
a = a + 1
End If
If .Range("B9").Interior.ColorIndex > 0 Then
a = a + 1
End If
If a >= 2 Then
.Tab.ColorIndex = 3
ElseIf a <= 1 Then
.Tab.ColorIndex = 4
End If
End If
y = y + 2
Next y
End With
Next s
Something like this may help you. It still has multiple if statements. But the statements are simple and don't have to deal with how the combinations of different cells being colored.
Also, I used colorindex > 0 as the condition for having color filling.
a = 0
If .Range("B7").Interior.ColorIndex > 0 Then
a = 1
End If
If .Range("B8").Interior.ColorIndex > 0 Then
a = a + 1
End If
If .Range("B9").Interior.ColorIndex > 0 Then
a = a + 1
End If
If a = 2 Then
.Range("B10").Interior.ColorIndex = 3
ElseIf a = 1 Then
.Range("B10").Interior.ColorIndex = 43
End If
I have a program Sub which works well. I want to convert it into a custom Function, but when I use this function in Excel an error (#VALUE!) occurs
Function ТридцатьТРи(Diapozon As Integer)
'для п/пр
Dim k, n As Integer
Dim parRange As Range
Set parRange = Range("Diapozon")
k = 0
n = 0
For Each Cell In parRange.Rows
If Cell.Offset(0, 1).Value = 1 And k = -1 Then
n = n - 1
End If
If Cell.Value = 1 And k = -1 Then
n = n + 1
End If
If Cell.Value = 1 Then
k = k + 1
If k = 2 Then
k = -1
End If
End If
If Cell.Value = 2 Or Cell.Value = 3 Then
k = 0
End If
Next Cell
ТридцатьТРи = n
End Function
Try the UDF code below (not sure about what you are trying to achieve with your logics inside the UDF), but it works (not getting #VALUE!).
Since you want to pass a Range object to the UDF (according to your screen-shot), you need to define it also in your Function code.
Code
Function cyrilic(Diapozon As Range) As Long
Dim k As Long, n As Long
Dim C As Range
k = 0
n = 0
For Each C In Diapozon.Rows
If C.Offset(0, 1).Value = 1 And k = -1 Then
n = n - 1
End If
If C.Value = 1 And k = -1 Then
n = n + 1
End If
If C.Value = 1 Then
k = k + 1
If k = 2 Then
k = -1
End If
End If
If C.Value = 2 Or C.Value = 3 Then
k = 0
End If
Next C
cyrilic = n
End Function
This will work as a worksheet function apperently, you need to input the range that you previousely defined with a named range "diapozon" as an input range.
Function cyrillic(rng As Range)
Dim k, n As Integer
Dim parRange As Range
Set parRange = rng
k = 0
n = 0
For Each Cell In parRange.Rows
If Cell.Offset(0, 1).Value = 1 And k = -1 Then
n = n - 1
End If
If Cell.Value = 1 And k = -1 Then
n = n + 1
End If
If Cell.Value = 1 Then
k = k + 1
If k = 2 Then
k = -1
End If
End If
If Cell.Value = 2 Or Cell.Value = 3 Then
k = 0
End If
Next Cell
cyrillic = n
End Function
Just type : =cyrillic("R1:RX") and it should work.
I was wondering why the following syntax does not work the way I thought it would in VBA, and what I should do to ensure it does;
For a = 1 To 10
For b = 1 To 10
For c = 1 To 10
If a <> b <> c Then
MsgBox (a & " " & b & " " & c)
End If
Next c
Next b
Next a
This is a simplified example, which can still be manually obtained with:
if a<>b and b<>c and c<>a then
But my actual intended code has 10 such variables multiple times, which makes it unfeasible with 55 unequal conditions, or likely for me to make a typo. I think there is a more efficient way but I have not found it.
Ps. My goal is to only have a message box pop up if all the variables are unique.
I have obtained my goal, though it can probably be done much more efficient than:
For a = 1 To 10
check(a) = True
For b = 1 To 10
If check(b) = False Then
check(b) = True
For c = 1 To 10
If check(c) = False Then
check(c) = True
For d = 1 To 10
If check(d) = False Then
check(d) = True
For e = 1 To 10
If check(e) = False Then
check(e) = True
MsgBox (a & " " & b & " " & c & " " & d & " " & e)
End If
check(e) = False
check(a) = True
check(b) = True
check(c) = True
check(d) = True
Next e
End If
check(d) = False
check(a) = True
check(b) = True
check(c) = True
Next d
End If
check(c) = False
check(a) = True
check(b) = True
Next c
End If
check(b) = False
check(a) = True
Next b
Next a
Here is an implementation of the Johnson-Trotter algorithm for enumerating permutations. It is a small modification of one that I wrote once when playing around with brute-force solutions to the Traveling Salesman Problem. Note that it returns a 2-dimensional array, which might consume a lot of memory. It is possible to refactor it so that it is a sub where the permutations are consumed rather than stored. Just replace the part of the code near the bottom (where the current permutation, perm, is stored in the array perms) by the code that uses the permutation.
Function Permutations(n As Long) As Variant
'implements Johnson-Trotter algorithm for
'listing permutations. Returns results as a variant array
'Thus not feasible for n > 10 or so
Dim perm As Variant, perms As Variant
Dim i As Long, j As Long, k As Long, r As Long, D As Long, m As Long
Dim p_i As Long, p_j As Long
Dim state As Variant
m = Application.WorksheetFunction.Fact(n)
ReDim perm(1 To n)
ReDim perms(1 To m, 1 To n) As Integer
ReDim state(1 To n, 1 To 2) 'state(i,1) = where item i is currently in perm
'state(i,2) = direction of i
k = 1 'will point to current permutation
For i = 1 To n
perm(i) = i
perms(k, i) = i
state(i, 1) = i
state(i, 2) = -1
Next i
state(1, 2) = 0
i = n 'from here on out, i will denote the largest moving
'will be 0 at the end
Do While i > 0
D = state(i, 2)
'swap
p_i = state(i, 1)
p_j = p_i + D
j = perm(p_j)
perm(p_i) = j
state(i, 1) = p_j
perm(p_j) = i
state(j, 1) = p_i
p_i = p_j
If p_i = 1 Or p_i = n Then
state(i, 2) = 0
Else
p_j = p_i + D
If perm(p_j) > i Then state(i, 2) = 0
End If
For j = i + 1 To n
If state(j, 1) < p_i Then
state(j, 2) = 1
Else
state(j, 2) = -1
End If
Next j
'now find i for next pass through loop
If i < n Then
i = n
Else
i = 0
For j = 1 To n
If state(j, 2) <> 0 And j > i Then i = j
Next j
End If
'record perm in perms:
k = k + 1
For r = 1 To n
perms(k, r) = perm(r)
Next r
Loop
Permutations = perms
End Function
Tested like:
Sub test()
Range("A1:G5040").Value = Permutations(7)
Dim A As Variant, i As Long, s As String
A = Permutations(10)
For i = 1 To 10
s = s & " " & A(3628800, i)
Next i
Debug.Print s
End Sub
The first 20 rows of output look like:
Also, 2 1 3 4 5 6 7 8 9 10 is printed in the immediate window. My first version used a vanilla variant away and caused an out-of-memory error with n = 10. I tweaked it so that perms is redimensioned to contain integers (which consume less memory than variants) and is now able to handle 10. It takes about 10 seconds on my machine to run the test code.
You could simply add a check right after the beginning of each inner loop, like follows
For a = 1 To 10
For b = 1 To 10
If b <> a Then '<-- this check will make sure subsequent inner loops shouldn't bother but for their loops variables
For c = 1 To 10
If c <> b Then '<-- same comment as preceeding one
For d = 1 to 10
If d <> c then MsgBox (a & " " & b & " " & c & " " & d) '<-- last check for last two variables
Next d
End If
Next c
End If
Next b
Next a
Try putting all those variables into the array and checking the array for duplicates, if none found, display the message box. Something like this:
Sub dupfind()
Dim ArrHelper(2) As Long
Dim k As Long
Dim j As Long
Dim ans As Long
Dim dupl As Boolean
Dim ArrAnswers() As Long
ans = 0
For a = 1 To 10
ArrHelper(0) = a
For b = 2 To 10
ArrHelper(1) = b
For c = 1 To 10
ArrHelper(2) = c
dupl = False
For k = 0 To UBound(ArrHelper) - 1
For j = k + 1 To UBound(ArrHelper)
If ArrHelper(k) = ArrHelper(j) Then
dupl = True
End If
Next j
Next k
If dupl = False Then
ReDim Preserve ArrAnswers(3, ans)
ArrAnswers(0, ans) = a
ArrAnswers(1, ans) = b
ArrAnswers(2, ans) = c
ans = ans + 1
End If
Next c
Next b
Next a
End Sub
Read your edit regarding storing permutations and changed the code a bit