Changeset 1993 in genesis for nodes/channelga.ml


Ignore:
Timestamp:
Apr 12, 2004, 9:37:29 PM (21 years ago)
Author:
lodewijk
Message:
  • channelga.py is obsolete
  • parsers voor de speciale gevallen erin gezet, lijkt te werken
File:
1 edited

Legend:

Unmodified
Added
Removed
  • nodes/channelga.ml

    r1991 r1993  
    1919     - on node x, interfaces y and z are well separated and can live on the
    2020       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
    2123     - interface x on node y will bother interface z on node w and need to
    2224       be on separate channels
     
    4547(** How long should the system iterate after an improvement? *)
    4648and max_stagnant_iterations = 2000
    47 (** What is the chance for an ESSID to channel assignment to mutate to a
     49(** What is the chance for an ESSID-to-channel assignment to mutate to a
    4850    random channel? *)
    49 and mutation_rate = 0.1;;
     51and mutation_rate = 0.1
     52(** The most basic score table *)
     53and scoretable = [ ((<=) 2,  1);
     54                   ((==) 2, -30);
     55                   ((==) 1, -70);
     56                   ((==) 0, -100) ]
    5057
    5158(* the type definitions. note that Caml has trouble with mutually recursive
     
    7986let groups = Hashtbl.create 4
    8087
     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 *)
    8191let 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 *)
     94let importantlinks = ref []
     95(** Hash mapping from nodename to a list of unusable channels for that node *)
    8296let 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 *)
     99let interference = ref []
     100
     101(** Run the given diff against the given scoretable and return the score *)
    89102let rec runtable t diff =
    90103     match t with
     
    114127let copyarray src dest = Array.blit src 0 dest 0 (Array.length src)
    115128
    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 *)
     131let in_list l e = try
     132                        let _ = List.find (fun x -> (compare e x) == 0) l in
    118133                        true
    119134                  with Not_found -> false
     
    133148        let is_unusable = in_list unusable in
    134149        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
    136152        else runtable scoretable diff;;
    137153
     
    148164        base_score * (List.length n.node_wis)
    149165
    150 let test_interference c (wi1, wi2) =
     166(** Score the given pair of interferent interfaces against the given
     167    configuration *)
     168let 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
    151171        let channel1 = c wi1.wi_essid in
    152172        let channel2 = c wi2.wi_essid in
    153173        let diff = abs (channel1 - channel2) in
    154         runtable scoretable diff
     174        let res = runtable scoretable diff in
     175        res
    155176
    156177(** 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. *)
    158180let score_configuration ns c =
    159181        let mapper = Hashtbl.find c in
    160182        let foldfunc acc n = acc + (node_score mapper n) in
    161183        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;;
    204186
    205187(** Return a random configuration. For some reason, if this function accesses
     
    216198        let sorted_nodes = List.sort (fun a b -> compare (a.node_name) (b.node_name)) (values nodes) in
    217199        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 " " in
    221         (* handle a row of fields. the first field is the supernode name, the
    222            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 with
    224            their original node's names for clarity, and remove the subnodes
    225            from the nodes hashtable *)
    226         let do_fields f = let nodename = head f in
    227                           let subnodenames = tail f in
    228                           let subnodes = List.map (Hashtbl.find nodes) subnodenames in
    229                           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 in
    231                           let wis = List.fold_left (fun a s -> a@(prefixed_wis s)) [] subnodes in
    232                           let node = { node_name = nodename; node_wis = wis } in
    233                           Hashtbl.add nodes nodename node in
    234         List.iter (do_fields $ (Str.split spacere)) (snarf_lines fname);;
    235200
    236201(** Generalized evolutionary algorithm driver.
     
    269234        population.(0);;
    270235
     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. *)
     240let 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 *)
     251let 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 *)
     280let 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 *)
     283let 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.*)
     287let 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 *)
     293let 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
     303let 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
    271317let main =
    272318        parse_file Sys.argv.(1);
    273         parse_nodeclusters "coupled.conf";
     319        parse_special_conf "special.conf";
    274320        Random.self_init();
    275321        let all_nodes = values nodes in
Note: See TracChangeset for help on using the changeset viewer.