Changeset 1993 in genesis for nodes/channelga.ml
- Timestamp:
- Apr 12, 2004, 9:37:29 PM (21 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
nodes/channelga.ml
r1991 r1993 19 19 - on node x, interfaces y and z are well separated and can live on the 20 20 same channel 21 - the link between x on y and z on w is very important, make sure it is 22 well separated on both ends of the link 21 23 - interface x on node y will bother interface z on node w and need to 22 24 be on separate channels … … 45 47 (** How long should the system iterate after an improvement? *) 46 48 and max_stagnant_iterations = 2000 47 (** What is the chance for an ESSID tochannel assignment to mutate to a49 (** What is the chance for an ESSID-to-channel assignment to mutate to a 48 50 random channel? *) 49 and mutation_rate = 0.1;; 51 and mutation_rate = 0.1 52 (** The most basic score table *) 53 and scoretable = [ ((<=) 2, 1); 54 ((==) 2, -30); 55 ((==) 1, -70); 56 ((==) 0, -100) ] 50 57 51 58 (* the type definitions. note that Caml has trouble with mutually recursive … … 79 86 let groups = Hashtbl.create 4 80 87 88 (* Now the hashes for the special cases *) 89 (** Hash mapping from nodename to a list of winame's indicating the wi's that 90 don't interfere with eachother for the given node *) 81 91 let nointerference = Hashtbl.create 4 92 (** List of (nodename1, winame1, nodename2, winame2) tuples indicating a very 93 important link that should be well-separated on both ends *) 94 let importantlinks = ref [] 95 (** Hash mapping from nodename to a list of unusable channels for that node *) 82 96 let unusable = Hashtbl.create 4 83 let interference = [] 84 85 let scoretable = [ ((<=) 2, 1); 86 ((==) 2, -30); 87 ((==) 1, -70); 88 ((==) 0, -100) ] 97 (** List of (nodename1, winame1, nodename2, winame2) tuples indicating two 98 interfering interfaces on different nodes *) 99 let interference = ref [] 100 101 (** Run the given diff against the given scoretable and return the score *) 89 102 let rec runtable t diff = 90 103 match t with … … 114 127 let copyarray src dest = Array.blit src 0 dest 0 (Array.length src) 115 128 116 let in_list l i = try 117 let _ = List.find ((==) i) l in 129 (** Is the given element in the given list? uses compare, so it works on 130 strings as well *) 131 let in_list l e = try 132 let _ = List.find (fun x -> (compare e x) == 0) l in 118 133 true 119 134 with Not_found -> false … … 133 148 let is_unusable = in_list unusable in 134 149 if (is_unusable channel1) || (is_unusable channel2) then -10000 135 else if in_list nointerference (maketuple wi1 wi2) then 1 150 else if (in_list nointerference wi1.wi_name) && 151 (in_list nointerference wi2.wi_name) then 1 136 152 else runtable scoretable diff;; 137 153 … … 148 164 base_score * (List.length n.node_wis) 149 165 150 let test_interference c (wi1, wi2) = 166 (** Score the given pair of interferent interfaces against the given 167 configuration *) 168 let score_interference c (nodename1, winame1, nodename2, winame2) = 169 let wi1 = List.find (fun wi -> (compare wi.wi_name winame1) == 0) (Hashtbl.find nodes nodename1).node_wis in 170 let wi2 = List.find (fun wi -> (compare wi.wi_name winame2) == 0) (Hashtbl.find nodes nodename2).node_wis in 151 171 let channel1 = c wi1.wi_essid in 152 172 let channel2 = c wi2.wi_essid in 153 173 let diff = abs (channel1 - channel2) in 154 runtable scoretable diff 174 let res = runtable scoretable diff in 175 res 155 176 156 177 (** Given a list of nodes and a configuration, return the score for the whole 157 configuration. This is the sum of the scores for all nodes. *) 178 configuration. This is the sum of the scores for all nodes, plus the sum 179 of the scores for all user-specified interferent pairs of interfaces. *) 158 180 let score_configuration ns c = 159 181 let mapper = Hashtbl.find c in 160 182 let foldfunc acc n = acc + (node_score mapper n) in 161 183 let nodescores = List.fold_left foldfunc 0 ns in 162 let interference_penalty = List.fold_left (fun a i -> a + test_interference mapper i) 0 interference in 163 nodescores + interference_penalty;; 164 165 (** Given a filename, return a list of all the lines in the file with the given 166 filename. Don't count on the order of the lines in the result. *) 167 let snarf_lines fname = 168 let infile = open_in fname in 169 let result = ref [] in 170 try 171 while true do 172 result := (input_line infile)::!result 173 done; 174 !result (* never gets here *) 175 with End_of_file -> !result 176 177 (** Given the name of the node currently being parsed, parse the given tuple 178 that consists of a wi name and an essid. *) 179 let parse_pair nodename (wname, essid) = 180 let new_wi = { wi_name = wname; wi_nodename = nodename; wi_essid = essid} in 181 let foo = try 182 let group = Hashtbl.find groups essid in 183 group.group_wis <- new_wi::group.group_wis; 184 with Not_found -> 185 let group = { group_essid = essid; group_wis = [ new_wi ] } in 186 Hashtbl.add groups essid group in 187 new_wi 188 189 let parse_fields fields = 190 let nodename = head fields in 191 let rec makepairs l = match l with 192 [] -> [] 193 | x::[] -> assert false 194 | a::b::xs -> (a, b)::(makepairs xs) in 195 let wis = List.map (parse_pair nodename) (makepairs (tail fields)) in 196 let sorted_wis = List.sort compare wis in 197 let node = { node_name = nodename; node_wis = sorted_wis } in 198 Hashtbl.add nodes nodename node 199 200 let parse_file fname = 201 let spacere = Str.regexp " " in 202 List.iter (parse_fields $ (Str.split spacere)) (snarf_lines fname) 203 ;; 184 let interference_score = List.fold_left (fun a i -> a + score_interference mapper i) 0 !interference in 185 nodescores + interference_score;; 204 186 205 187 (** Return a random configuration. For some reason, if this function accesses … … 216 198 let sorted_nodes = List.sort (fun a b -> compare (a.node_name) (b.node_name)) (values nodes) in 217 199 List.iter (fun n -> print_string (n.node_name ^ ":" ^ (wis n) ^ "\n")) sorted_nodes 218 219 let parse_nodeclusters fname =220 let spacere = Str.regexp " " in221 (* handle a row of fields. the first field is the supernode name, the222 rest are the subnode names. create a new node for the supernode,223 stuff all the wi's of the subnodes under it, names prefixed with224 their original node's names for clarity, and remove the subnodes225 from the nodes hashtable *)226 let do_fields f = let nodename = head f in227 let subnodenames = tail f in228 let subnodes = List.map (Hashtbl.find nodes) subnodenames in229 List.iter (Hashtbl.remove nodes) subnodenames;230 let prefixed_wis n = List.map (fun w -> { w with wi_name = n.node_name ^ "." ^ w.wi_name}) n.node_wis in231 let wis = List.fold_left (fun a s -> a@(prefixed_wis s)) [] subnodes in232 let node = { node_name = nodename; node_wis = wis } in233 Hashtbl.add nodes nodename node in234 List.iter (do_fields $ (Str.split spacere)) (snarf_lines fname);;235 200 236 201 (** Generalized evolutionary algorithm driver. … … 269 234 population.(0);; 270 235 236 (** BEGIN PARSING CODE *) 237 238 (** Given a filename, return a list of all the lines in the file with the given 239 filename. Don't count on the order of the lines in the result. *) 240 let snarf_lines fname = 241 let infile = open_in fname in 242 let result = ref [] in 243 try 244 while true do 245 result := (input_line infile)::!result 246 done; 247 !result (* never gets here *) 248 with End_of_file -> !result 249 250 (** Read the main input from the given filename *) 251 let parse_file fname = 252 let spacere = Str.regexp " " in 253 (** Given the name of the node currently being parsed, parse the given tuple 254 that consists of a wi name and an essid. *) 255 let parse_pair nodename (wname, essid) = 256 let new_wi = { wi_name = wname; wi_nodename = nodename; wi_essid = essid} in 257 let foo = try 258 let group = Hashtbl.find groups essid in 259 group.group_wis <- new_wi::group.group_wis; 260 with Not_found -> 261 let group = { group_essid = essid; group_wis = [ new_wi ] } in 262 Hashtbl.add groups essid group in 263 new_wi in 264 let parse_fields fields = 265 let nodename = head fields in 266 let rec makepairs l = match l with 267 [] -> [] 268 | x::[] -> assert false 269 | a::b::xs -> (a, b)::(makepairs xs) in 270 let wis = List.map (parse_pair nodename) (makepairs (tail fields)) in 271 let sorted_wis = List.sort compare wis in 272 let node = { node_name = nodename; node_wis = sorted_wis } in 273 Hashtbl.add nodes nodename node in 274 List.iter (parse_fields $ (Str.split spacere)) (snarf_lines fname) 275 ;; 276 277 (* the parsers for the special case components *) 278 279 (** The first field is the nodename, the rest are interface names *) 280 let parse_nointerference fs = Hashtbl.add nointerference (head fs) (tail fs) 281 (** Read four fields from the given list and add them as a tuple to the given 282 list reference *) 283 let parse_quadruplet l fs = 284 let f = List.nth fs in 285 l := (f 0, f 1, f 2, f 3)::!l 286 (** The first field is the nodename, the rest are channels.*) 287 let parse_unusable fs = 288 let channels = List.map int_of_string (tail fs) in 289 Hashtbl.add unusable (head fs) channels 290 (** The first field is the supernode name, the rest are the names of the 291 subnodes. Construct a new node for the supernode and remove the subnodes 292 from the nodes hash *) 293 let parse_supernode fs = 294 let nodename = head fs in 295 let subnodenames = tail fs in 296 let subnodes = List.map (Hashtbl.find nodes) subnodenames in 297 List.iter (Hashtbl.remove nodes) subnodenames; 298 let prefixed_wis n = List.map (fun w -> { w with wi_name = n.node_name ^ "." ^ w.wi_name}) n.node_wis in 299 let wis = List.fold_left (fun a s -> a@(prefixed_wis s)) [] subnodes in 300 let node = { node_name = nodename; node_wis = wis } in 301 Hashtbl.add nodes nodename node 302 303 let parse_special_conf fname = 304 let spacere = Str.regexp " " in 305 let functable = [ ("nointerference", parse_nointerference); 306 ("important", parse_quadruplet importantlinks); 307 ("interference", parse_quadruplet interference); 308 ("unusable", parse_unusable); 309 ("supernode", parse_supernode) ] in 310 let do_line fs = (List.assoc (head fs) functable) (tail fs) in 311 try 312 List.iter (do_line $ Str.split spacere) (snarf_lines fname) 313 with x -> () 314 315 (** END PARSING CODE *) 316 271 317 let main = 272 318 parse_file Sys.argv.(1); 273 parse_ nodeclusters "coupled.conf";319 parse_special_conf "special.conf"; 274 320 Random.self_init(); 275 321 let all_nodes = values nodes in
Note:
See TracChangeset
for help on using the changeset viewer.