Related
Let us assume there are 5-time slots and at each time slot, I have 4 options to choose from, each with a known reward, for eg. rewards = [5, 2, 1, -3]. At every time step, at least 1 of the four options must be selected, with a condition that, if option 3 (with reward -3) is chosen at a time t, then for the remaining time steps, none of the options should be selected. As an example, considering the options are indexed from 0, both [2, 1, 1, 0, 3] and [2, 1, 1, 3, 99] are valid solutions with the second solution having option 3 selected in the 3rd time step and 99 is some random value representing no option was chosen.
The Z3py code I tried is here:
T = 6 #Total time slots
s = Solver()
pick = [[Bool('t%d_ch%d' %(j, i)) for i in range(4)] for j in range(T)]
# Rewards of each option
Rewards = [5, 2, 1, -3]
# Select at most one of the 4 options as True
for i in range(T):
s.add(Or(Not(Or(pick[i][0], pick[i][1], pick[i][2], pick[i][3])),
And(Xor(pick[i][0],pick[i][1]), Not(Or(pick[i][2], pick[i][3]))),
And(Xor(pick[i][2],pick[i][3]), Not(Or(pick[i][0], pick[i][1])))))
# If option 3 is picked, then none of the 4 options should be selected for the future time slots
# else, exactly one should be selected.
for i in range(len(pick)-1):
for j in range(4):
s.add(If(And(j==3,pick[i][j]),
Not(Or(pick[i+1][0], pick[i+1][1], pick[i+1][2], pick[i+1][3])),
Or(And(Xor(pick[i+1][0],pick[i+1][1]), Not(Or(pick[i+1][2], pick[i+1][3]))),
And(Xor(pick[i+1][2],pick[i+1][3]), Not(Or(pick[i+1][0], pick[i+1][1]))))))
if s.check()==False:
print("unsat")
m=s.model()
print(m)
With this implementation, I am not getting solutions such as [2, 1, 1, 3, 99]. All of them either do not have option 3 or have it in the last time slot.
I know there is an error inside the If part but I'm unable to figure it out. Is there a better way to achieve such solutions?
It's hard to decipher what you're trying to do. From a basic reading of your description, I think this might be an instance of the XY problem. See https://xyproblem.info/ for details on that, and try to cast your question in terms of what your original goal is; instead of a particular solution, you're trying to implement. (It seems to me that the solution you came up with is unnecessarily complicated.)
Having said that, you can solve your problem as stated if you get rid of the 99 requirement and simply indicate -3 as the terminator. Once you pick -3, then all the following picks should be -3. This can be coded as follows:
from z3 import *
T = 6
s = Solver()
Rewards = [5, 2, 1, -3]
picks = [Int('pick_%d' % i) for i in range(T)]
def pickReward(p):
return Or([p == r for r in Rewards])
for i in range(T):
if i == 0:
s.add(pickReward(picks[i]))
else:
s.add(If(picks[i-1] == -3, picks[i] == -3, pickReward(picks[i])))
while s.check() == sat:
m = s.model()
picked = []
for i in picks:
picked += [m[i]]
print(picked)
s.add(Or([p != v for p, v in zip(picks, picked)]))
When run, this prints:
[5, -3, -3, -3, -3, -3]
[1, 5, 5, 5, 5, 1]
[1, 2, 5, 5, 5, 1]
[2, 2, 5, 5, 5, 1]
[2, 5, 5, 5, 5, 1]
[2, 1, 5, 5, 5, 1]
[1, 1, 5, 5, 5, 1]
[2, 1, 5, 5, 5, 2]
[2, 5, 5, 5, 5, 2]
[2, 5, 5, 5, 5, 5]
[2, 5, 5, 5, 5, -3]
[2, 1, 5, 5, 5, 5]
...
I interrupted the above as it keeps enumerating all the possible picks. There are a total of 1093 of them in this particular case.
(You can get different answers depending on your version of z3.)
Hope this gets you started. Stating what your original goal is directly is usually much more helpful, should you have further questions.
Set literals were not supported until 2.2, How to set literals after Dart 2.2. Please feel free to comment. Thank you.
class item_t {
String name;
int weight;
int value;
}
main() {
const List<item_t> items = [
{'map', 9, 1}, // reports errors
];
}
update 1
I could define the list as a serial of define statements. However, it seems it is ineffective.
class item_t {
String name;
int weight;
int value;
}
main() {
// final item_t items = new item_t(100);
List<item_t> items = new List(2);
items[0].name = 'map';
items[0].weight = 9;
items[0].value = 1;
}
In C language, I can define a structure effectively but I don't know how to do that in dart.
typedef struct {
char *name;
int weight;
int value;
} item_t;
item_t items[] = {
{"map", 9, 150},
{"compass", 13, 35},
{"water", 153, 200},
};
update 2
Thank you jamesdlin's advise, I can simplify the list initialization and access the element by index. However, it still can't be as effective as C language.
var mySet = [
{"map", 9, 150},
{"compass", 13, 35},
{"water", 153, 200},
{"sandwich", 50, 160},
{"glucose", 15, 60},
{"tin", 68, 45},
{"banana", 27, 60},
{"apple", 39, 40},
{"cheese", 23, 30},
{"beer", 52, 10},
{"suntan cream", 11, 70},
{"camera", 32, 30},
{"T-shirt", 24, 15},
{"trousers", 48, 10},
{"umbrella", 73, 40},
{"waterproof trousers", 42, 70},
{"waterproof overclothes", 43, 75},
{"note-case", 22, 80},
{"sunglasses", 7, 20},
{"towel", 18, 12},
{"socks", 4, 50},
{"book", 30, 10}
];
print(mySet[0].elementAt(1));
You use { and } to specify Set (and Map) literals:
var mySet = {1, 2, 3};
Note that to avoid ambiguity with Map literals, you must explicitly specify a type when creating an empty set. For example:
var emptySet = <int>{};
Also see https://dart.dev/guides/language/language-tour#sets
Just replace { and } with [ and ], respectively, and everything will work fine.
a1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
a2 = [2..4, 8..11, 16..17]
Removing one range of values from an array can be done like this:
[1, 2, 3, 4, 5, 6, 7, 8, 9].slice!(2..5)
Iterating over the ranges and apply the same as above (a2.each { |range| a1.slice!(range) }) isn't perfect though. The ranges overlap sometimes and thus destroy the referencing index for the other ranges.
So, any suggestions on how to remove the ranges in a2 from a1 in the most efficient way?
a1 is normally [*0..10080] long. a2 has about 30 ranges, each containing hundreds of values.
If the result of the first operation impacts the second you're either going to have to track the resulting offset implications, which can get crazy complicated, or simply go about doing the reverse operation and instead flag which you want or don't want using the ranges:
require 'set'
a1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
a2 = [2..4, 8..11, 16..17]
# Convert the ranges to a set of index values to remove
reject = Set.new(a2.flat_map(&:to_a))
# Using value/index pairs, accumulate those values which are
# not being excluded by their index.
a1.each_with_index.each_with_object([ ]) do |(v, i), a|
a << v unless (reject.include?(i))
end
# => [0, 1, 5, 6, 7, 12, 13, 14, 15, 18, 19, 20]
[-1, *a2.flat_map(&:minmax), a1.length].each_slice(2).flat_map{|i,j| a1[i+1...j]}
# => [0, 1, 5, 6, 7, 12, 13, 14, 15, 18, 19, 20]
I'm not sure this is the least naive solution, but it seems simple to convert your ranges into arrays so you're dealing with like-for-like:
a2.each{ |a| a1 = a1 - a.to_a }
a1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
a2 = [2..4, 8..11, 16..17]
a1 - a2.flat_map(&:to_a)
i try to plot the result of this code as vertical line each one in the position of the solution of the FindRoot routine (something like that: http://www.astrobio.net/albums/xsolar/ach.sized.jpg ).
omega[a_] := 2 \[Pi] /a^(3/2);
Do[
Print[FindRoot[omega[a]/omega[5.2]==j/i+1, {a, 1}]],
{j,1,7,1},{i,1,7,1}]
Can someone help me please?
I'm part guessing, because your question isn't clear enough:
omega[a_] := 2 Pi/a^(3/2);
ListPlot[Flatten[
Table[{a /. FindRoot[omega[a]/omega[5.2] == j/i + 1, {a, 1}], i + j},
{j, 1, 7, 1}, {i, 1, 7, 1}], 1],
Filling -> Axis, PlotRange -> {{0, 6}, {0, 15}}]
How can I read a file like this:
11111
10001
10001
10001
11111
To a bidimensional array like this:
{{1, 1, 1, 1, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 1, 1, 1, 1}}
In Lua?
This is what I thought of:
for i = 1, number_of_lines do
current_line = map_file:read("*line")
character_array = {}
for i = 1, #current_line do
table.insert(character_array, current_line[i])
end
end
However, I don't know how to get 'number_of_lines', this is, the number of lines in a text file with Lua. How can I do it?
Also, if there's some other easier way please tell me about it.
You don't need to get the number of lines. Just keep going until you run out of lines.
local line_data = {}
for line in map_file:lines() do
local character_array = {}
for i = 1, #line do
character_array[#character_array + 1] = line[i];
end
line_data[#line_data + 1] = character_array
end